@@ -2,10 +2,11 @@ use super::{ForceCollect, Parser, PathStyle, TrailingToken};
2
2
use crate :: errors:: {
3
3
self , AmbiguousRangePattern , DotDotDotForRemainingFields , DotDotDotRangeToPatternNotAllowed ,
4
4
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 ,
9
10
UnexpectedVertVertInPattern ,
10
11
} ;
11
12
use crate :: { maybe_recover_from_interpolated_ty_qpath, maybe_whole} ;
@@ -366,11 +367,11 @@ impl<'a> Parser<'a> {
366
367
// Parse _
367
368
PatKind :: Wild
368
369
} else if self . eat_keyword ( kw:: Mut ) {
369
- self . parse_pat_ident_mut ( ) ?
370
+ self . parse_pat_ident_mut ( syntax_loc ) ?
370
371
} else if self . eat_keyword ( kw:: Ref ) {
371
372
// Parse ref ident @ pat / ref mut ident @ pat
372
373
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 ) ?
374
375
} else if self . eat_keyword ( kw:: Box ) {
375
376
self . parse_pat_box ( ) ?
376
377
} else if self . check_inline_const ( 0 ) {
@@ -392,7 +393,7 @@ impl<'a> Parser<'a> {
392
393
// Parse `ident @ pat`
393
394
// This can give false positives and parse nullary enums,
394
395
// they are dealt with later in resolve.
395
- self . parse_pat_ident ( BindingAnnotation :: NONE ) ?
396
+ self . parse_pat_ident ( BindingAnnotation :: NONE , syntax_loc ) ?
396
397
} else if self . is_start_of_pat_with_path ( ) {
397
398
// Parse pattern starting with a path
398
399
let ( qself, path) = if self . eat_lt ( ) {
@@ -401,7 +402,7 @@ impl<'a> Parser<'a> {
401
402
( Some ( qself) , path)
402
403
} else {
403
404
// Parse an unqualified path
404
- ( None , self . parse_path ( PathStyle :: Pat , syntax_loc ) ?)
405
+ ( None , self . parse_path ( PathStyle :: Pat ) ?)
405
406
} ;
406
407
let span = lo. to ( self . prev_token . span ) ;
407
408
@@ -574,12 +575,12 @@ impl<'a> Parser<'a> {
574
575
}
575
576
576
577
/// 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 > {
578
579
let mut_span = self . prev_token . span ;
579
580
580
581
if self . eat_keyword ( kw:: Ref ) {
581
582
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 ) ;
583
584
}
584
585
585
586
self . recover_additional_muts ( ) ;
@@ -784,7 +785,7 @@ impl<'a> Parser<'a> {
784
785
( Some ( qself) , path)
785
786
} else {
786
787
// Parse an unqualified path
787
- ( None , self . parse_path ( PathStyle :: Pat , None ) ?)
788
+ ( None , self . parse_path ( PathStyle :: Pat ) ?)
788
789
} ;
789
790
let hi = self . prev_token . span ;
790
791
Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: Path ( qself, path) ) )
@@ -813,16 +814,28 @@ impl<'a> Parser<'a> {
813
814
| token:: DotDotDot | token:: DotDotEq | token:: DotDot // A range pattern.
814
815
| token:: ModSep // A tuple / struct variant pattern.
815
816
| 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 ( ) ) )
819
817
}
820
818
821
819
/// Parses `ident` or `ident @ pat`.
822
820
/// Used by the copy foo and ref foo patterns to give a good
823
821
/// 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 > {
825
827
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
+
826
839
let sub = if self . eat ( & token:: At ) {
827
840
Some ( self . parse_pat_no_top_alt ( Some ( Expected :: BindingPattern ) , None ) ?)
828
841
} else {
0 commit comments