@@ -1733,7 +1733,7 @@ impl<'a> Parser<'a> {
1733
1733
}
1734
1734
} else if self . eat_keyword ( keywords:: Impl ) {
1735
1735
// Always parse bounds greedily for better error recovery.
1736
- let bounds = self . parse_generic_bounds ( ) ?;
1736
+ let bounds = self . parse_generic_bounds ( None ) ?;
1737
1737
impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
1738
1738
TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds)
1739
1739
} else if self . check_keyword ( keywords:: Dyn ) &&
@@ -1742,13 +1742,13 @@ impl<'a> Parser<'a> {
1742
1742
!can_continue_type_after_non_fn_ident ( t) ) ) {
1743
1743
self . bump ( ) ; // `dyn`
1744
1744
// Always parse bounds greedily for better error recovery.
1745
- let bounds = self . parse_generic_bounds ( ) ?;
1745
+ let bounds = self . parse_generic_bounds ( None ) ?;
1746
1746
impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
1747
1747
TyKind :: TraitObject ( bounds, TraitObjectSyntax :: Dyn )
1748
1748
} else if self . check ( & token:: Question ) ||
1749
1749
self . check_lifetime ( ) && self . look_ahead ( 1 , |t| t. is_like_plus ( ) ) {
1750
1750
// Bound list (trait object type)
1751
- TyKind :: TraitObject ( self . parse_generic_bounds_common ( allow_plus) ?,
1751
+ TyKind :: TraitObject ( self . parse_generic_bounds_common ( allow_plus, None ) ?,
1752
1752
TraitObjectSyntax :: None )
1753
1753
} else if self . eat_lt ( ) {
1754
1754
// Qualified path
@@ -1794,7 +1794,7 @@ impl<'a> Parser<'a> {
1794
1794
let mut bounds = vec ! [ GenericBound :: Trait ( poly_trait_ref, TraitBoundModifier :: None ) ] ;
1795
1795
if parse_plus {
1796
1796
self . eat_plus ( ) ; // `+`, or `+=` gets split and `+` is discarded
1797
- bounds. append ( & mut self . parse_generic_bounds ( ) ?) ;
1797
+ bounds. append ( & mut self . parse_generic_bounds ( None ) ?) ;
1798
1798
}
1799
1799
Ok ( TyKind :: TraitObject ( bounds, TraitObjectSyntax :: None ) )
1800
1800
}
@@ -1819,7 +1819,7 @@ impl<'a> Parser<'a> {
1819
1819
}
1820
1820
1821
1821
self . bump ( ) ; // `+`
1822
- let bounds = self . parse_generic_bounds ( ) ?;
1822
+ let bounds = self . parse_generic_bounds ( None ) ?;
1823
1823
let sum_span = ty. span . to ( self . prev_span ) ;
1824
1824
1825
1825
let mut err = struct_span_err ! ( self . sess. span_diagnostic, sum_span, E0178 ,
@@ -5496,18 +5496,24 @@ impl<'a> Parser<'a> {
5496
5496
/// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
5497
5497
/// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
5498
5498
/// ```
5499
- fn parse_generic_bounds_common ( & mut self , allow_plus : bool ) -> PResult < ' a , GenericBounds > {
5499
+ fn parse_generic_bounds_common ( & mut self ,
5500
+ allow_plus : bool ,
5501
+ colon_span : Option < Span > ) -> PResult < ' a , GenericBounds > {
5500
5502
let mut bounds = Vec :: new ( ) ;
5503
+ let mut negative_bounds = Vec :: new ( ) ;
5504
+ let mut last_plus_span = None ;
5501
5505
loop {
5502
5506
// This needs to be synchronized with `Token::can_begin_bound`.
5503
5507
let is_bound_start = self . check_path ( ) || self . check_lifetime ( ) ||
5508
+ self . check ( & token:: Not ) || // used for error reporting only
5504
5509
self . check ( & token:: Question ) ||
5505
5510
self . check_keyword ( keywords:: For ) ||
5506
5511
self . check ( & token:: OpenDelim ( token:: Paren ) ) ;
5507
5512
if is_bound_start {
5508
5513
let lo = self . span ;
5509
5514
let has_parens = self . eat ( & token:: OpenDelim ( token:: Paren ) ) ;
5510
5515
let inner_lo = self . span ;
5516
+ let is_negative = self . eat ( & token:: Not ) ;
5511
5517
let question = if self . eat ( & token:: Question ) { Some ( self . prev_span ) } else { None } ;
5512
5518
if self . token . is_lifetime ( ) {
5513
5519
if let Some ( question_span) = question {
@@ -5538,28 +5544,60 @@ impl<'a> Parser<'a> {
5538
5544
if has_parens {
5539
5545
self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
5540
5546
}
5541
- let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, lo. to ( self . prev_span ) ) ;
5542
- let modifier = if question. is_some ( ) {
5543
- TraitBoundModifier :: Maybe
5547
+ let poly_span = lo. to ( self . prev_span ) ;
5548
+ if is_negative {
5549
+ negative_bounds. push (
5550
+ last_plus_span. or ( colon_span) . unwrap ( )
5551
+ . to ( poly_span) ) ;
5544
5552
} else {
5545
- TraitBoundModifier :: None
5546
- } ;
5547
- bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
5553
+ let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, poly_span) ;
5554
+ let modifier = if question. is_some ( ) {
5555
+ TraitBoundModifier :: Maybe
5556
+ } else {
5557
+ TraitBoundModifier :: None
5558
+ } ;
5559
+ bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
5560
+ }
5548
5561
}
5549
5562
} else {
5550
5563
break
5551
5564
}
5552
5565
5553
5566
if !allow_plus || !self . eat_plus ( ) {
5554
5567
break
5555
- }
5568
+ } else {
5569
+ last_plus_span = Some ( self . prev_span ) ;
5570
+ }
5571
+ }
5572
+
5573
+ if !negative_bounds. is_empty ( ) {
5574
+ let plural = negative_bounds. len ( ) > 1 ;
5575
+ let mut err = self . struct_span_err ( negative_bounds,
5576
+ "negative trait bounds are not supported" ) ;
5577
+ let bound_list = colon_span. unwrap ( ) . to ( self . prev_span ) ;
5578
+ let mut new_bound_list = String :: new ( ) ;
5579
+ if !bounds. is_empty ( ) {
5580
+ let mut snippets = bounds. iter ( ) . map ( |bound| bound. span ( ) )
5581
+ . map ( |span| self . sess . source_map ( ) . span_to_snippet ( span) ) ;
5582
+ while let Some ( Ok ( snippet) ) = snippets. next ( ) {
5583
+ new_bound_list. push_str ( " + " ) ;
5584
+ new_bound_list. push_str ( & snippet) ;
5585
+ }
5586
+ new_bound_list = new_bound_list. replacen ( " +" , ":" , 1 ) ;
5587
+ }
5588
+ err. span_suggestion_short ( bound_list,
5589
+ & format ! ( "remove the trait bound{}" ,
5590
+ if plural { "s" } else { "" } ) ,
5591
+ new_bound_list,
5592
+ Applicability :: MachineApplicable ) ;
5593
+ err. emit ( ) ;
5556
5594
}
5557
5595
5558
5596
return Ok ( bounds) ;
5559
5597
}
5560
5598
5561
- fn parse_generic_bounds ( & mut self ) -> PResult < ' a , GenericBounds > {
5562
- self . parse_generic_bounds_common ( true )
5599
+ fn parse_generic_bounds ( & mut self , colon_span : Option < Span > ) -> PResult < ' a , GenericBounds > {
5600
+ self . parse_generic_bounds_common ( true , colon_span )
5563
5601
}
5564
5602
5565
5603
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -5587,7 +5625,7 @@ impl<'a> Parser<'a> {
5587
5625
5588
5626
// Parse optional colon and param bounds.
5589
5627
let bounds = if self . eat ( & token:: Colon ) {
5590
- self . parse_generic_bounds ( ) ?
5628
+ self . parse_generic_bounds ( None ) ?
5591
5629
} else {
5592
5630
Vec :: new ( )
5593
5631
} ;
@@ -5619,7 +5657,7 @@ impl<'a> Parser<'a> {
5619
5657
5620
5658
// Parse optional colon and param bounds.
5621
5659
let bounds = if self . eat ( & token:: Colon ) {
5622
- self . parse_generic_bounds ( ) ?
5660
+ self . parse_generic_bounds ( None ) ?
5623
5661
} else {
5624
5662
Vec :: new ( )
5625
5663
} ;
@@ -6032,7 +6070,7 @@ impl<'a> Parser<'a> {
6032
6070
// or with mandatory equality sign and the second type.
6033
6071
let ty = self . parse_ty ( ) ?;
6034
6072
if self . eat ( & token:: Colon ) {
6035
- let bounds = self . parse_generic_bounds ( ) ?;
6073
+ let bounds = self . parse_generic_bounds ( None ) ?;
6036
6074
where_clause. predicates . push ( ast:: WherePredicate :: BoundPredicate (
6037
6075
ast:: WhereBoundPredicate {
6038
6076
span : lo. to ( self . prev_span ) ,
@@ -6546,14 +6584,14 @@ impl<'a> Parser<'a> {
6546
6584
6547
6585
// Parse optional colon and supertrait bounds.
6548
6586
let bounds = if self . eat ( & token:: Colon ) {
6549
- self . parse_generic_bounds ( ) ?
6587
+ self . parse_generic_bounds ( Some ( self . prev_span ) ) ?
6550
6588
} else {
6551
6589
Vec :: new ( )
6552
6590
} ;
6553
6591
6554
6592
if self . eat ( & token:: Eq ) {
6555
6593
// it's a trait alias
6556
- let bounds = self . parse_generic_bounds ( ) ?;
6594
+ let bounds = self . parse_generic_bounds ( None ) ?;
6557
6595
tps. where_clause = self . parse_where_clause ( ) ?;
6558
6596
self . expect ( & token:: Semi ) ?;
6559
6597
if is_auto == IsAuto :: Yes {
@@ -7588,7 +7626,7 @@ impl<'a> Parser<'a> {
7588
7626
tps. where_clause = self . parse_where_clause ( ) ?;
7589
7627
let alias = if existential {
7590
7628
self . expect ( & token:: Colon ) ?;
7591
- let bounds = self . parse_generic_bounds ( ) ?;
7629
+ let bounds = self . parse_generic_bounds ( None ) ?;
7592
7630
AliasKind :: Existential ( bounds)
7593
7631
} else {
7594
7632
self . expect ( & token:: Eq ) ?;
0 commit comments