Skip to content

Commit a68f760

Browse files
authored
Rollup merge of rust-lang#58861 - estebank:fix-negative-traits, r=petrochenkov
Expand where negative supertrait specific error is shown Fix rust-lang#58857. r? @petrochenkov
2 parents 55dc386 + dc4973d commit a68f760

File tree

3 files changed

+43
-24
lines changed

3 files changed

+43
-24
lines changed

src/libsyntax/parse/parser.rs

+28-24
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,7 @@ impl<'a> Parser<'a> {
18031803
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
18041804
if parse_plus {
18051805
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
1806-
bounds.append(&mut self.parse_generic_bounds(None)?);
1806+
bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
18071807
}
18081808
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
18091809
}
@@ -5523,6 +5523,7 @@ impl<'a> Parser<'a> {
55235523
let mut bounds = Vec::new();
55245524
let mut negative_bounds = Vec::new();
55255525
let mut last_plus_span = None;
5526+
let mut was_negative = false;
55265527
loop {
55275528
// This needs to be synchronized with `Token::can_begin_bound`.
55285529
let is_bound_start = self.check_path() || self.check_lifetime() ||
@@ -5567,9 +5568,10 @@ impl<'a> Parser<'a> {
55675568
}
55685569
let poly_span = lo.to(self.prev_span);
55695570
if is_negative {
5570-
negative_bounds.push(
5571-
last_plus_span.or(colon_span).unwrap()
5572-
.to(poly_span));
5571+
was_negative = true;
5572+
if let Some(sp) = last_plus_span.or(colon_span) {
5573+
negative_bounds.push(sp.to(poly_span));
5574+
}
55735575
} else {
55745576
let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
55755577
let modifier = if question.is_some() {
@@ -5591,26 +5593,28 @@ impl<'a> Parser<'a> {
55915593
}
55925594
}
55935595

5594-
if !negative_bounds.is_empty() {
5596+
if !negative_bounds.is_empty() || was_negative {
55955597
let plural = negative_bounds.len() > 1;
55965598
let mut err = self.struct_span_err(negative_bounds,
55975599
"negative trait bounds are not supported");
5598-
let bound_list = colon_span.unwrap().to(self.prev_span);
5599-
let mut new_bound_list = String::new();
5600-
if !bounds.is_empty() {
5601-
let mut snippets = bounds.iter().map(|bound| bound.span())
5602-
.map(|span| self.sess.source_map().span_to_snippet(span));
5603-
while let Some(Ok(snippet)) = snippets.next() {
5604-
new_bound_list.push_str(" + ");
5605-
new_bound_list.push_str(&snippet);
5606-
}
5607-
new_bound_list = new_bound_list.replacen(" +", ":", 1);
5608-
}
5609-
err.span_suggestion_short(bound_list,
5610-
&format!("remove the trait bound{}",
5611-
if plural { "s" } else { "" }),
5612-
new_bound_list,
5613-
Applicability::MachineApplicable);
5600+
if let Some(bound_list) = colon_span {
5601+
let bound_list = bound_list.to(self.prev_span);
5602+
let mut new_bound_list = String::new();
5603+
if !bounds.is_empty() {
5604+
let mut snippets = bounds.iter().map(|bound| bound.span())
5605+
.map(|span| self.sess.source_map().span_to_snippet(span));
5606+
while let Some(Ok(snippet)) = snippets.next() {
5607+
new_bound_list.push_str(" + ");
5608+
new_bound_list.push_str(&snippet);
5609+
}
5610+
new_bound_list = new_bound_list.replacen(" +", ":", 1);
5611+
}
5612+
err.span_suggestion_short(bound_list,
5613+
&format!("remove the trait bound{}",
5614+
if plural { "s" } else { "" }),
5615+
new_bound_list,
5616+
Applicability::MachineApplicable);
5617+
}
56145618
err.emit();
56155619
}
56165620

@@ -5646,7 +5650,7 @@ impl<'a> Parser<'a> {
56465650

56475651
// Parse optional colon and param bounds.
56485652
let bounds = if self.eat(&token::Colon) {
5649-
self.parse_generic_bounds(None)?
5653+
self.parse_generic_bounds(Some(self.prev_span))?
56505654
} else {
56515655
Vec::new()
56525656
};
@@ -6091,7 +6095,7 @@ impl<'a> Parser<'a> {
60916095
// or with mandatory equality sign and the second type.
60926096
let ty = self.parse_ty()?;
60936097
if self.eat(&token::Colon) {
6094-
let bounds = self.parse_generic_bounds(None)?;
6098+
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
60956099
where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
60966100
ast::WhereBoundPredicate {
60976101
span: lo.to(self.prev_span),
@@ -7643,7 +7647,7 @@ impl<'a> Parser<'a> {
76437647
tps.where_clause = self.parse_where_clause()?;
76447648
let alias = if existential {
76457649
self.expect(&token::Colon)?;
7646-
let bounds = self.parse_generic_bounds(None)?;
7650+
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
76477651
AliasKind::Existential(bounds)
76487652
} else {
76497653
self.expect(&token::Eq)?;

src/test/ui/issues/issue-58857.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
struct Conj<A> {a : A}
2+
trait Valid {}
3+
4+
impl<A: !Valid> Conj<A>{}
5+
//~^ ERROR negative trait bounds are not supported
6+
7+
fn main() {}

src/test/ui/issues/issue-58857.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: negative trait bounds are not supported
2+
--> $DIR/issue-58857.rs:4:7
3+
|
4+
LL | impl<A: !Valid> Conj<A>{}
5+
| ^^^^^^^^ help: remove the trait bound
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)