@@ -2,10 +2,11 @@ use super::{ForceCollect, Parser, PathStyle, TrailingToken};
22use crate :: errors:: {
33 self , AmbiguousRangePattern , DotDotDotForRemainingFields , DotDotDotRangeToPatternNotAllowed ,
44 DotDotDotRestPattern , EnumPatternInsteadOfIdentifier , ExpectedBindingLeftOfAt ,
5- ExpectedCommaAfterPatternField , InclusiveRangeExtraEquals , InclusiveRangeMatchArrow ,
6- InclusiveRangeNoEnd , InvalidMutInPattern , PatternOnWrongSideOfAt , RefMutOrderIncorrect ,
7- RemoveLet , RepeatedMutInPattern , TopLevelOrPatternNotAllowed , TopLevelOrPatternNotAllowedSugg ,
8- TrailingVertNotAllowed , UnexpectedLifetimeInPattern , UnexpectedVertVertBeforeFunctionParam ,
5+ ExpectedCommaAfterPatternField , GenericArgsInPatRequireTurbofishSyntax ,
6+ InclusiveRangeExtraEquals , InclusiveRangeMatchArrow , InclusiveRangeNoEnd , InvalidMutInPattern ,
7+ PatternOnWrongSideOfAt , RefMutOrderIncorrect , RemoveLet , RepeatedMutInPattern ,
8+ TopLevelOrPatternNotAllowed , TopLevelOrPatternNotAllowedSugg , TrailingVertNotAllowed ,
9+ UnexpectedLifetimeInPattern , UnexpectedVertVertBeforeFunctionParam ,
910 UnexpectedVertVertInPattern ,
1011} ;
1112use crate :: { maybe_recover_from_interpolated_ty_qpath, maybe_whole} ;
@@ -366,11 +367,11 @@ impl<'a> Parser<'a> {
366367 // Parse _
367368 PatKind :: Wild
368369 } else if self . eat_keyword ( kw:: Mut ) {
369- self . parse_pat_ident_mut ( ) ?
370+ self . parse_pat_ident_mut ( syntax_loc ) ?
370371 } else if self . eat_keyword ( kw:: Ref ) {
371372 // Parse ref ident @ pat / ref mut ident @ pat
372373 let mutbl = self . parse_mutability ( ) ;
373- self . parse_pat_ident ( BindingAnnotation ( ByRef :: Yes , mutbl) ) ?
374+ self . parse_pat_ident ( BindingAnnotation ( ByRef :: Yes , mutbl) , syntax_loc ) ?
374375 } else if self . eat_keyword ( kw:: Box ) {
375376 self . parse_pat_box ( ) ?
376377 } else if self . check_inline_const ( 0 ) {
@@ -392,7 +393,7 @@ impl<'a> Parser<'a> {
392393 // Parse `ident @ pat`
393394 // This can give false positives and parse nullary enums,
394395 // they are dealt with later in resolve.
395- self . parse_pat_ident ( BindingAnnotation :: NONE ) ?
396+ self . parse_pat_ident ( BindingAnnotation :: NONE , syntax_loc ) ?
396397 } else if self . is_start_of_pat_with_path ( ) {
397398 // Parse pattern starting with a path
398399 let ( qself, path) = if self . eat_lt ( ) {
@@ -401,7 +402,7 @@ impl<'a> Parser<'a> {
401402 ( Some ( qself) , path)
402403 } else {
403404 // Parse an unqualified path
404- ( None , self . parse_path ( PathStyle :: Pat , syntax_loc ) ?)
405+ ( None , self . parse_path ( PathStyle :: Pat ) ?)
405406 } ;
406407 let span = lo. to ( self . prev_token . span ) ;
407408
@@ -574,12 +575,12 @@ impl<'a> Parser<'a> {
574575 }
575576
576577 /// Parse a mutable binding with the `mut` token already eaten.
577- fn parse_pat_ident_mut ( & mut self ) -> PResult < ' a , PatKind > {
578+ fn parse_pat_ident_mut ( & mut self , syntax_loc : Option < PatternLocation > ) -> PResult < ' a , PatKind > {
578579 let mut_span = self . prev_token . span ;
579580
580581 if self . eat_keyword ( kw:: Ref ) {
581582 self . sess . emit_err ( RefMutOrderIncorrect { span : mut_span. to ( self . prev_token . span ) } ) ;
582- return self . parse_pat_ident ( BindingAnnotation :: REF_MUT ) ;
583+ return self . parse_pat_ident ( BindingAnnotation :: REF_MUT , syntax_loc ) ;
583584 }
584585
585586 self . recover_additional_muts ( ) ;
@@ -784,7 +785,7 @@ impl<'a> Parser<'a> {
784785 ( Some ( qself) , path)
785786 } else {
786787 // Parse an unqualified path
787- ( None , self . parse_path ( PathStyle :: Pat , None ) ?)
788+ ( None , self . parse_path ( PathStyle :: Pat ) ?)
788789 } ;
789790 let hi = self . prev_token . span ;
790791 Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: Path ( qself, path) ) )
@@ -813,16 +814,28 @@ impl<'a> Parser<'a> {
813814 | token:: DotDotDot | token:: DotDotEq | token:: DotDot // A range pattern.
814815 | token:: ModSep // A tuple / struct variant pattern.
815816 | token:: Not ) ) // A macro expanding to a pattern.
816- // May suggest the turbofish syntax for generics, only valid for recoveries.
817- && !( self . look_ahead ( 1 , |t| t. kind == token:: Lt )
818- && self . look_ahead ( 2 , |t| t. can_begin_type ( ) ) )
819817 }
820818
821819 /// Parses `ident` or `ident @ pat`.
822820 /// Used by the copy foo and ref foo patterns to give a good
823821 /// error message when parsing mistakes like `ref foo(a, b)`.
824- fn parse_pat_ident ( & mut self , binding_annotation : BindingAnnotation ) -> PResult < ' a , PatKind > {
822+ fn parse_pat_ident (
823+ & mut self ,
824+ binding_annotation : BindingAnnotation ,
825+ syntax_loc : Option < PatternLocation > ,
826+ ) -> PResult < ' a , PatKind > {
825827 let ident = self . parse_ident ( ) ?;
828+
829+ if !matches ! ( syntax_loc, Some ( PatternLocation :: FunctionParameter ) )
830+ && self . check_noexpect ( & token:: Lt )
831+ && self . look_ahead ( 1 , |t| t. can_begin_type ( ) )
832+ {
833+ return Err ( self . sess . create_err ( GenericArgsInPatRequireTurbofishSyntax {
834+ span : self . token . span ,
835+ suggest_turbofish : self . token . span . shrink_to_lo ( ) ,
836+ } ) ) ;
837+ }
838+
826839 let sub = if self . eat ( & token:: At ) {
827840 Some ( self . parse_pat_no_top_alt ( Some ( Expected :: BindingPattern ) , None ) ?)
828841 } else {
0 commit comments