@@ -27,6 +27,14 @@ use crate::{
27
27
pub use :: parser:: TopEntryPoint ;
28
28
pub use tt:: { Delimiter , DelimiterKind , Punct } ;
29
29
30
+ pub use crate :: {
31
+ syntax_bridge:: {
32
+ parse_exprs_with_sep, parse_to_token_tree, syntax_node_to_token_tree,
33
+ syntax_node_to_token_tree_censored, token_tree_to_syntax_node,
34
+ } ,
35
+ token_map:: TokenMap ,
36
+ } ;
37
+
30
38
#[ derive( Debug , PartialEq , Eq , Clone ) ]
31
39
pub enum ParseError {
32
40
UnexpectedToken ( String ) ,
@@ -70,14 +78,6 @@ impl fmt::Display for ExpandError {
70
78
}
71
79
}
72
80
73
- pub use crate :: {
74
- syntax_bridge:: {
75
- parse_exprs_with_sep, parse_to_token_tree, syntax_node_to_token_tree,
76
- syntax_node_to_token_tree_censored, token_tree_to_syntax_node,
77
- } ,
78
- token_map:: TokenMap ,
79
- } ;
80
-
81
81
/// This struct contains AST for a single `macro_rules` definition. What might
82
82
/// be very confusing is that AST has almost exactly the same shape as
83
83
/// `tt::TokenTree`, but there's a crucial difference: in macro rules, `$ident`
@@ -121,11 +121,9 @@ impl Shift {
121
121
}
122
122
}
123
123
tt:: TokenTree :: Leaf ( leaf) => {
124
- let id = match leaf {
125
- tt:: Leaf :: Literal ( it) => it. id ,
126
- tt:: Leaf :: Punct ( it) => it. id ,
127
- tt:: Leaf :: Ident ( it) => it. id ,
128
- } ;
124
+ let & ( tt:: Leaf :: Ident ( tt:: Ident { id, .. } )
125
+ | tt:: Leaf :: Punct ( tt:: Punct { id, .. } )
126
+ | tt:: Leaf :: Literal ( tt:: Literal { id, .. } ) ) = leaf;
129
127
130
128
( id != tt:: TokenId :: unspecified ( ) ) . then ( || id. 0 )
131
129
}
@@ -138,15 +136,15 @@ impl Shift {
138
136
pub fn shift_all ( self , tt : & mut tt:: Subtree ) {
139
137
for t in & mut tt. token_trees {
140
138
match t {
141
- tt:: TokenTree :: Leaf ( leaf ) => match leaf {
142
- tt:: Leaf :: Ident ( ident ) => ident . id = self . shift ( ident . id ) ,
143
- tt:: Leaf :: Punct ( punct ) => punct . id = self . shift ( punct . id ) ,
144
- tt:: Leaf :: Literal ( lit ) => lit . id = self . shift ( lit . id ) ,
145
- } ,
139
+ tt:: TokenTree :: Leaf (
140
+ tt:: Leaf :: Ident ( tt :: Ident { id , .. } )
141
+ | tt:: Leaf :: Punct ( tt :: Punct { id , .. } )
142
+ | tt:: Leaf :: Literal ( tt :: Literal { id , .. } ) ,
143
+ ) => * id = self . shift ( * id ) ,
146
144
tt:: TokenTree :: Subtree ( tt) => {
147
145
if let Some ( it) = tt. delimiter . as_mut ( ) {
148
146
it. id = self . shift ( it. id ) ;
149
- } ;
147
+ }
150
148
self . shift_all ( tt)
151
149
}
152
150
}
@@ -155,9 +153,10 @@ impl Shift {
155
153
156
154
pub fn shift ( self , id : tt:: TokenId ) -> tt:: TokenId {
157
155
if id == tt:: TokenId :: unspecified ( ) {
158
- return id;
156
+ id
157
+ } else {
158
+ tt:: TokenId ( id. 0 + self . 0 )
159
159
}
160
- tt:: TokenId ( id. 0 + self . 0 )
161
160
}
162
161
163
162
pub fn unshift ( self , id : tt:: TokenId ) -> Option < tt:: TokenId > {
@@ -190,8 +189,8 @@ impl DeclarativeMacro {
190
189
}
191
190
}
192
191
193
- for rule in & rules {
194
- validate ( & rule . lhs ) ?;
192
+ for Rule { lhs , .. } in & rules {
193
+ validate ( lhs) ?;
195
194
}
196
195
197
196
Ok ( DeclarativeMacro { rules, shift : Shift :: new ( tt) } )
@@ -220,12 +219,13 @@ impl DeclarativeMacro {
220
219
cov_mark:: hit!( parse_macro_def_simple) ;
221
220
let rule = Rule :: parse ( & mut src, false ) ?;
222
221
if src. len ( ) != 0 {
223
- return Err ( ParseError :: Expected ( "remain tokens in macro def" . to_string ( ) ) ) ;
222
+ return Err ( ParseError :: Expected ( "remaining tokens in macro def" . to_string ( ) ) ) ;
224
223
}
225
224
rules. push ( rule) ;
226
225
}
227
- for rule in & rules {
228
- validate ( & rule. lhs ) ?;
226
+
227
+ for Rule { lhs, .. } in & rules {
228
+ validate ( lhs) ?;
229
229
}
230
230
231
231
Ok ( DeclarativeMacro { rules, shift : Shift :: new ( tt) } )
@@ -281,28 +281,18 @@ fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> {
281
281
Op :: Repeat { tokens : subtree, separator, .. } => {
282
282
// Checks that no repetition which could match an empty token
283
283
// https://github.com/rust-lang/rust/blob/a58b1ed44f5e06976de2bdc4d7dc81c36a96934f/src/librustc_expand/mbe/macro_rules.rs#L558
284
-
285
- if separator. is_none ( )
286
- && subtree. iter ( ) . all ( |child_op| {
287
- match child_op {
288
- Op :: Var { kind, .. } => {
289
- // vis is optional
290
- if kind. as_ref ( ) . map_or ( false , |it| it == "vis" ) {
291
- return true ;
292
- }
293
- }
294
- Op :: Repeat { kind, .. } => {
295
- return matches ! (
296
- kind,
297
- parser:: RepeatKind :: ZeroOrMore | parser:: RepeatKind :: ZeroOrOne
298
- )
299
- }
300
- Op :: Leaf ( _) => { }
301
- Op :: Subtree { .. } => { }
302
- }
303
- false
304
- } )
305
- {
284
+ let lsh_is_empty_seq = separator. is_none ( ) && subtree. iter ( ) . all ( |child_op| {
285
+ match child_op {
286
+ // vis is optional
287
+ Op :: Var { kind : Some ( kind) , .. } => kind == "vis" ,
288
+ Op :: Repeat {
289
+ kind : parser:: RepeatKind :: ZeroOrMore | parser:: RepeatKind :: ZeroOrOne ,
290
+ ..
291
+ } => true ,
292
+ _ => false ,
293
+ }
294
+ } ) ;
295
+ if lsh_is_empty_seq {
306
296
return Err ( ParseError :: RepetitionEmptyTokenTree ) ;
307
297
}
308
298
validate ( subtree) ?
0 commit comments