@@ -98,6 +98,7 @@ macro_rules! prec {
98
98
enum PartialOp {
99
99
Not ,
100
100
LoneNot ,
101
+ Colon ,
101
102
Dot ,
102
103
Mul ,
103
104
Div ,
@@ -118,6 +119,7 @@ impl PartialOp {
118
119
fn precedence ( self ) -> Result < ( ExprPrecedence , ExprPosition , ExprPosition ) , ( ) > {
119
120
match self {
120
121
Self :: Not | Self :: LoneNot | Self :: Dot => Err ( ( ) ) ,
122
+ Self :: Colon => Ok ( ( ExprPrecedence :: Cast , ExprPosition :: Cast , ExprPosition :: Cast ) ) ,
121
123
Self :: Mul | Self :: Div | Self :: Mod => Ok ( prec ! ( Mul ) ) ,
122
124
Self :: Add | Self :: Sub => Ok ( prec ! ( Add ) ) ,
123
125
Self :: Shr | Self :: Shl => Ok ( prec ! ( Shift ) ) ,
@@ -132,6 +134,7 @@ impl PartialOp {
132
134
fn as_str ( self ) -> & ' static str {
133
135
match self {
134
136
Self :: Not | Self :: LoneNot => "!" ,
137
+ Self :: Colon => ":" ,
135
138
Self :: Dot => "." ,
136
139
Self :: Mul => "*" ,
137
140
Self :: Div => "/" ,
@@ -158,6 +161,7 @@ enum State {
158
161
Expr ( ExprKind ) ,
159
162
BinOp ( ExprPosition ) ,
160
163
PartialBinOp ( ExprKind , PartialOp ) ,
164
+ PathSep ,
161
165
}
162
166
impl Default for State {
163
167
fn default ( ) -> Self {
@@ -188,7 +192,6 @@ struct Snip {
188
192
}
189
193
190
194
struct ExprParser {
191
- state : State ,
192
195
next_string : String ,
193
196
precedence : ExprPrecedence ,
194
197
result : TokenStream ,
@@ -197,7 +200,6 @@ impl ExprParser {
197
200
#[ allow( clippy:: needless_pass_by_value) ]
198
201
fn new ( cx_tokens : Vec < TT > , app_tokens : Vec < TT > , ctxt_tokens : Vec < TT > ) -> Self {
199
202
Self {
200
- state : State :: default ( ) ,
201
203
next_string : String :: new ( ) ,
202
204
precedence : ExprPrecedence :: Postfix ,
203
205
result : quote ! {
@@ -210,7 +212,7 @@ impl ExprParser {
210
212
}
211
213
}
212
214
213
- fn push_str ( & mut self ) {
215
+ fn push_next_string ( & mut self ) {
214
216
if !self . next_string . is_empty ( ) {
215
217
let s = & self . next_string ;
216
218
self . result . extend ( quote ! ( sugg. push_str( #s) ; ) ) ;
@@ -241,11 +243,38 @@ impl ExprParser {
241
243
}
242
244
}
243
245
246
+ fn parse_ty ( & mut self , iter : & mut <TokenStream as IntoIterator >:: IntoIter ) -> Result < ( ) , Error > {
247
+ match iter. next ( ) . unwrap ( ) {
248
+ TT :: Punct ( p) if p. as_char ( ) == '$' => match iter. next ( ) . unwrap ( ) {
249
+ TT :: Ident ( cmd) => match & * cmd. to_string ( ) {
250
+ "ident" => match iter. next ( ) . unwrap ( ) {
251
+ TT :: Group ( args) if args. delimiter ( ) == Delimiter :: Parenthesis => {
252
+ self . push_next_string ( ) ;
253
+ let stream = args. stream ( ) ;
254
+ self . result . extend ( quote ! {
255
+ let _ = core:: write!( sugg, "{}" , #stream) ;
256
+ } ) ;
257
+ } ,
258
+ tt => return Err ( Error :: UnexpectedToken ( tt. span ( ) ) ) ,
259
+ } ,
260
+ _ => return Err ( Error :: UnknownCommand ( cmd. span ( ) ) ) ,
261
+ } ,
262
+ tt => return Err ( Error :: UnexpectedToken ( tt. span ( ) ) ) ,
263
+ } ,
264
+ TT :: Ident ( name) => {
265
+ let _ = write ! ( self . next_string, "{} " , name) ;
266
+ } ,
267
+ tt => return Err ( Error :: UnexpectedToken ( tt. span ( ) ) ) ,
268
+ }
269
+ Ok ( ( ) )
270
+ }
271
+
244
272
#[ allow( clippy:: too_many_lines) ]
245
273
fn parse ( & mut self , mut iter : <TokenStream as IntoIterator >:: IntoIter ) -> Result < ( ) , Error > {
274
+ let mut state = State :: default ( ) ;
246
275
while let Some ( tt) = iter. next ( ) {
247
- self . state = match ( tt, mem:: take ( & mut self . state ) ) {
248
- ( TT :: Punct ( p) , state @ ( Start | Prefix | PrefixRef | BinOp ( _) | PartialBinOp ( ..) ) )
276
+ state = match ( tt, mem:: take ( & mut state) ) {
277
+ ( TT :: Punct ( p) , state @ ( Start | Prefix | PrefixRef | BinOp ( _) | PartialBinOp ( ..) | PathSep ) )
249
278
if p. as_char ( ) == '$' =>
250
279
{
251
280
match iter. next ( ) . unwrap ( ) {
@@ -263,9 +292,9 @@ impl ExprParser {
263
292
let _ = write ! ( self . next_string, " {} " , op. as_str( ) ) ;
264
293
rhs_pos
265
294
} ,
266
- Expr ( _) => return Err ( Error :: UnexpectedSnip ( cmd. span ( ) ) ) ,
295
+ Expr ( _) | PathSep => return Err ( Error :: UnexpectedSnip ( cmd. span ( ) ) ) ,
267
296
} ;
268
- self . push_str ( ) ;
297
+ self . push_next_string ( ) ;
269
298
Expr ( ExprKind :: Snip ( Snip {
270
299
position,
271
300
stream : args. stream ( ) ,
@@ -279,7 +308,7 @@ impl ExprParser {
279
308
}
280
309
match iter. next ( ) . unwrap ( ) {
281
310
TT :: Group ( args) if args. delimiter ( ) == Delimiter :: Parenthesis => {
282
- self . push_str ( ) ;
311
+ self . push_next_string ( ) ;
283
312
let stream = args. stream ( ) ;
284
313
self . result . extend ( quote ! {
285
314
let mutability: rustc_ast:: Mutability = #stream;
@@ -301,7 +330,7 @@ impl ExprParser {
301
330
} else {
302
331
self . push_partial_op ( state) ;
303
332
}
304
- self . push_str ( ) ;
333
+ self . push_next_string ( ) ;
305
334
let stream = args. stream ( ) ;
306
335
self . result . extend ( quote ! {
307
336
let _ = core:: write!( sugg, "{}" , #stream) ;
@@ -322,7 +351,6 @@ impl ExprParser {
322
351
self . push_snip ( kind, ExprPosition :: Postfix ) ;
323
352
let precedence = self . precedence ;
324
353
self . next_string . push ( '(' ) ;
325
- self . state = Start ;
326
354
self . parse ( g. stream ( ) . into_iter ( ) ) ?;
327
355
self . next_string . push ( ')' ) ;
328
356
self . precedence = precedence;
@@ -332,7 +360,6 @@ impl ExprParser {
332
360
self . push_snip ( kind, ExprPosition :: Postfix ) ;
333
361
let precedence = self . precedence ;
334
362
self . next_string . push ( '[' ) ;
335
- self . state = Start ;
336
363
self . parse ( g. stream ( ) . into_iter ( ) ) ?;
337
364
self . next_string . push ( ']' ) ;
338
365
self . precedence = precedence;
@@ -359,6 +386,14 @@ impl ExprParser {
359
386
} ,
360
387
tt => return Err ( Error :: UnexpectedToken ( tt. span ( ) ) ) ,
361
388
} ,
389
+ ( ':' , Spacing :: Joint ) => PartialBinOp ( kind, PartialOp :: Colon ) ,
390
+ ( ':' , Spacing :: Alone ) => {
391
+ self . push_snip ( kind, ExprPosition :: Cast ) ;
392
+ self . next_string . push_str ( ": " ) ;
393
+ self . parse_ty ( & mut iter) ;
394
+ self . push_precedence ( ExprPrecedence :: Cast ) ;
395
+ Expr ( ExprKind :: Normal )
396
+ } ,
362
397
( '=' , Spacing :: Joint ) => PartialBinOp ( kind, PartialOp :: Assign ) ,
363
398
( '=' , Spacing :: Alone ) => {
364
399
self . push_snip ( kind, ExprPosition :: AssignLhs ) ;
@@ -422,6 +457,10 @@ impl ExprParser {
422
457
self . next_string . push_str ( ".." ) ;
423
458
BinOp ( ExprPosition :: Range )
424
459
} ,
460
+ ( ':' , PartialOp :: Colon ) if matches ! ( kind, ExprKind :: Ident ) => {
461
+ self . next_string . push_str ( "::" ) ;
462
+ PathSep
463
+ } ,
425
464
(
426
465
'=' ,
427
466
PartialOp :: Mul
@@ -528,11 +567,25 @@ impl ExprParser {
528
567
} ,
529
568
s => {
530
569
self . push_partial_op ( state) ;
531
- let _ = write ! ( self . next_string, "{}" , s) ;
570
+ self . next_string . push_str ( s) ;
532
571
Expr ( ExprKind :: Ident )
533
572
} ,
534
573
}
535
574
} ,
575
+ ( TT :: Ident ( name) , PathSep ) => {
576
+ let _ = write ! ( self . next_string, "{}" , name) ;
577
+ Expr ( ExprKind :: Ident )
578
+ } ,
579
+ ( TT :: Ident ( name) , Expr ( kind) ) => match & * name. to_string ( ) {
580
+ "as" => {
581
+ self . push_snip ( kind, ExprPosition :: Cast ) ;
582
+ self . push_precedence ( ExprPrecedence :: Cast ) ;
583
+ self . next_string . push_str ( " as " ) ;
584
+ self . parse_ty ( & mut iter) ;
585
+ Expr ( ExprKind :: Normal )
586
+ } ,
587
+ _ => return Err ( Error :: UnexpectedToken ( name. span ( ) ) ) ,
588
+ } ,
536
589
537
590
// Atoms
538
591
( TT :: Literal ( lit) , state @ ( Start | Prefix | PrefixRef | BinOp ( _) | PartialBinOp ( ..) ) ) => {
@@ -546,7 +599,6 @@ impl ExprParser {
546
599
self . push_partial_op ( state) ;
547
600
let precedence = self . precedence ;
548
601
self . next_string . push ( '(' ) ;
549
- self . state = Start ;
550
602
self . parse ( g. stream ( ) . into_iter ( ) ) ?;
551
603
self . next_string . push ( ')' ) ;
552
604
self . precedence = precedence;
@@ -557,8 +609,8 @@ impl ExprParser {
557
609
} ;
558
610
}
559
611
560
- self . push_str ( ) ;
561
- match mem :: take ( & mut self . state ) {
612
+ self . push_next_string ( ) ;
613
+ match state {
562
614
Start => Ok ( ( ) ) ,
563
615
Expr ( kind) => {
564
616
self . push_snip ( kind, ExprPosition :: Closure ) ;
0 commit comments