@@ -308,11 +308,11 @@ impl<'a> Parser<'a> {
308
308
// Function pointer type or bound list (trait object type) starting with a poly-trait.
309
309
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
310
310
// `for<'lt> Trait1<'lt> + Trait2 + 'a`
311
- let ( lifetime_defs , _) = self . parse_late_bound_lifetime_defs ( ) ?;
311
+ let ( bound_vars , _) = self . parse_higher_ranked_binder ( ) ?;
312
312
if self . check_fn_front_matter ( false , Case :: Sensitive ) {
313
313
self . parse_ty_fn_ptr (
314
314
lo,
315
- lifetime_defs ,
315
+ bound_vars ,
316
316
Some ( self . prev_token . span . shrink_to_lo ( ) ) ,
317
317
recover_return_sign,
318
318
) ?
@@ -326,7 +326,7 @@ impl<'a> Parser<'a> {
326
326
let path = self . parse_path ( PathStyle :: Type ) ?;
327
327
let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
328
328
let kind = self . parse_remaining_bounds_path (
329
- lifetime_defs ,
329
+ bound_vars ,
330
330
path,
331
331
lo,
332
332
parse_plus,
@@ -359,7 +359,7 @@ impl<'a> Parser<'a> {
359
359
let path = self . parse_path ( PathStyle :: Type ) ?;
360
360
let parse_plus = allow_plus == AllowPlus :: Yes && self . check_plus ( ) ;
361
361
self . parse_remaining_bounds_path (
362
- lifetime_defs ,
362
+ bound_vars ,
363
363
path,
364
364
lo,
365
365
parse_plus,
@@ -443,7 +443,7 @@ impl<'a> Parser<'a> {
443
443
let ty = ts. into_iter ( ) . next ( ) . unwrap ( ) ;
444
444
let maybe_bounds = allow_plus == AllowPlus :: Yes && self . token . is_like_plus ( ) ;
445
445
match ty. kind {
446
- // `(TY_BOUND_NOPAREN) + BOUND + ...`.
446
+ // `"(" BareTraitBound ")" "+" Bound "+" ...`.
447
447
TyKind :: Path ( None , path) if maybe_bounds => self . parse_remaining_bounds_path (
448
448
ThinVec :: new ( ) ,
449
449
path,
@@ -853,10 +853,13 @@ impl<'a> Parser<'a> {
853
853
Ok ( TyKind :: ImplTrait ( ast:: DUMMY_NODE_ID , bounds) )
854
854
}
855
855
856
- fn parse_precise_capturing_args (
857
- & mut self ,
858
- ) -> PResult < ' a , ( ThinVec < PreciseCapturingArg > , Span ) > {
859
- let lo = self . token . span ;
856
+ /// Parse a use-bound aka precise capturing list.
857
+ ///
858
+ /// ```ebnf
859
+ /// UseBound = "use" "<" (PreciseCapture ("," PreciseCapture)* ","?)? ">"
860
+ /// PreciseCapture = "Self" | Ident | Lifetime
861
+ /// ```
862
+ fn parse_use_bound ( & mut self , lo : Span , parens : ast:: Parens ) -> PResult < ' a , GenericBound > {
860
863
self . expect_lt ( ) ?;
861
864
let ( args, _, _) = self . parse_seq_to_before_tokens (
862
865
& [ exp ! ( Gt ) ] ,
@@ -882,7 +885,13 @@ impl<'a> Parser<'a> {
882
885
} ,
883
886
) ?;
884
887
self . expect_gt ( ) ?;
885
- Ok ( ( args, lo. to ( self . prev_token . span ) ) )
888
+
889
+ if let ast:: Parens :: Yes = parens {
890
+ self . expect ( exp ! ( CloseParen ) ) ?;
891
+ self . report_parenthesized_bound ( lo, self . prev_token . span , "precise capturing lists" ) ;
892
+ }
893
+
894
+ Ok ( GenericBound :: Use ( args, lo. to ( self . prev_token . span ) ) )
886
895
}
887
896
888
897
/// Is a `dyn B0 + ... + Bn` type allowed here?
@@ -940,9 +949,10 @@ impl<'a> Parser<'a> {
940
949
self . parse_generic_bounds_common ( AllowPlus :: Yes )
941
950
}
942
951
943
- /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+` .
952
+ /// Parse generic bounds .
944
953
///
945
- /// See `parse_generic_bound` for the `BOUND` grammar.
954
+ /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
955
+ /// Otherwise, this only parses a single bound or none.
946
956
fn parse_generic_bounds_common ( & mut self , allow_plus : AllowPlus ) -> PResult < ' a , GenericBounds > {
947
957
let mut bounds = Vec :: new ( ) ;
948
958
@@ -988,48 +998,56 @@ impl<'a> Parser<'a> {
988
998
|| self . check_keyword ( exp ! ( Use ) )
989
999
}
990
1000
991
- /// Parses a bound according to the grammar:
1001
+ /// Parse a bound.
1002
+ ///
992
1003
/// ```ebnf
993
- /// BOUND = TY_BOUND | LT_BOUND
1004
+ /// Bound = LifetimeBound | UseBound | TraitBound
994
1005
/// ```
995
1006
fn parse_generic_bound ( & mut self ) -> PResult < ' a , GenericBound > {
996
- let lo = self . token . span ;
997
1007
let leading_token = self . prev_token ;
1008
+ let lo = self . token . span ;
1009
+
1010
+ // We only admit parenthesized *trait* bounds. However, we want to gracefully recover from
1011
+ // other kinds of parenthesized bounds, so parse the opening parenthesis *here*.
1012
+ //
1013
+ // In the future we might want to lift this syntactic restriction and
1014
+ // introduce "`GenericBound::Paren(Box<GenericBound>)`".
998
1015
let parens = if self . eat ( exp ! ( OpenParen ) ) { ast:: Parens :: Yes } else { ast:: Parens :: No } ;
999
1016
1000
- let bound = if self . token . is_lifetime ( ) {
1001
- self . parse_generic_lt_bound ( lo, parens) ?
1017
+ if self . token . is_lifetime ( ) {
1018
+ self . parse_lifetime_bound ( lo, parens)
1002
1019
} else if self . eat_keyword ( exp ! ( Use ) ) {
1003
- // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of
1004
- // lifetimes and ident params (including SelfUpper). These are validated later
1005
- // for order, duplication, and whether they actually reference params.
1006
- let use_span = self . prev_token . span ;
1007
- let ( args, args_span) = self . parse_precise_capturing_args ( ) ?;
1008
- GenericBound :: Use ( args, use_span. to ( args_span) )
1020
+ self . parse_use_bound ( lo, parens)
1009
1021
} else {
1010
- self . parse_generic_ty_bound ( lo, parens, & leading_token) ?
1011
- } ;
1012
-
1013
- Ok ( bound)
1022
+ self . parse_trait_bound ( lo, parens, & leading_token)
1023
+ }
1014
1024
}
1015
1025
1016
- /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
1026
+ /// Parse a lifetime-bound aka outlives-bound.
1027
+ ///
1017
1028
/// ```ebnf
1018
- /// LT_BOUND = LIFETIME
1029
+ /// LifetimeBound = Lifetime
1019
1030
/// ```
1020
- fn parse_generic_lt_bound (
1021
- & mut self ,
1022
- lo : Span ,
1023
- parens : ast:: Parens ,
1024
- ) -> PResult < ' a , GenericBound > {
1031
+ fn parse_lifetime_bound ( & mut self , lo : Span , parens : ast:: Parens ) -> PResult < ' a , GenericBound > {
1025
1032
let lt = self . expect_lifetime ( ) ;
1026
- let bound = GenericBound :: Outlives ( lt ) ;
1033
+
1027
1034
if let ast:: Parens :: Yes = parens {
1028
- // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
1029
- // possibly introducing `GenericBound::Paren(Box<GenericBound>)`?
1030
- self . recover_paren_lifetime ( lo) ?;
1035
+ self . expect ( exp ! ( CloseParen ) ) ?;
1036
+ self . report_parenthesized_bound ( lo, self . prev_token . span , "lifetime bounds" ) ;
1031
1037
}
1032
- Ok ( bound)
1038
+
1039
+ Ok ( GenericBound :: Outlives ( lt) )
1040
+ }
1041
+
1042
+ fn report_parenthesized_bound ( & self , lo : Span , hi : Span , kind : & str ) -> ErrorGuaranteed {
1043
+ let mut diag =
1044
+ self . dcx ( ) . struct_span_err ( lo. to ( hi) , format ! ( "{kind} may not be parenthesized" ) ) ;
1045
+ diag. multipart_suggestion (
1046
+ "remove the parentheses" ,
1047
+ vec ! [ ( lo, String :: new( ) ) , ( hi, String :: new( ) ) ] ,
1048
+ Applicability :: MachineApplicable ,
1049
+ ) ;
1050
+ diag. emit ( )
1033
1051
}
1034
1052
1035
1053
/// Emits an error if any trait bound modifiers were present.
@@ -1074,27 +1092,17 @@ impl<'a> Parser<'a> {
1074
1092
unreachable ! ( "lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?" )
1075
1093
}
1076
1094
1077
- /// Recover on `('lifetime)` with `(` already eaten.
1078
- fn recover_paren_lifetime ( & mut self , lo : Span ) -> PResult < ' a , ( ) > {
1079
- self . expect ( exp ! ( CloseParen ) ) ?;
1080
- let span = lo. to ( self . prev_token . span ) ;
1081
- let sugg = errors:: RemoveParens { lo, hi : self . prev_token . span } ;
1082
-
1083
- self . dcx ( ) . emit_err ( errors:: ParenthesizedLifetime { span, sugg } ) ;
1084
- Ok ( ( ) )
1085
- }
1086
-
1087
1095
/// Parses the modifiers that may precede a trait in a bound, e.g. `?Trait` or `[const] Trait`.
1088
1096
///
1089
1097
/// If no modifiers are present, this does not consume any tokens.
1090
1098
///
1091
1099
/// ```ebnf
1092
- /// CONSTNESS = [["["] "const" [ "]"]]
1093
- /// ASYNCNESS = [ "async"]
1094
- /// POLARITY = [ "?" | "!"]
1100
+ /// Constness = ("const" | "[" "const" "]")?
1101
+ /// Asyncness = "async"?
1102
+ /// Polarity = ( "?" | "!")?
1095
1103
/// ```
1096
1104
///
1097
- /// See `parse_generic_ty_bound ` for the complete grammar of trait bound modifiers .
1105
+ /// See `parse_trait_bound ` for more context .
1098
1106
fn parse_trait_bound_modifiers ( & mut self ) -> PResult < ' a , TraitBoundModifiers > {
1099
1107
let modifier_lo = self . token . span ;
1100
1108
let constness = self . parse_bound_constness ( ) ?;
@@ -1187,20 +1195,21 @@ impl<'a> Parser<'a> {
1187
1195
} )
1188
1196
}
1189
1197
1190
- /// Parses a type bound according to:
1198
+ /// Parse a trait bound.
1199
+ ///
1191
1200
/// ```ebnf
1192
- /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
1193
- /// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
1201
+ /// TraitBound = BareTraitBound | "(" BareTraitBound ")"
1202
+ /// BareTraitBound =
1203
+ /// (HigherRankedBinder Constness Asyncness | Polarity)
1204
+ /// TypePath
1194
1205
/// ```
1195
- ///
1196
- /// For example, this grammar accepts `for<'a: 'b> [const] ?m::Trait<'a>`.
1197
- fn parse_generic_ty_bound (
1206
+ fn parse_trait_bound (
1198
1207
& mut self ,
1199
1208
lo : Span ,
1200
1209
parens : ast:: Parens ,
1201
1210
leading_token : & Token ,
1202
1211
) -> PResult < ' a , GenericBound > {
1203
- let ( mut lifetime_defs , binder_span) = self . parse_late_bound_lifetime_defs ( ) ?;
1212
+ let ( mut bound_vars , binder_span) = self . parse_higher_ranked_binder ( ) ?;
1204
1213
1205
1214
let modifiers_lo = self . token . span ;
1206
1215
let modifiers = self . parse_trait_bound_modifiers ( ) ?;
@@ -1223,11 +1232,11 @@ impl<'a> Parser<'a> {
1223
1232
// e.g. `T: for<'a> 'a` or `T: [const] 'a`.
1224
1233
if self . token . is_lifetime ( ) {
1225
1234
let _: ErrorGuaranteed = self . error_lt_bound_with_modifiers ( modifiers, binder_span) ;
1226
- return self . parse_generic_lt_bound ( lo, parens) ;
1235
+ return self . parse_lifetime_bound ( lo, parens) ;
1227
1236
}
1228
1237
1229
- if let ( more_lifetime_defs , Some ( binder_span) ) = self . parse_late_bound_lifetime_defs ( ) ? {
1230
- 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 ) ;
1231
1240
self . dcx ( ) . emit_err ( errors:: BinderBeforeModifiers { binder_span, modifiers_span } ) ;
1232
1241
}
1233
1242
@@ -1287,7 +1296,7 @@ impl<'a> Parser<'a> {
1287
1296
} ;
1288
1297
1289
1298
if self . may_recover ( ) && self . token == TokenKind :: OpenParen {
1290
- 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 ) ?;
1291
1300
}
1292
1301
1293
1302
if let ast:: Parens :: Yes = parens {
@@ -1310,7 +1319,7 @@ impl<'a> Parser<'a> {
1310
1319
}
1311
1320
1312
1321
let poly_trait =
1313
- 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) ;
1314
1323
Ok ( GenericBound :: Trait ( poly_trait) )
1315
1324
}
1316
1325
@@ -1349,8 +1358,12 @@ impl<'a> Parser<'a> {
1349
1358
}
1350
1359
}
1351
1360
1352
- /// Optionally parses `for<$generic_params>`.
1353
- pub ( super ) fn parse_late_bound_lifetime_defs (
1361
+ /// Parse an optional higher-ranked binder.
1362
+ ///
1363
+ /// ```ebnf
1364
+ /// HigherRankedBinder = ("for" "<" GenericParams ">")?
1365
+ /// ```
1366
+ pub ( super ) fn parse_higher_ranked_binder (
1354
1367
& mut self ,
1355
1368
) -> PResult < ' a , ( ThinVec < GenericParam > , Option < Span > ) > {
1356
1369
if self . eat_keyword ( exp ! ( For ) ) {
0 commit comments