@@ -925,8 +925,17 @@ impl<'a> Parser<'a> {
925
925
self . parse_closure_expr ( attrs)
926
926
} else if self . eat_keyword ( kw:: If ) {
927
927
self . parse_if_expr ( attrs)
928
- } else if self . eat_keyword ( kw:: For ) {
929
- self . parse_for_expr ( None , self . prev_token . span , attrs)
928
+ } else if self . check_keyword ( kw:: For ) {
929
+ if self . choose_generics_over_qpath ( 1 ) {
930
+ // NOTE(Centril, eddyb): DO NOT REMOVE! Beyond providing parser recovery,
931
+ // this is an insurance policy in case we allow qpaths in (tuple-)struct patterns.
932
+ // When `for <Foo as Bar>::Proj in $expr $block` is wanted,
933
+ // you can disambiguate in favor of a pattern with `(...)`.
934
+ self . recover_quantified_closure_expr ( attrs)
935
+ } else {
936
+ assert ! ( self . eat_keyword( kw:: For ) ) ;
937
+ self . parse_for_expr ( None , self . prev_token . span , attrs)
938
+ }
930
939
} else if self . eat_keyword ( kw:: While ) {
931
940
self . parse_while_expr ( None , self . prev_token . span , attrs)
932
941
} else if let Some ( label) = self . eat_label ( ) {
@@ -1416,6 +1425,26 @@ impl<'a> Parser<'a> {
1416
1425
Ok ( self . mk_expr ( blk. span , ExprKind :: Block ( blk, opt_label) , attrs) )
1417
1426
}
1418
1427
1428
+ /// Recover on an explicitly quantified closure expression, e.g., `for<'a> |x: &'a u8| *x + 1`.
1429
+ fn recover_quantified_closure_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
1430
+ let lo = self . token . span ;
1431
+ let _ = self . parse_late_bound_lifetime_defs ( ) ?;
1432
+ let span_for = lo. to ( self . prev_token . span ) ;
1433
+ let closure = self . parse_closure_expr ( attrs) ?;
1434
+
1435
+ self . struct_span_err ( span_for, "cannot introduce explicit parameters for a closure" )
1436
+ . span_label ( closure. span , "the parameters are attached to this closure" )
1437
+ . span_suggestion (
1438
+ span_for,
1439
+ "remove the parameters" ,
1440
+ String :: new ( ) ,
1441
+ Applicability :: MachineApplicable ,
1442
+ )
1443
+ . emit ( ) ;
1444
+
1445
+ Ok ( self . mk_expr_err ( lo. to ( closure. span ) ) )
1446
+ }
1447
+
1419
1448
/// Parses a closure expression (e.g., `move |args| expr`).
1420
1449
fn parse_closure_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
1421
1450
let lo = self . token . span ;
0 commit comments