@@ -307,11 +307,11 @@ impl<'a> Parser<'a> {
307
307
// Function pointer type or bound list (trait object type) starting with a poly-trait.
308
308
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
309
309
// `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 ( ) ?;
311
311
if self . check_fn_front_matter ( false , Case :: Sensitive ) {
312
312
self . parse_ty_fn_ptr (
313
313
lo,
314
- lifetime_defs ,
314
+ bound_vars ,
315
315
Some ( self . prev_token . span . shrink_to_lo ( ) ) ,
316
316
recover_return_sign,
317
317
) ?
@@ -325,7 +325,7 @@ impl<'a> Parser<'a> {
325
325
let path = self . parse_path ( PathStyle :: Type ) ?;
326
326
let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
327
327
let kind = self . parse_remaining_bounds_path (
328
- lifetime_defs ,
328
+ bound_vars ,
329
329
path,
330
330
lo,
331
331
parse_plus,
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
358
358
let path = self . parse_path ( PathStyle :: Type ) ?;
359
359
let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
360
360
self . parse_remaining_bounds_path (
361
- lifetime_defs ,
361
+ bound_vars ,
362
362
path,
363
363
lo,
364
364
parse_plus,
@@ -442,7 +442,7 @@ impl<'a> Parser<'a> {
442
442
let ty = ts. into_iter ( ) . next ( ) . unwrap ( ) ;
443
443
let maybe_bounds = allow_plus == AllowPlus :: Yes && self . token . is_like_plus ( ) ;
444
444
match ty. kind {
445
- // `(TY_BOUND_NOPAREN) + BOUND + ...`.
445
+ // `"(" BareTraitBound ")" "+" Bound "+" ...`.
446
446
TyKind :: Path ( None , path) if maybe_bounds => self . parse_remaining_bounds_path (
447
447
ThinVec :: new ( ) ,
448
448
path,
@@ -847,11 +847,13 @@ impl<'a> Parser<'a> {
847
847
Ok ( TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds) )
848
848
}
849
849
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 > {
855
857
self . expect_lt ( ) ?;
856
858
let ( args, _, _) = self . parse_seq_to_before_tokens (
857
859
& [ exp ! ( Gt ) ] ,
@@ -880,16 +882,7 @@ impl<'a> Parser<'a> {
880
882
881
883
if let ast:: Parens :: Yes = parens {
882
884
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" ) ;
893
886
}
894
887
895
888
Ok ( GenericBound :: Use ( args, lo. to ( self . prev_token . span ) ) )
@@ -950,9 +943,10 @@ impl<'a> Parser<'a> {
950
943
self . parse_generic_bounds_common ( AllowPlus :: Yes )
951
944
}
952
945
953
- /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+` .
946
+ /// Parse generic bounds .
954
947
///
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.
956
950
fn parse_generic_bounds_common ( & mut self , allow_plus : AllowPlus ) -> PResult < ' a , GenericBounds > {
957
951
let mut bounds = Vec :: new ( ) ;
958
952
@@ -998,42 +992,56 @@ impl<'a> Parser<'a> {
998
992
|| self . check_keyword ( exp ! ( Use ) )
999
993
}
1000
994
1001
- /// Parses a bound according to the grammar:
995
+ /// Parse a bound.
996
+ ///
1002
997
/// ```ebnf
1003
- /// BOUND = TY_BOUND | LT_BOUND
998
+ /// Bound = LifetimeBound | UseBound | TraitBound
1004
999
/// ```
1005
1000
fn parse_generic_bound ( & mut self ) -> PResult < ' a , GenericBound > {
1006
1001
let leading_token = self . prev_token ;
1007
1002
let lo = self . token . span ;
1008
1003
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>)`".
1009
1009
let parens = if self . eat ( exp ! ( OpenParen ) ) { ast:: Parens :: Yes } else { ast:: Parens :: No } ;
1010
1010
1011
1011
if self . token . is_lifetime ( ) {
1012
- self . parse_generic_lt_bound ( lo, parens)
1012
+ self . parse_lifetime_bound ( lo, parens)
1013
1013
} else if self . eat_keyword ( exp ! ( Use ) ) {
1014
- self . parse_precise_capturing_args ( lo, parens)
1014
+ self . parse_use_bound ( lo, parens)
1015
1015
} else {
1016
- self . parse_generic_ty_bound ( lo, parens, & leading_token)
1016
+ self . parse_trait_bound ( lo, parens, & leading_token)
1017
1017
}
1018
1018
}
1019
1019
1020
- /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
1020
+ /// Parse a lifetime-bound aka outlives-bound.
1021
+ ///
1021
1022
/// ```ebnf
1022
- /// LT_BOUND = LIFETIME
1023
+ /// LifetimeBound = Lifetime
1023
1024
/// ```
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 > {
1029
1026
let lt = self . expect_lifetime ( ) ;
1030
- let bound = GenericBound :: Outlives ( lt ) ;
1027
+
1031
1028
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" ) ;
1035
1031
}
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 ( )
1037
1045
}
1038
1046
1039
1047
/// Emits an error if any trait bound modifiers were present.
@@ -1078,27 +1086,17 @@ impl<'a> Parser<'a> {
1078
1086
unreachable ! ( "lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?" )
1079
1087
}
1080
1088
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
-
1091
1089
/// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
1092
1090
///
1093
1091
/// If no modifiers are present, this does not consume any tokens.
1094
1092
///
1095
1093
/// ```ebnf
1096
- /// CONSTNESS = [["["] "const" [ "]"]]
1097
- /// ASYNCNESS = [ "async"]
1098
- /// POLARITY = [ "?" | "!"]
1094
+ /// Constness = ("const" | "[" "const" "]")?
1095
+ /// Asyncness = "async"?
1096
+ /// Polarity = ( "?" | "!")?
1099
1097
/// ```
1100
1098
///
1101
- /// See `parse_generic_ty_bound ` for the complete grammar of trait bound modifiers .
1099
+ /// See `parse_trait_bound ` for more context .
1102
1100
fn parse_trait_bound_modifiers ( & mut self ) -> PResult < ' a , TraitBoundModifiers > {
1103
1101
let modifier_lo = self . token . span ;
1104
1102
let constness = self . parse_bound_constness ( ) ?;
@@ -1191,20 +1189,21 @@ impl<'a> Parser<'a> {
1191
1189
} )
1192
1190
}
1193
1191
1194
- /// Parses a type bound according to:
1192
+ /// Parse a trait bound.
1193
+ ///
1195
1194
/// ```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
1198
1199
/// ```
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 (
1202
1201
& mut self ,
1203
1202
lo : Span ,
1204
1203
parens : ast:: Parens ,
1205
1204
leading_token : & Token ,
1206
1205
) -> 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 ( ) ?;
1208
1207
1209
1208
let modifiers_lo = self . token . span ;
1210
1209
let modifiers = self . parse_trait_bound_modifiers ( ) ?;
@@ -1227,11 +1226,11 @@ impl<'a> Parser<'a> {
1227
1226
// e.g. `T: for<'a> 'a` or `T: [const] 'a`.
1228
1227
if self . token . is_lifetime ( ) {
1229
1228
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) ;
1231
1230
}
1232
1231
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 ) ;
1235
1234
self . dcx ( ) . emit_err ( errors:: BinderBeforeModifiers { binder_span, modifiers_span } ) ;
1236
1235
}
1237
1236
@@ -1291,7 +1290,7 @@ impl<'a> Parser<'a> {
1291
1290
} ;
1292
1291
1293
1292
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 ) ?;
1295
1294
}
1296
1295
1297
1296
if let ast:: Parens :: Yes = parens {
@@ -1314,7 +1313,7 @@ impl<'a> Parser<'a> {
1314
1313
}
1315
1314
1316
1315
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) ;
1318
1317
Ok ( GenericBound :: Trait ( poly_trait) )
1319
1318
}
1320
1319
@@ -1352,8 +1351,12 @@ impl<'a> Parser<'a> {
1352
1351
}
1353
1352
}
1354
1353
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 (
1357
1360
& mut self ,
1358
1361
) -> PResult < ' a , ( ThinVec < GenericParam > , Option < Span > ) > {
1359
1362
if self . eat_keyword ( exp ! ( For ) ) {
0 commit comments