mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
parent
c1d2d83ca3
commit
dc4973dfd9
@ -1803,7 +1803,7 @@ impl<'a> Parser<'a> {
|
||||
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
|
||||
if parse_plus {
|
||||
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
|
||||
bounds.append(&mut self.parse_generic_bounds(None)?);
|
||||
bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
|
||||
}
|
||||
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
|
||||
}
|
||||
@ -5523,6 +5523,7 @@ impl<'a> Parser<'a> {
|
||||
let mut bounds = Vec::new();
|
||||
let mut negative_bounds = Vec::new();
|
||||
let mut last_plus_span = None;
|
||||
let mut was_negative = false;
|
||||
loop {
|
||||
// This needs to be synchronized with `Token::can_begin_bound`.
|
||||
let is_bound_start = self.check_path() || self.check_lifetime() ||
|
||||
@ -5567,9 +5568,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
let poly_span = lo.to(self.prev_span);
|
||||
if is_negative {
|
||||
negative_bounds.push(
|
||||
last_plus_span.or(colon_span).unwrap()
|
||||
.to(poly_span));
|
||||
was_negative = true;
|
||||
if let Some(sp) = last_plus_span.or(colon_span) {
|
||||
negative_bounds.push(sp.to(poly_span));
|
||||
}
|
||||
} else {
|
||||
let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
|
||||
let modifier = if question.is_some() {
|
||||
@ -5591,26 +5593,28 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
if !negative_bounds.is_empty() {
|
||||
if !negative_bounds.is_empty() || was_negative {
|
||||
let plural = negative_bounds.len() > 1;
|
||||
let mut err = self.struct_span_err(negative_bounds,
|
||||
"negative trait bounds are not supported");
|
||||
let bound_list = colon_span.unwrap().to(self.prev_span);
|
||||
let mut new_bound_list = String::new();
|
||||
if !bounds.is_empty() {
|
||||
let mut snippets = bounds.iter().map(|bound| bound.span())
|
||||
.map(|span| self.sess.source_map().span_to_snippet(span));
|
||||
while let Some(Ok(snippet)) = snippets.next() {
|
||||
new_bound_list.push_str(" + ");
|
||||
new_bound_list.push_str(&snippet);
|
||||
if let Some(bound_list) = colon_span {
|
||||
let bound_list = bound_list.to(self.prev_span);
|
||||
let mut new_bound_list = String::new();
|
||||
if !bounds.is_empty() {
|
||||
let mut snippets = bounds.iter().map(|bound| bound.span())
|
||||
.map(|span| self.sess.source_map().span_to_snippet(span));
|
||||
while let Some(Ok(snippet)) = snippets.next() {
|
||||
new_bound_list.push_str(" + ");
|
||||
new_bound_list.push_str(&snippet);
|
||||
}
|
||||
new_bound_list = new_bound_list.replacen(" +", ":", 1);
|
||||
}
|
||||
new_bound_list = new_bound_list.replacen(" +", ":", 1);
|
||||
err.span_suggestion_short(bound_list,
|
||||
&format!("remove the trait bound{}",
|
||||
if plural { "s" } else { "" }),
|
||||
new_bound_list,
|
||||
Applicability::MachineApplicable);
|
||||
}
|
||||
err.span_suggestion_short(bound_list,
|
||||
&format!("remove the trait bound{}",
|
||||
if plural { "s" } else { "" }),
|
||||
new_bound_list,
|
||||
Applicability::MachineApplicable);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
@ -5646,7 +5650,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
// Parse optional colon and param bounds.
|
||||
let bounds = if self.eat(&token::Colon) {
|
||||
self.parse_generic_bounds(None)?
|
||||
self.parse_generic_bounds(Some(self.prev_span))?
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
@ -6091,7 +6095,7 @@ impl<'a> Parser<'a> {
|
||||
// or with mandatory equality sign and the second type.
|
||||
let ty = self.parse_ty()?;
|
||||
if self.eat(&token::Colon) {
|
||||
let bounds = self.parse_generic_bounds(None)?;
|
||||
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
|
||||
where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
|
||||
ast::WhereBoundPredicate {
|
||||
span: lo.to(self.prev_span),
|
||||
@ -7643,7 +7647,7 @@ impl<'a> Parser<'a> {
|
||||
tps.where_clause = self.parse_where_clause()?;
|
||||
let alias = if existential {
|
||||
self.expect(&token::Colon)?;
|
||||
let bounds = self.parse_generic_bounds(None)?;
|
||||
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
|
||||
AliasKind::Existential(bounds)
|
||||
} else {
|
||||
self.expect(&token::Eq)?;
|
||||
|
7
src/test/ui/issues/issue-58857.rs
Normal file
7
src/test/ui/issues/issue-58857.rs
Normal file
@ -0,0 +1,7 @@
|
||||
struct Conj<A> {a : A}
|
||||
trait Valid {}
|
||||
|
||||
impl<A: !Valid> Conj<A>{}
|
||||
//~^ ERROR negative trait bounds are not supported
|
||||
|
||||
fn main() {}
|
8
src/test/ui/issues/issue-58857.stderr
Normal file
8
src/test/ui/issues/issue-58857.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: negative trait bounds are not supported
|
||||
--> $DIR/issue-58857.rs:4:7
|
||||
|
|
||||
LL | impl<A: !Valid> Conj<A>{}
|
||||
| ^^^^^^^^ help: remove the trait bound
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user