@@ -1731,7 +1731,7 @@ impl<'a> Parser<'a> {
17311731 }
17321732 } else if self . eat_keyword ( keywords:: Impl ) {
17331733 // Always parse bounds greedily for better error recovery.
1734- let bounds = self . parse_generic_bounds ( ) ?;
1734+ let bounds = self . parse_generic_bounds ( None ) ?;
17351735 impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
17361736 TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds)
17371737 } else if self . check_keyword ( keywords:: Dyn ) &&
@@ -1740,13 +1740,13 @@ impl<'a> Parser<'a> {
17401740 !can_continue_type_after_non_fn_ident ( t) ) ) {
17411741 self . bump ( ) ; // `dyn`
17421742 // Always parse bounds greedily for better error recovery.
1743- let bounds = self . parse_generic_bounds ( ) ?;
1743+ let bounds = self . parse_generic_bounds ( None ) ?;
17441744 impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
17451745 TyKind :: TraitObject ( bounds, TraitObjectSyntax :: Dyn )
17461746 } else if self . check ( & token:: Question ) ||
17471747 self . check_lifetime ( ) && self . look_ahead ( 1 , |t| t. is_like_plus ( ) ) {
17481748 // Bound list (trait object type)
1749- TyKind :: TraitObject ( self . parse_generic_bounds_common ( allow_plus) ?,
1749+ TyKind :: TraitObject ( self . parse_generic_bounds_common ( allow_plus, None ) ?,
17501750 TraitObjectSyntax :: None )
17511751 } else if self . eat_lt ( ) {
17521752 // Qualified path
@@ -1792,7 +1792,7 @@ impl<'a> Parser<'a> {
17921792 let mut bounds = vec ! [ GenericBound :: Trait ( poly_trait_ref, TraitBoundModifier :: None ) ] ;
17931793 if parse_plus {
17941794 self . eat_plus ( ) ; // `+`, or `+=` gets split and `+` is discarded
1795- bounds. append ( & mut self . parse_generic_bounds ( ) ?) ;
1795+ bounds. append ( & mut self . parse_generic_bounds ( None ) ?) ;
17961796 }
17971797 Ok ( TyKind :: TraitObject ( bounds, TraitObjectSyntax :: None ) )
17981798 }
@@ -1817,7 +1817,7 @@ impl<'a> Parser<'a> {
18171817 }
18181818
18191819 self . bump ( ) ; // `+`
1820- let bounds = self . parse_generic_bounds ( ) ?;
1820+ let bounds = self . parse_generic_bounds ( None ) ?;
18211821 let sum_span = ty. span . to ( self . prev_span ) ;
18221822
18231823 let mut err = struct_span_err ! ( self . sess. span_diagnostic, sum_span, E0178 ,
@@ -5492,18 +5492,24 @@ impl<'a> Parser<'a> {
54925492 /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
54935493 /// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
54945494 /// ```
5495- fn parse_generic_bounds_common ( & mut self , allow_plus : bool ) -> PResult < ' a , GenericBounds > {
5495+ fn parse_generic_bounds_common ( & mut self ,
5496+ allow_plus : bool ,
5497+ colon_span : Option < Span > ) -> PResult < ' a , GenericBounds > {
54965498 let mut bounds = Vec :: new ( ) ;
5499+ let mut negative_bounds = Vec :: new ( ) ;
5500+ let mut last_plus_span = None ;
54975501 loop {
54985502 // This needs to be synchronized with `Token::can_begin_bound`.
54995503 let is_bound_start = self . check_path ( ) || self . check_lifetime ( ) ||
5504+ self . check ( & token:: Not ) || // used for error reporting only
55005505 self . check ( & token:: Question ) ||
55015506 self . check_keyword ( keywords:: For ) ||
55025507 self . check ( & token:: OpenDelim ( token:: Paren ) ) ;
55035508 if is_bound_start {
55045509 let lo = self . span ;
55055510 let has_parens = self . eat ( & token:: OpenDelim ( token:: Paren ) ) ;
55065511 let inner_lo = self . span ;
5512+ let is_negative = self . eat ( & token:: Not ) ;
55075513 let question = if self . eat ( & token:: Question ) { Some ( self . prev_span ) } else { None } ;
55085514 if self . token . is_lifetime ( ) {
55095515 if let Some ( question_span) = question {
@@ -5534,28 +5540,60 @@ impl<'a> Parser<'a> {
55345540 if has_parens {
55355541 self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
55365542 }
5537- let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, lo. to ( self . prev_span ) ) ;
5538- let modifier = if question. is_some ( ) {
5539- TraitBoundModifier :: Maybe
5543+ let poly_span = lo. to ( self . prev_span ) ;
5544+ if is_negative {
5545+ negative_bounds. push (
5546+ last_plus_span. or ( colon_span) . unwrap ( )
5547+ . to ( poly_span) ) ;
55405548 } else {
5541- TraitBoundModifier :: None
5542- } ;
5543- bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
5549+ let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, poly_span) ;
5550+ let modifier = if question. is_some ( ) {
5551+ TraitBoundModifier :: Maybe
5552+ } else {
5553+ TraitBoundModifier :: None
5554+ } ;
5555+ bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
5556+ }
55445557 }
55455558 } else {
55465559 break
55475560 }
55485561
55495562 if !allow_plus || !self . eat_plus ( ) {
55505563 break
5551- }
5564+ } else {
5565+ last_plus_span = Some ( self . prev_span ) ;
5566+ }
5567+ }
5568+
5569+ if !negative_bounds. is_empty ( ) {
5570+ let plural = negative_bounds. len ( ) > 1 ;
5571+ let mut err = self . struct_span_err ( negative_bounds,
5572+ "negative trait bounds are not supported" ) ;
5573+ let bound_list = colon_span. unwrap ( ) . to ( self . prev_span ) ;
5574+ let mut new_bound_list = String :: new ( ) ;
5575+ if !bounds. is_empty ( ) {
5576+ let mut snippets = bounds. iter ( ) . map ( |bound| bound. span ( ) )
5577+ . map ( |span| self . sess . source_map ( ) . span_to_snippet ( span) ) ;
5578+ while let Some ( Ok ( snippet) ) = snippets. next ( ) {
5579+ new_bound_list. push_str ( " + " ) ;
5580+ new_bound_list. push_str ( & snippet) ;
5581+ }
5582+ new_bound_list = new_bound_list. replacen ( " +" , ":" , 1 ) ;
5583+ }
5584+ err. span_suggestion_short ( bound_list,
5585+ & format ! ( "remove the trait bound{}" ,
5586+ if plural { "s" } else { "" } ) ,
5587+ new_bound_list,
5588+ Applicability :: MachineApplicable ) ;
5589+ err. emit ( ) ;
55525590 }
55535591
55545592 return Ok ( bounds) ;
55555593 }
55565594
5557- fn parse_generic_bounds ( & mut self ) -> PResult < ' a , GenericBounds > {
5558- self . parse_generic_bounds_common ( true )
5595+ fn parse_generic_bounds ( & mut self , colon_span : Option < Span > ) -> PResult < ' a , GenericBounds > {
5596+ self . parse_generic_bounds_common ( true , colon_span )
55595597 }
55605598
55615599 /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -5583,7 +5621,7 @@ impl<'a> Parser<'a> {
55835621
55845622 // Parse optional colon and param bounds.
55855623 let bounds = if self . eat ( & token:: Colon ) {
5586- self . parse_generic_bounds ( ) ?
5624+ self . parse_generic_bounds ( None ) ?
55875625 } else {
55885626 Vec :: new ( )
55895627 } ;
@@ -5615,7 +5653,7 @@ impl<'a> Parser<'a> {
56155653
56165654 // Parse optional colon and param bounds.
56175655 let bounds = if self . eat ( & token:: Colon ) {
5618- self . parse_generic_bounds ( ) ?
5656+ self . parse_generic_bounds ( None ) ?
56195657 } else {
56205658 Vec :: new ( )
56215659 } ;
@@ -6028,7 +6066,7 @@ impl<'a> Parser<'a> {
60286066 // or with mandatory equality sign and the second type.
60296067 let ty = self . parse_ty ( ) ?;
60306068 if self . eat ( & token:: Colon ) {
6031- let bounds = self . parse_generic_bounds ( ) ?;
6069+ let bounds = self . parse_generic_bounds ( None ) ?;
60326070 where_clause. predicates . push ( ast:: WherePredicate :: BoundPredicate (
60336071 ast:: WhereBoundPredicate {
60346072 span : lo. to ( self . prev_span ) ,
@@ -6542,14 +6580,14 @@ impl<'a> Parser<'a> {
65426580
65436581 // Parse optional colon and supertrait bounds.
65446582 let bounds = if self . eat ( & token:: Colon ) {
6545- self . parse_generic_bounds ( ) ?
6583+ self . parse_generic_bounds ( Some ( self . prev_span ) ) ?
65466584 } else {
65476585 Vec :: new ( )
65486586 } ;
65496587
65506588 if self . eat ( & token:: Eq ) {
65516589 // it's a trait alias
6552- let bounds = self . parse_generic_bounds ( ) ?;
6590+ let bounds = self . parse_generic_bounds ( None ) ?;
65536591 tps. where_clause = self . parse_where_clause ( ) ?;
65546592 self . expect ( & token:: Semi ) ?;
65556593 if is_auto == IsAuto :: Yes {
@@ -7584,7 +7622,7 @@ impl<'a> Parser<'a> {
75847622 tps. where_clause = self . parse_where_clause ( ) ?;
75857623 let alias = if existential {
75867624 self . expect ( & token:: Colon ) ?;
7587- let bounds = self . parse_generic_bounds ( ) ?;
7625+ let bounds = self . parse_generic_bounds ( None ) ?;
75887626 AliasKind :: Existential ( bounds)
75897627 } else {
75907628 self . expect ( & token:: Eq ) ?;
0 commit comments