@@ -925,8 +925,17 @@ impl<'a> Parser<'a> {
925925 self . parse_closure_expr ( attrs)
926926 } else if self . eat_keyword ( kw:: If ) {
927927 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+ }
930939 } else if self . eat_keyword ( kw:: While ) {
931940 self . parse_while_expr ( None , self . prev_token . span , attrs)
932941 } else if let Some ( label) = self . eat_label ( ) {
@@ -1416,6 +1425,26 @@ impl<'a> Parser<'a> {
14161425 Ok ( self . mk_expr ( blk. span , ExprKind :: Block ( blk, opt_label) , attrs) )
14171426 }
14181427
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+
14191448 /// Parses a closure expression (e.g., `move |args| expr`).
14201449 fn parse_closure_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
14211450 let lo = self . token . span ;
0 commit comments