@@ -3,14 +3,16 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
33use rustc_ast:: mut_visit:: { noop_visit_pat, MutVisitor } ;
44use rustc_ast:: ptr:: P ;
55use rustc_ast:: token;
6- use rustc_ast:: { self as ast, AttrVec , Attribute , MacCall , Pat , PatField , PatKind , RangeEnd } ;
7- use rustc_ast:: { BindingMode , Expr , ExprKind , Mutability , Path , QSelf , RangeSyntax } ;
6+ use rustc_ast:: {
7+ self as ast, AttrVec , Attribute , BindingMode , Expr , ExprKind , MacCall , Mutability , Pat ,
8+ PatField , PatKind , Path , QSelf , RangeEnd , RangeSyntax ,
9+ } ;
810use rustc_ast_pretty:: pprust;
911use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , PResult } ;
1012use rustc_span:: source_map:: { respan, Span , Spanned } ;
1113use rustc_span:: symbol:: { kw, sym, Ident } ;
1214
13- type Expected = Option < & ' static str > ;
15+ pub ( super ) type Expected = Option < & ' static str > ;
1416
1517/// `Expected` for function and lambda parameter patterns.
1618pub ( super ) const PARAM_EXPECTED : Expected = Some ( "parameter name" ) ;
@@ -98,55 +100,9 @@ impl<'a> Parser<'a> {
98100 // If we parsed a leading `|` which should be gated,
99101 // then we should really gate the leading `|`.
100102 // This complicated procedure is done purely for diagnostics UX.
101- let mut first_pat = first_pat;
102-
103- if let ( RecoverColon :: Yes , token:: Colon ) = ( ra, & self . token . kind ) {
104- if matches ! (
105- first_pat. kind,
106- PatKind :: Ident ( BindingMode :: ByValue ( Mutability :: Not ) , _, None )
107- | PatKind :: Path ( ..)
108- ) && self . look_ahead ( 1 , |token| token. is_ident ( ) && !token. is_reserved_ident ( ) )
109- {
110- // The pattern looks like it might be a path with a `::` -> `:` typo:
111- // `match foo { bar:baz => {} }`
112- let span = self . token . span ;
113- // We only emit "unexpected `:`" error here if we can successfully parse the
114- // whole pattern correctly in that case.
115- let snapshot = self . clone ( ) ;
116-
117- // Create error for "unexpected `:`".
118- match self . expected_one_of_not_found ( & [ ] , & [ ] ) {
119- Err ( mut err) => {
120- self . bump ( ) ; // Skip the `:`.
121- match self . parse_pat_no_top_alt ( expected) {
122- Err ( mut inner_err) => {
123- // Carry on as if we had not done anything, callers will emit a
124- // reasonable error.
125- inner_err. cancel ( ) ;
126- err. cancel ( ) ;
127- * self = snapshot;
128- }
129- Ok ( pat) => {
130- // We've parsed the rest of the pattern.
131- err. span_suggestion (
132- span,
133- "maybe write a path separator here" ,
134- "::" . to_string ( ) ,
135- Applicability :: MachineApplicable ,
136- ) ;
137- err. emit ( ) ;
138- first_pat =
139- self . mk_pat ( first_pat. span . to ( pat. span ) , PatKind :: Wild ) ;
140- }
141- }
142- }
143- _ => {
144- // Carry on as if we had not done anything. This should be unreachable.
145- * self = snapshot;
146- }
147- } ;
148- }
149- }
103+
104+ // Check if the user wrote `foo:bar` instead of `foo::bar`.
105+ let first_pat = self . maybe_recover_colon_colon_in_pat_typo ( first_pat, ra, expected) ;
150106
151107 if let Some ( leading_vert_span) = leading_vert_span {
152108 // If there was a leading vert, treat this as an or-pattern. This improves
@@ -321,57 +277,6 @@ impl<'a> Parser<'a> {
321277 err. emit ( ) ;
322278 }
323279
324- /// Some special error handling for the "top-level" patterns in a match arm,
325- /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
326- fn maybe_recover_unexpected_comma ( & mut self , lo : Span , rc : RecoverComma ) -> PResult < ' a , ( ) > {
327- if rc == RecoverComma :: No || self . token != token:: Comma {
328- return Ok ( ( ) ) ;
329- }
330-
331- // An unexpected comma after a top-level pattern is a clue that the
332- // user (perhaps more accustomed to some other language) forgot the
333- // parentheses in what should have been a tuple pattern; return a
334- // suggestion-enhanced error here rather than choking on the comma later.
335- let comma_span = self . token . span ;
336- self . bump ( ) ;
337- if let Err ( mut err) = self . skip_pat_list ( ) {
338- // We didn't expect this to work anyway; we just wanted to advance to the
339- // end of the comma-sequence so we know the span to suggest parenthesizing.
340- err. cancel ( ) ;
341- }
342- let seq_span = lo. to ( self . prev_token . span ) ;
343- let mut err = self . struct_span_err ( comma_span, "unexpected `,` in pattern" ) ;
344- if let Ok ( seq_snippet) = self . span_to_snippet ( seq_span) {
345- const MSG : & str = "try adding parentheses to match on a tuple..." ;
346-
347- err. span_suggestion (
348- seq_span,
349- MSG ,
350- format ! ( "({})" , seq_snippet) ,
351- Applicability :: MachineApplicable ,
352- ) ;
353- err. span_suggestion (
354- seq_span,
355- "...or a vertical bar to match on multiple alternatives" ,
356- seq_snippet. replace ( "," , " |" ) ,
357- Applicability :: MachineApplicable ,
358- ) ;
359- }
360- Err ( err)
361- }
362-
363- /// Parse and throw away a parenthesized comma separated
364- /// sequence of patterns until `)` is reached.
365- fn skip_pat_list ( & mut self ) -> PResult < ' a , ( ) > {
366- while !self . check ( & token:: CloseDelim ( token:: Paren ) ) {
367- self . parse_pat_no_top_alt ( None ) ?;
368- if !self . eat ( & token:: Comma ) {
369- return Ok ( ( ) ) ;
370- }
371- }
372- Ok ( ( ) )
373- }
374-
375280 /// A `|` or possibly `||` token shouldn't be here. Ban it.
376281 fn ban_illegal_vert ( & mut self , lo : Option < Span > , pos : & str , ctx : & str ) {
377282 let span = self . token . span ;
@@ -1168,7 +1073,7 @@ impl<'a> Parser<'a> {
11681073 self . mk_pat ( span, PatKind :: Ident ( bm, ident, None ) )
11691074 }
11701075
1171- fn mk_pat ( & self , span : Span , kind : PatKind ) -> P < Pat > {
1076+ pub ( super ) fn mk_pat ( & self , span : Span , kind : PatKind ) -> P < Pat > {
11721077 P ( Pat { kind, span, id : ast:: DUMMY_NODE_ID , tokens : None } )
11731078 }
11741079}
0 commit comments