@@ -307,11 +307,11 @@ impl<'a> Parser<'a> {
307307 // Function pointer type or bound list (trait object type) starting with a poly-trait.
308308 // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
309309 // `for<'lt> Trait1<'lt> + Trait2 + 'a`
310- let ( lifetime_defs , _) = self . parse_late_bound_lifetime_defs ( ) ?;
310+ let ( bound_vars , _) = self . parse_higher_ranked_binder ( ) ?;
311311 if self . check_fn_front_matter ( false , Case :: Sensitive ) {
312312 self . parse_ty_fn_ptr (
313313 lo,
314- lifetime_defs ,
314+ bound_vars ,
315315 Some ( self . prev_token . span . shrink_to_lo ( ) ) ,
316316 recover_return_sign,
317317 ) ?
@@ -325,7 +325,7 @@ impl<'a> Parser<'a> {
325325 let path = self . parse_path ( PathStyle :: Type ) ?;
326326 let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
327327 let kind = self . parse_remaining_bounds_path (
328- lifetime_defs ,
328+ bound_vars ,
329329 path,
330330 lo,
331331 parse_plus,
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
358358 let path = self . parse_path ( PathStyle :: Type ) ?;
359359 let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
360360 self . parse_remaining_bounds_path (
361- lifetime_defs ,
361+ bound_vars ,
362362 path,
363363 lo,
364364 parse_plus,
@@ -442,7 +442,7 @@ impl<'a> Parser<'a> {
442442 let ty = ts. into_iter ( ) . next ( ) . unwrap ( ) ;
443443 let maybe_bounds = allow_plus == AllowPlus :: Yes && self . token . is_like_plus ( ) ;
444444 match ty. kind {
445- // `(TY_BOUND_NOPAREN) + BOUND + ...`.
445+ // `"(" BareTraitBound ")" "+" Bound "+" ...`.
446446 TyKind :: Path ( None , path) if maybe_bounds => self . parse_remaining_bounds_path (
447447 ThinVec :: new ( ) ,
448448 path,
@@ -847,11 +847,13 @@ impl<'a> Parser<'a> {
847847 Ok ( TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds) )
848848 }
849849
850- fn parse_precise_capturing_args (
851- & mut self ,
852- lo : Span ,
853- parens : ast:: Parens ,
854- ) -> PResult < ' a , GenericBound > {
850+ /// Parse a use-bound aka precise capturing list.
851+ ///
852+ /// ```ebnf
853+ /// UseBound = "use" "<" (PreciseCapture ("," PreciseCapture)* ","?)? ">"
854+ /// PreciseCapture = "Self" | Ident | Lifetime
855+ /// ```
856+ fn parse_use_bound ( & mut self , lo : Span , parens : ast:: Parens ) -> PResult < ' a , GenericBound > {
855857 self . expect_lt ( ) ?;
856858 let ( args, _, _) = self . parse_seq_to_before_tokens (
857859 & [ exp ! ( Gt ) ] ,
@@ -950,9 +952,10 @@ impl<'a> Parser<'a> {
950952 self . parse_generic_bounds_common ( AllowPlus :: Yes )
951953 }
952954
953- /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+` .
955+ /// Parse generic bounds .
954956 ///
955- /// See `parse_generic_bound` for the `BOUND` grammar.
957+ /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
958+ /// Otherwise, this only parses a single bound or none.
956959 fn parse_generic_bounds_common ( & mut self , allow_plus : AllowPlus ) -> PResult < ' a , GenericBounds > {
957960 let mut bounds = Vec :: new ( ) ;
958961
@@ -998,42 +1001,53 @@ impl<'a> Parser<'a> {
9981001 || self . check_keyword ( exp ! ( Use ) )
9991002 }
10001003
1001- /// Parses a bound according to the grammar:
1004+ /// Parse a bound.
1005+ ///
10021006 /// ```ebnf
1003- /// BOUND = TY_BOUND | LT_BOUND
1007+ /// Bound = LifetimeBound | UseBound | TraitBound
10041008 /// ```
10051009 fn parse_generic_bound ( & mut self ) -> PResult < ' a , GenericBound > {
10061010 let leading_token = self . prev_token ;
10071011 let lo = self . token . span ;
10081012
1013+ // We only admit parenthesized *trait* bounds. However, we want to gracefully recover from
1014+ // other kinds of parenthesized bounds, so parse the opening parenthesis *here*.
1015+ //
1016+ // In the future we might want to lift this syntactic restriction and
1017+ // introduce "`GenericBound::Paren(Box<GenericBound>)`".
10091018 let parens = if self . eat ( exp ! ( OpenParen ) ) { ast:: Parens :: Yes } else { ast:: Parens :: No } ;
10101019
10111020 if self . token . is_lifetime ( ) {
1012- self . parse_generic_lt_bound ( lo, parens)
1021+ self . parse_lifetime_bound ( lo, parens)
10131022 } else if self . eat_keyword ( exp ! ( Use ) ) {
1014- self . parse_precise_capturing_args ( lo, parens)
1023+ self . parse_use_bound ( lo, parens)
10151024 } else {
1016- self . parse_generic_ty_bound ( lo, parens, & leading_token)
1025+ self . parse_trait_bound ( lo, parens, & leading_token)
10171026 }
10181027 }
10191028
1020- /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
1029+ /// Parse a lifetime-bound aka outlives-bound.
1030+ ///
10211031 /// ```ebnf
1022- /// LT_BOUND = LIFETIME
1032+ /// LifetimeBound = Lifetime
10231033 /// ```
1024- fn parse_generic_lt_bound (
1025- & mut self ,
1026- lo : Span ,
1027- parens : ast:: Parens ,
1028- ) -> PResult < ' a , GenericBound > {
1034+ fn parse_lifetime_bound ( & mut self , lo : Span , parens : ast:: Parens ) -> PResult < ' a , GenericBound > {
10291035 let lt = self . expect_lifetime ( ) ;
1030- let bound = GenericBound :: Outlives ( lt ) ;
1036+
10311037 if let ast:: Parens :: Yes = parens {
1032- // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
1033- // possibly introducing `GenericBound::Paren(Box<GenericBound>)`?
1034- self . recover_paren_lifetime ( lo) ?;
1038+ self . expect ( exp ! ( CloseParen ) ) ?;
1039+ let hi = self . prev_token . span ;
1040+ let mut diag =
1041+ self . dcx ( ) . struct_span_err ( lo. to ( hi) , "lifetime bounds may not be parenthesized" ) ;
1042+ diag. multipart_suggestion (
1043+ "remove the parentheses" ,
1044+ vec ! [ ( lo, String :: new( ) ) , ( hi, String :: new( ) ) ] ,
1045+ Applicability :: MachineApplicable ,
1046+ ) ;
1047+ diag. emit ( ) ;
10351048 }
1036- Ok ( bound)
1049+
1050+ Ok ( GenericBound :: Outlives ( lt) )
10371051 }
10381052
10391053 /// Emits an error if any trait bound modifiers were present.
@@ -1078,27 +1092,17 @@ impl<'a> Parser<'a> {
10781092 unreachable ! ( "lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?" )
10791093 }
10801094
1081- /// Recover on `('lifetime)` with `(` already eaten.
1082- fn recover_paren_lifetime ( & mut self , lo : Span ) -> PResult < ' a , ( ) > {
1083- self . expect ( exp ! ( CloseParen ) ) ?;
1084- let span = lo. to ( self . prev_token . span ) ;
1085- let sugg = errors:: RemoveParens { lo, hi : self . prev_token . span } ;
1086-
1087- self . dcx ( ) . emit_err ( errors:: ParenthesizedLifetime { span, sugg } ) ;
1088- Ok ( ( ) )
1089- }
1090-
10911095 /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
10921096 ///
10931097 /// If no modifiers are present, this does not consume any tokens.
10941098 ///
10951099 /// ```ebnf
1096- /// CONSTNESS = [["["] "const" [ "]"]]
1097- /// ASYNCNESS = [ "async"]
1098- /// POLARITY = [ "?" | "!"]
1100+ /// Constness = ("const" | "[" "const" "]")?
1101+ /// Asyncness = "async"?
1102+ /// Polarity = ( "?" | "!")?
10991103 /// ```
11001104 ///
1101- /// See `parse_generic_ty_bound ` for the complete grammar of trait bound modifiers .
1105+ /// See `parse_trait_bound ` for more context .
11021106 fn parse_trait_bound_modifiers ( & mut self ) -> PResult < ' a , TraitBoundModifiers > {
11031107 let modifier_lo = self . token . span ;
11041108 let constness = self . parse_bound_constness ( ) ?;
@@ -1191,20 +1195,21 @@ impl<'a> Parser<'a> {
11911195 } )
11921196 }
11931197
1194- /// Parses a type bound according to:
1198+ /// Parse a trait bound.
1199+ ///
11951200 /// ```ebnf
1196- /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
1197- /// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
1201+ /// TraitBound = BareTraitBound | "(" BareTraitBound ")"
1202+ /// BareTraitBound =
1203+ /// (HigherRankedBinder Constness Asyncness | Polarity)?
1204+ /// TypePath
11981205 /// ```
1199- ///
1200- /// For example, this grammar accepts `for<'a: 'b> [const] ?m::Trait<'a>`.
1201- fn parse_generic_ty_bound (
1206+ fn parse_trait_bound (
12021207 & mut self ,
12031208 lo : Span ,
12041209 parens : ast:: Parens ,
12051210 leading_token : & Token ,
12061211 ) -> PResult < ' a , GenericBound > {
1207- let ( mut lifetime_defs , binder_span) = self . parse_late_bound_lifetime_defs ( ) ?;
1212+ let ( mut bound_vars , binder_span) = self . parse_higher_ranked_binder ( ) ?;
12081213
12091214 let modifiers_lo = self . token . span ;
12101215 let modifiers = self . parse_trait_bound_modifiers ( ) ?;
@@ -1227,11 +1232,11 @@ impl<'a> Parser<'a> {
12271232 // e.g. `T: for<'a> 'a` or `T: [const] 'a`.
12281233 if self . token . is_lifetime ( ) {
12291234 let _: ErrorGuaranteed = self . error_lt_bound_with_modifiers ( modifiers, binder_span) ;
1230- return self . parse_generic_lt_bound ( lo, parens) ;
1235+ return self . parse_lifetime_bound ( lo, parens) ;
12311236 }
12321237
1233- if let ( more_lifetime_defs , Some ( binder_span) ) = self . parse_late_bound_lifetime_defs ( ) ? {
1234- lifetime_defs . extend ( more_lifetime_defs ) ;
1238+ if let ( more_bound_vars , Some ( binder_span) ) = self . parse_higher_ranked_binder ( ) ? {
1239+ bound_vars . extend ( more_bound_vars ) ;
12351240 self . dcx ( ) . emit_err ( errors:: BinderBeforeModifiers { binder_span, modifiers_span } ) ;
12361241 }
12371242
@@ -1291,7 +1296,7 @@ impl<'a> Parser<'a> {
12911296 } ;
12921297
12931298 if self . may_recover ( ) && self . token == TokenKind :: OpenParen {
1294- self . recover_fn_trait_with_lifetime_params ( & mut path, & mut lifetime_defs ) ?;
1299+ self . recover_fn_trait_with_lifetime_params ( & mut path, & mut bound_vars ) ?;
12951300 }
12961301
12971302 if let ast:: Parens :: Yes = parens {
@@ -1314,7 +1319,7 @@ impl<'a> Parser<'a> {
13141319 }
13151320
13161321 let poly_trait =
1317- PolyTraitRef :: new ( lifetime_defs , path, modifiers, lo. to ( self . prev_token . span ) , parens) ;
1322+ PolyTraitRef :: new ( bound_vars , path, modifiers, lo. to ( self . prev_token . span ) , parens) ;
13181323 Ok ( GenericBound :: Trait ( poly_trait) )
13191324 }
13201325
@@ -1352,8 +1357,12 @@ impl<'a> Parser<'a> {
13521357 }
13531358 }
13541359
1355- /// Optionally parses `for<$generic_params>`.
1356- pub ( super ) fn parse_late_bound_lifetime_defs (
1360+ /// Parse an optional higher-ranked binder.
1361+ ///
1362+ /// ```ebnf
1363+ /// HigherRankedBinder = ("for" "<" GenericParams ">")?
1364+ /// ```
1365+ pub ( super ) fn parse_higher_ranked_binder (
13571366 & mut self ,
13581367 ) -> PResult < ' a , ( ThinVec < GenericParam > , Option < Span > ) > {
13591368 if self . eat_keyword ( exp ! ( For ) ) {
0 commit comments