@@ -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 ) ] ,
@@ -880,16 +882,7 @@ impl<'a> Parser<'a> {
880882
881883 if let ast:: Parens :: Yes = parens {
882884 self . expect ( exp ! ( CloseParen ) ) ?;
883- let hi = self . prev_token . span ;
884- let mut diag = self
885- . dcx ( )
886- . struct_span_err ( lo. to ( hi) , "precise capturing lists may not be parenthesized" ) ;
887- diag. multipart_suggestion (
888- "remove the parentheses" ,
889- vec ! [ ( lo, String :: new( ) ) , ( hi, String :: new( ) ) ] ,
890- Applicability :: MachineApplicable ,
891- ) ;
892- diag. emit ( ) ;
885+ self . report_parenthesized_bound ( lo, self . prev_token . span , "precise capturing lists" ) ;
893886 }
894887
895888 Ok ( GenericBound :: Use ( args, lo. to ( self . prev_token . span ) ) )
@@ -950,9 +943,10 @@ impl<'a> Parser<'a> {
950943 self . parse_generic_bounds_common ( AllowPlus :: Yes )
951944 }
952945
953- /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+` .
946+ /// Parse generic bounds .
954947 ///
955- /// See `parse_generic_bound` for the `BOUND` grammar.
948+ /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
949+ /// Otherwise, this only parses a single bound or none.
956950 fn parse_generic_bounds_common ( & mut self , allow_plus : AllowPlus ) -> PResult < ' a , GenericBounds > {
957951 let mut bounds = Vec :: new ( ) ;
958952
@@ -998,42 +992,56 @@ impl<'a> Parser<'a> {
998992 || self . check_keyword ( exp ! ( Use ) )
999993 }
1000994
1001- /// Parses a bound according to the grammar:
995+ /// Parse a bound.
996+ ///
1002997 /// ```ebnf
1003- /// BOUND = TY_BOUND | LT_BOUND
998+ /// Bound = LifetimeBound | UseBound | TraitBound
1004999 /// ```
10051000 fn parse_generic_bound ( & mut self ) -> PResult < ' a , GenericBound > {
10061001 let leading_token = self . prev_token ;
10071002 let lo = self . token . span ;
10081003
1004+ // We only admit parenthesized *trait* bounds. However, we want to gracefully recover from
1005+ // other kinds of parenthesized bounds, so parse the opening parenthesis *here*.
1006+ //
1007+ // In the future we might want to lift this syntactic restriction and
1008+ // introduce "`GenericBound::Paren(Box<GenericBound>)`".
10091009 let parens = if self . eat ( exp ! ( OpenParen ) ) { ast:: Parens :: Yes } else { ast:: Parens :: No } ;
10101010
10111011 if self . token . is_lifetime ( ) {
1012- self . parse_generic_lt_bound ( lo, parens)
1012+ self . parse_lifetime_bound ( lo, parens)
10131013 } else if self . eat_keyword ( exp ! ( Use ) ) {
1014- self . parse_precise_capturing_args ( lo, parens)
1014+ self . parse_use_bound ( lo, parens)
10151015 } else {
1016- self . parse_generic_ty_bound ( lo, parens, & leading_token)
1016+ self . parse_trait_bound ( lo, parens, & leading_token)
10171017 }
10181018 }
10191019
1020- /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
1020+ /// Parse a lifetime-bound aka outlives-bound.
1021+ ///
10211022 /// ```ebnf
1022- /// LT_BOUND = LIFETIME
1023+ /// LifetimeBound = Lifetime
10231024 /// ```
1024- fn parse_generic_lt_bound (
1025- & mut self ,
1026- lo : Span ,
1027- parens : ast:: Parens ,
1028- ) -> PResult < ' a , GenericBound > {
1025+ fn parse_lifetime_bound ( & mut self , lo : Span , parens : ast:: Parens ) -> PResult < ' a , GenericBound > {
10291026 let lt = self . expect_lifetime ( ) ;
1030- let bound = GenericBound :: Outlives ( lt ) ;
1027+
10311028 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) ?;
1029+ self . expect ( exp ! ( CloseParen ) ) ?;
1030+ self . report_parenthesized_bound ( lo, self . prev_token . span , "lifetime bounds" ) ;
10351031 }
1036- Ok ( bound)
1032+
1033+ Ok ( GenericBound :: Outlives ( lt) )
1034+ }
1035+
1036+ fn report_parenthesized_bound ( & self , lo : Span , hi : Span , kind : & str ) -> ErrorGuaranteed {
1037+ let mut diag =
1038+ self . dcx ( ) . struct_span_err ( lo. to ( hi) , format ! ( "{kind} may not be parenthesized" ) ) ;
1039+ diag. multipart_suggestion (
1040+ "remove the parentheses" ,
1041+ vec ! [ ( lo, String :: new( ) ) , ( hi, String :: new( ) ) ] ,
1042+ Applicability :: MachineApplicable ,
1043+ ) ;
1044+ diag. emit ( )
10371045 }
10381046
10391047 /// Emits an error if any trait bound modifiers were present.
@@ -1078,27 +1086,17 @@ impl<'a> Parser<'a> {
10781086 unreachable ! ( "lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?" )
10791087 }
10801088
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-
10911089 /// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
10921090 ///
10931091 /// If no modifiers are present, this does not consume any tokens.
10941092 ///
10951093 /// ```ebnf
1096- /// CONSTNESS = [["["] "const" [ "]"]]
1097- /// ASYNCNESS = [ "async"]
1098- /// POLARITY = [ "?" | "!"]
1094+ /// Constness = ("const" | "[" "const" "]")?
1095+ /// Asyncness = "async"?
1096+ /// Polarity = ( "?" | "!")?
10991097 /// ```
11001098 ///
1101- /// See `parse_generic_ty_bound ` for the complete grammar of trait bound modifiers .
1099+ /// See `parse_trait_bound ` for more context .
11021100 fn parse_trait_bound_modifiers ( & mut self ) -> PResult < ' a , TraitBoundModifiers > {
11031101 let modifier_lo = self . token . span ;
11041102 let constness = self . parse_bound_constness ( ) ?;
@@ -1191,20 +1189,21 @@ impl<'a> Parser<'a> {
11911189 } )
11921190 }
11931191
1194- /// Parses a type bound according to:
1192+ /// Parse a trait bound.
1193+ ///
11951194 /// ```ebnf
1196- /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
1197- /// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
1195+ /// TraitBound = BareTraitBound | "(" BareTraitBound ")"
1196+ /// BareTraitBound =
1197+ /// (HigherRankedBinder Constness Asyncness | Polarity)?
1198+ /// TypePath
11981199 /// ```
1199- ///
1200- /// For example, this grammar accepts `for<'a: 'b> [const] ?m::Trait<'a>`.
1201- fn parse_generic_ty_bound (
1200+ fn parse_trait_bound (
12021201 & mut self ,
12031202 lo : Span ,
12041203 parens : ast:: Parens ,
12051204 leading_token : & Token ,
12061205 ) -> PResult < ' a , GenericBound > {
1207- let ( mut lifetime_defs , binder_span) = self . parse_late_bound_lifetime_defs ( ) ?;
1206+ let ( mut bound_vars , binder_span) = self . parse_higher_ranked_binder ( ) ?;
12081207
12091208 let modifiers_lo = self . token . span ;
12101209 let modifiers = self . parse_trait_bound_modifiers ( ) ?;
@@ -1227,11 +1226,11 @@ impl<'a> Parser<'a> {
12271226 // e.g. `T: for<'a> 'a` or `T: [const] 'a`.
12281227 if self . token . is_lifetime ( ) {
12291228 let _: ErrorGuaranteed = self . error_lt_bound_with_modifiers ( modifiers, binder_span) ;
1230- return self . parse_generic_lt_bound ( lo, parens) ;
1229+ return self . parse_lifetime_bound ( lo, parens) ;
12311230 }
12321231
1233- if let ( more_lifetime_defs , Some ( binder_span) ) = self . parse_late_bound_lifetime_defs ( ) ? {
1234- lifetime_defs . extend ( more_lifetime_defs ) ;
1232+ if let ( more_bound_vars , Some ( binder_span) ) = self . parse_higher_ranked_binder ( ) ? {
1233+ bound_vars . extend ( more_bound_vars ) ;
12351234 self . dcx ( ) . emit_err ( errors:: BinderBeforeModifiers { binder_span, modifiers_span } ) ;
12361235 }
12371236
@@ -1291,7 +1290,7 @@ impl<'a> Parser<'a> {
12911290 } ;
12921291
12931292 if self . may_recover ( ) && self . token == TokenKind :: OpenParen {
1294- self . recover_fn_trait_with_lifetime_params ( & mut path, & mut lifetime_defs ) ?;
1293+ self . recover_fn_trait_with_lifetime_params ( & mut path, & mut bound_vars ) ?;
12951294 }
12961295
12971296 if let ast:: Parens :: Yes = parens {
@@ -1314,7 +1313,7 @@ impl<'a> Parser<'a> {
13141313 }
13151314
13161315 let poly_trait =
1317- PolyTraitRef :: new ( lifetime_defs , path, modifiers, lo. to ( self . prev_token . span ) , parens) ;
1316+ PolyTraitRef :: new ( bound_vars , path, modifiers, lo. to ( self . prev_token . span ) , parens) ;
13181317 Ok ( GenericBound :: Trait ( poly_trait) )
13191318 }
13201319
@@ -1352,8 +1351,12 @@ impl<'a> Parser<'a> {
13521351 }
13531352 }
13541353
1355- /// Optionally parses `for<$generic_params>`.
1356- pub ( super ) fn parse_late_bound_lifetime_defs (
1354+ /// Parse an optional higher-ranked binder.
1355+ ///
1356+ /// ```ebnf
1357+ /// HigherRankedBinder = ("for" "<" GenericParams ">")?
1358+ /// ```
1359+ pub ( super ) fn parse_higher_ranked_binder (
13571360 & mut self ,
13581361 ) -> PResult < ' a , ( ThinVec < GenericParam > , Option < Span > ) > {
13591362 if self . eat_keyword ( exp ! ( For ) ) {
0 commit comments