@@ -1731,7 +1731,7 @@ impl<'a> Parser<'a> {
1731
1731
}
1732
1732
} else if self . eat_keyword ( keywords:: Impl ) {
1733
1733
// Always parse bounds greedily for better error recovery.
1734
- let bounds = self . parse_generic_bounds ( ) ?;
1734
+ let bounds = self . parse_generic_bounds ( None ) ?;
1735
1735
impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
1736
1736
TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds)
1737
1737
} else if self . check_keyword ( keywords:: Dyn ) &&
@@ -1740,13 +1740,13 @@ impl<'a> Parser<'a> {
1740
1740
!can_continue_type_after_non_fn_ident ( t) ) ) {
1741
1741
self . bump ( ) ; // `dyn`
1742
1742
// Always parse bounds greedily for better error recovery.
1743
- let bounds = self . parse_generic_bounds ( ) ?;
1743
+ let bounds = self . parse_generic_bounds ( None ) ?;
1744
1744
impl_dyn_multi = bounds. len ( ) > 1 || self . prev_token_kind == PrevTokenKind :: Plus ;
1745
1745
TyKind :: TraitObject ( bounds, TraitObjectSyntax :: Dyn )
1746
1746
} else if self . check ( & token:: Question ) ||
1747
1747
self . check_lifetime ( ) && self . look_ahead ( 1 , |t| t. is_like_plus ( ) ) {
1748
1748
// 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 ) ?,
1750
1750
TraitObjectSyntax :: None )
1751
1751
} else if self . eat_lt ( ) {
1752
1752
// Qualified path
@@ -1792,7 +1792,7 @@ impl<'a> Parser<'a> {
1792
1792
let mut bounds = vec ! [ GenericBound :: Trait ( poly_trait_ref, TraitBoundModifier :: None ) ] ;
1793
1793
if parse_plus {
1794
1794
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 ) ?) ;
1796
1796
}
1797
1797
Ok ( TyKind :: TraitObject ( bounds, TraitObjectSyntax :: None ) )
1798
1798
}
@@ -1817,7 +1817,7 @@ impl<'a> Parser<'a> {
1817
1817
}
1818
1818
1819
1819
self . bump ( ) ; // `+`
1820
- let bounds = self . parse_generic_bounds ( ) ?;
1820
+ let bounds = self . parse_generic_bounds ( None ) ?;
1821
1821
let sum_span = ty. span . to ( self . prev_span ) ;
1822
1822
1823
1823
let mut err = struct_span_err ! ( self . sess. span_diagnostic, sum_span, E0178 ,
@@ -5492,18 +5492,24 @@ impl<'a> Parser<'a> {
5492
5492
/// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
5493
5493
/// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
5494
5494
/// ```
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 > {
5496
5498
let mut bounds = Vec :: new ( ) ;
5499
+ let mut negative_bounds = Vec :: new ( ) ;
5500
+ let mut last_plus_span = None ;
5497
5501
loop {
5498
5502
// This needs to be synchronized with `Token::can_begin_bound`.
5499
5503
let is_bound_start = self . check_path ( ) || self . check_lifetime ( ) ||
5504
+ self . check ( & token:: Not ) || // used for error reporting only
5500
5505
self . check ( & token:: Question ) ||
5501
5506
self . check_keyword ( keywords:: For ) ||
5502
5507
self . check ( & token:: OpenDelim ( token:: Paren ) ) ;
5503
5508
if is_bound_start {
5504
5509
let lo = self . span ;
5505
5510
let has_parens = self . eat ( & token:: OpenDelim ( token:: Paren ) ) ;
5506
5511
let inner_lo = self . span ;
5512
+ let is_negative = self . eat ( & token:: Not ) ;
5507
5513
let question = if self . eat ( & token:: Question ) { Some ( self . prev_span ) } else { None } ;
5508
5514
if self . token . is_lifetime ( ) {
5509
5515
if let Some ( question_span) = question {
@@ -5534,28 +5540,60 @@ impl<'a> Parser<'a> {
5534
5540
if has_parens {
5535
5541
self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
5536
5542
}
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) ) ;
5540
5548
} 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
+ }
5544
5557
}
5545
5558
} else {
5546
5559
break
5547
5560
}
5548
5561
5549
5562
if !allow_plus || !self . eat_plus ( ) {
5550
5563
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 ( ) ;
5552
5590
}
5553
5591
5554
5592
return Ok ( bounds) ;
5555
5593
}
5556
5594
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 )
5559
5597
}
5560
5598
5561
5599
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -5583,7 +5621,7 @@ impl<'a> Parser<'a> {
5583
5621
5584
5622
// Parse optional colon and param bounds.
5585
5623
let bounds = if self . eat ( & token:: Colon ) {
5586
- self . parse_generic_bounds ( ) ?
5624
+ self . parse_generic_bounds ( None ) ?
5587
5625
} else {
5588
5626
Vec :: new ( )
5589
5627
} ;
@@ -5615,7 +5653,7 @@ impl<'a> Parser<'a> {
5615
5653
5616
5654
// Parse optional colon and param bounds.
5617
5655
let bounds = if self . eat ( & token:: Colon ) {
5618
- self . parse_generic_bounds ( ) ?
5656
+ self . parse_generic_bounds ( None ) ?
5619
5657
} else {
5620
5658
Vec :: new ( )
5621
5659
} ;
@@ -6028,7 +6066,7 @@ impl<'a> Parser<'a> {
6028
6066
// or with mandatory equality sign and the second type.
6029
6067
let ty = self . parse_ty ( ) ?;
6030
6068
if self . eat ( & token:: Colon ) {
6031
- let bounds = self . parse_generic_bounds ( ) ?;
6069
+ let bounds = self . parse_generic_bounds ( None ) ?;
6032
6070
where_clause. predicates . push ( ast:: WherePredicate :: BoundPredicate (
6033
6071
ast:: WhereBoundPredicate {
6034
6072
span : lo. to ( self . prev_span ) ,
@@ -6542,14 +6580,14 @@ impl<'a> Parser<'a> {
6542
6580
6543
6581
// Parse optional colon and supertrait bounds.
6544
6582
let bounds = if self . eat ( & token:: Colon ) {
6545
- self . parse_generic_bounds ( ) ?
6583
+ self . parse_generic_bounds ( Some ( self . prev_span ) ) ?
6546
6584
} else {
6547
6585
Vec :: new ( )
6548
6586
} ;
6549
6587
6550
6588
if self . eat ( & token:: Eq ) {
6551
6589
// it's a trait alias
6552
- let bounds = self . parse_generic_bounds ( ) ?;
6590
+ let bounds = self . parse_generic_bounds ( None ) ?;
6553
6591
tps. where_clause = self . parse_where_clause ( ) ?;
6554
6592
self . expect ( & token:: Semi ) ?;
6555
6593
if is_auto == IsAuto :: Yes {
@@ -7584,7 +7622,7 @@ impl<'a> Parser<'a> {
7584
7622
tps. where_clause = self . parse_where_clause ( ) ?;
7585
7623
let alias = if existential {
7586
7624
self . expect ( & token:: Colon ) ?;
7587
- let bounds = self . parse_generic_bounds ( ) ?;
7625
+ let bounds = self . parse_generic_bounds ( None ) ?;
7588
7626
AliasKind :: Existential ( bounds)
7589
7627
} else {
7590
7628
self . expect ( & token:: Eq ) ?;
0 commit comments