@@ -56,37 +56,34 @@ const PAT_RECOVERY_SET: TokenSet =
56
56
token_set ! [ LET_KW , IF_KW , WHILE_KW , LOOP_KW , MATCH_KW , R_PAREN , COMMA ] ;
57
57
58
58
fn atom_pat ( p : & mut Parser , recovery_set : TokenSet ) -> Option < CompletedMarker > {
59
- let la0 = p. nth ( 0 ) ;
60
- let la1 = p. nth ( 1 ) ;
61
- if la0 == T ! [ ref]
62
- || la0 == T ! [ mut ]
63
- || la0 == T ! [ box]
64
- || ( la0 == IDENT && !( la1 == T ! [ :: ] || la1 == T ! [ '(' ] || la1 == T ! [ '{' ] || la1 == T ! [ !] ) )
65
- {
66
- return Some ( bind_pat ( p, true ) ) ;
67
- }
68
- if paths:: is_use_path_start ( p) {
69
- return Some ( path_pat ( p) ) ;
70
- }
59
+ // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
60
+ // (T![x]).
61
+ let is_path_or_macro_pat = |la1| {
62
+ la1 == T ! [ :: ] || la1 == T ! [ '(' ] || la1 == T ! [ '{' ] || la1 == T ! [ !]
63
+ } ;
71
64
72
- if is_literal_pat_start ( p) {
73
- return Some ( literal_pat ( p) ) ;
74
- }
65
+ let m = match p. nth ( 0 ) {
66
+ T ! [ box] => box_pat ( p) ,
67
+ T ! [ ref] | T ! [ mut ] | IDENT if !is_path_or_macro_pat ( p. nth ( 1 ) ) => bind_pat ( p, true ) ,
68
+
69
+ _ if paths:: is_use_path_start ( p) => path_pat ( p) ,
70
+ _ if is_literal_pat_start ( p) => literal_pat ( p) ,
75
71
76
- let m = match la0 {
77
72
T ! [ _] => placeholder_pat ( p) ,
78
73
T ! [ & ] => ref_pat ( p) ,
79
74
T ! [ '(' ] => tuple_pat ( p) ,
80
75
T ! [ '[' ] => slice_pat ( p) ,
76
+
81
77
_ => {
82
78
p. err_recover ( "expected pattern" , recovery_set) ;
83
79
return None ;
84
80
}
85
81
} ;
82
+
86
83
Some ( m)
87
84
}
88
85
89
- fn is_literal_pat_start ( p : & mut Parser ) -> bool {
86
+ fn is_literal_pat_start ( p : & Parser ) -> bool {
90
87
p. at ( T ! [ -] ) && ( p. nth ( 1 ) == INT_NUMBER || p. nth ( 1 ) == FLOAT_NUMBER )
91
88
|| p. at_ts ( expressions:: LITERAL_FIRST )
92
89
}
@@ -261,11 +258,9 @@ fn pat_list(p: &mut Parser, ket: SyntaxKind) {
261
258
// let ref mut d = ();
262
259
// let e @ _ = ();
263
260
// let ref mut f @ g @ _ = ();
264
- // let box i = Box::new(1i32);
265
261
// }
266
262
fn bind_pat ( p : & mut Parser , with_at : bool ) -> CompletedMarker {
267
263
let m = p. start ( ) ;
268
- p. eat ( T ! [ box] ) ;
269
264
p. eat ( T ! [ ref] ) ;
270
265
p. eat ( T ! [ mut ] ) ;
271
266
name ( p) ;
@@ -274,3 +269,29 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
274
269
}
275
270
m. complete ( p, BIND_PAT )
276
271
}
272
+
273
+ // test_err ref_box_pat
274
+ // fn main() {
275
+ // let ref box i = ();
276
+ // }
277
+
278
+ // test box_pat
279
+ // struct Outer<'a> {
280
+ // i: Box<i32>,
281
+ // j: Box<Inner<'a>>,
282
+ // }
283
+ //
284
+ // struct Inner<'a>(&'a i32);
285
+ //
286
+ // fn main() {
287
+ // let box i = ();
288
+ // let box Outer { box i, j: box Inner(box &x) } = ();
289
+ // let box ref mut i = ();
290
+ // }
291
+ fn box_pat ( p : & mut Parser ) -> CompletedMarker {
292
+ assert ! ( p. at( T ![ box] ) ) ;
293
+ let m = p. start ( ) ;
294
+ p. bump ( ) ;
295
+ pattern ( p) ;
296
+ m. complete ( p, BOX_PAT )
297
+ }
0 commit comments