@@ -2,7 +2,7 @@ use super::*;
2
2
3
3
pub ( super ) const PATTERN_FIRST : TokenSet = expressions:: LITERAL_FIRST
4
4
. union ( paths:: PATH_FIRST )
5
- . union ( token_set ! [ BOX_KW , REF_KW , MUT_KW , L_PAREN , L_BRACK , AMP , UNDERSCORE , MINUS ] ) ;
5
+ . union ( token_set ! [ BOX_KW , REF_KW , MUT_KW , L_PAREN , L_BRACK , AMP , UNDERSCORE , MINUS , DOT ] ) ;
6
6
7
7
pub ( crate ) fn pattern ( p : & mut Parser ) {
8
8
pattern_r ( p, PAT_RECOVERY_SET ) ;
@@ -73,6 +73,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
73
73
_ if paths:: is_use_path_start ( p) => path_pat ( p) ,
74
74
_ if is_literal_pat_start ( p) => literal_pat ( p) ,
75
75
76
+ T ! [ . ] if p. at ( T ! [ ..] ) => dot_dot_pat ( p) ,
76
77
T ! [ _] => placeholder_pat ( p) ,
77
78
T ! [ & ] => ref_pat ( p) ,
78
79
T ! [ '(' ] => tuple_pat ( p) ,
@@ -163,7 +164,9 @@ fn record_field_pat_list(p: &mut Parser) {
163
164
p. bump_any ( ) ;
164
165
while !p. at ( EOF ) && !p. at ( T ! [ '}' ] ) {
165
166
match p. current ( ) {
167
+ // A trailing `..` is *not* treated as a DOT_DOT_PAT.
166
168
T ! [ . ] if p. at ( T ! [ ..] ) => p. bump ( T ! [ ..] ) ,
169
+
167
170
IDENT if p. nth ( 1 ) == T ! [ : ] => record_field_pat ( p) ,
168
171
T ! [ '{' ] => error_block ( p, "expected ident" ) ,
169
172
T ! [ box] => {
@@ -201,6 +204,39 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
201
204
m. complete ( p, PLACEHOLDER_PAT )
202
205
}
203
206
207
+ // test dot_dot_pat
208
+ // fn main() {
209
+ // let .. = ();
210
+ // //
211
+ // // Tuples
212
+ // //
213
+ // let (a, ..) = ();
214
+ // let (a, ..,) = ();
215
+ // let Tuple(a, ..) = ();
216
+ // let Tuple(a, ..,) = ();
217
+ // let (.., ..) = ();
218
+ // let Tuple(.., ..) = ();
219
+ // let (.., a, ..) = ();
220
+ // let Tuple(.., a, ..) = ();
221
+ // //
222
+ // // Slices
223
+ // //
224
+ // let [..] = ();
225
+ // let [head, ..] = ();
226
+ // let [head, tail @ ..] = ();
227
+ // let [head, .., cons] = ();
228
+ // let [head, mid @ .., cons] = ();
229
+ // let [head, .., .., cons] = ();
230
+ // let [head, .., mid, tail @ ..] = ();
231
+ // let [head, .., mid, .., cons] = ();
232
+ // }
233
+ fn dot_dot_pat ( p : & mut Parser ) -> CompletedMarker {
234
+ assert ! ( p. at( T ![ ..] ) ) ;
235
+ let m = p. start ( ) ;
236
+ p. bump ( T ! [ ..] ) ;
237
+ m. complete ( p, DOT_DOT_PAT )
238
+ }
239
+
204
240
// test ref_pat
205
241
// fn main() {
206
242
// let &a = ();
@@ -241,16 +277,12 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker {
241
277
242
278
fn pat_list ( p : & mut Parser , ket : SyntaxKind ) {
243
279
while !p. at ( EOF ) && !p. at ( ket) {
244
- match p. current ( ) {
245
- T ! [ . ] if p. at ( T ! [ ..] ) => p. bump ( T ! [ ..] ) ,
246
- _ => {
247
- if !p. at_ts ( PATTERN_FIRST ) {
248
- p. error ( "expected a pattern" ) ;
249
- break ;
250
- }
251
- pattern ( p)
252
- }
280
+ if !p. at_ts ( PATTERN_FIRST ) {
281
+ p. error ( "expected a pattern" ) ;
282
+ break ;
253
283
}
284
+
285
+ pattern ( p) ;
254
286
if !p. at ( ket) {
255
287
p. expect ( T ! [ , ] ) ;
256
288
}
0 commit comments