@@ -55,8 +55,10 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
55
55
fn from_internal ( ( stream, rustc) : ( TokenStream , & mut Rustc < ' _ , ' _ > ) ) -> Self {
56
56
use rustc_ast:: token:: * ;
57
57
58
+ // Estimate the capacity as `stream.len()` rounded up to the next power
59
+ // of two to limit the number of required reallocations.
60
+ let mut trees = Vec :: with_capacity ( stream. len ( ) . next_power_of_two ( ) ) ;
58
61
let mut cursor = stream. into_trees ( ) ;
59
- let mut trees = Vec :: new ( ) ;
60
62
61
63
while let Some ( ( tree, spacing) ) = cursor. next_with_spacing ( ) {
62
64
let joint = spacing == Joint ;
@@ -77,105 +79,88 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
77
79
tokenstream:: TokenTree :: Token ( token) => token,
78
80
} ;
79
81
80
- macro_rules! tt {
81
- ( $ty: ident { $( $field: ident $( : $value: expr) * ) ,+ $( , ) ? } ) => (
82
- trees. push( TokenTree :: $ty( self :: $ty {
83
- $( $field $( : $value) * , ) +
84
- span,
85
- } ) )
86
- ) ;
87
- ( $ty: ident:: $method: ident( $( $value: expr) ,* ) ) => (
88
- trees. push( TokenTree :: $ty( self :: $ty:: $method( $( $value, ) * span) ) )
89
- ) ;
90
- }
91
- macro_rules! op {
92
- ( $a: expr) => { {
93
- tt!( Punct { ch: $a, joint } ) ;
94
- } } ;
95
- ( $a: expr, $b: expr) => { {
96
- tt!( Punct { ch: $a, joint: true } ) ;
97
- tt!( Punct { ch: $b, joint } ) ;
98
- } } ;
99
- ( $a: expr, $b: expr, $c: expr) => { {
100
- tt!( Punct { ch: $a, joint: true } ) ;
101
- tt!( Punct { ch: $b, joint: true } ) ;
102
- tt!( Punct { ch: $c, joint } ) ;
103
- } } ;
104
- }
82
+ let mut op = |s : & str | {
83
+ assert ! ( s. is_ascii( ) ) ;
84
+ trees. extend ( s. as_bytes ( ) . iter ( ) . enumerate ( ) . map ( |( idx, & ch) | {
85
+ TokenTree :: Punct ( Punct { ch, joint : joint || idx != s. len ( ) - 1 , span } )
86
+ } ) ) ;
87
+ } ;
105
88
106
89
match kind {
107
- Eq => op ! ( '=' ) ,
108
- Lt => op ! ( '<' ) ,
109
- Le => op ! ( '<' , '=' ) ,
110
- EqEq => op ! ( '=' , '=' ) ,
111
- Ne => op ! ( '!' , '=' ) ,
112
- Ge => op ! ( '>' , '=' ) ,
113
- Gt => op ! ( '>' ) ,
114
- AndAnd => op ! ( '&' , '&' ) ,
115
- OrOr => op ! ( '|' , '|' ) ,
116
- Not => op ! ( '!' ) ,
117
- Tilde => op ! ( '~' ) ,
118
- BinOp ( Plus ) => op ! ( '+' ) ,
119
- BinOp ( Minus ) => op ! ( '-' ) ,
120
- BinOp ( Star ) => op ! ( '*' ) ,
121
- BinOp ( Slash ) => op ! ( '/' ) ,
122
- BinOp ( Percent ) => op ! ( '%' ) ,
123
- BinOp ( Caret ) => op ! ( '^' ) ,
124
- BinOp ( And ) => op ! ( '&' ) ,
125
- BinOp ( Or ) => op ! ( '|' ) ,
126
- BinOp ( Shl ) => op ! ( '<' , '<' ) ,
127
- BinOp ( Shr ) => op ! ( '>' , '>' ) ,
128
- BinOpEq ( Plus ) => op ! ( '+' , '=' ) ,
129
- BinOpEq ( Minus ) => op ! ( '-' , '=' ) ,
130
- BinOpEq ( Star ) => op ! ( '*' , '=' ) ,
131
- BinOpEq ( Slash ) => op ! ( '/' , '=' ) ,
132
- BinOpEq ( Percent ) => op ! ( '%' , '=' ) ,
133
- BinOpEq ( Caret ) => op ! ( '^' , '=' ) ,
134
- BinOpEq ( And ) => op ! ( '&' , '=' ) ,
135
- BinOpEq ( Or ) => op ! ( '|' , '=' ) ,
136
- BinOpEq ( Shl ) => op ! ( '<' , '<' , '=' ) ,
137
- BinOpEq ( Shr ) => op ! ( '>' , '>' , '=' ) ,
138
- At => op ! ( '@' ) ,
139
- Dot => op ! ( '.' ) ,
140
- DotDot => op ! ( '.' , '.' ) ,
141
- DotDotDot => op ! ( '.' , '.' , '.' ) ,
142
- DotDotEq => op ! ( '.' , '.' , '=' ) ,
143
- Comma => op ! ( ',' ) ,
144
- Semi => op ! ( ';' ) ,
145
- Colon => op ! ( ':' ) ,
146
- ModSep => op ! ( ':' , ':' ) ,
147
- RArrow => op ! ( '-' , '>' ) ,
148
- LArrow => op ! ( '<' , '-' ) ,
149
- FatArrow => op ! ( '=' , '>' ) ,
150
- Pound => op ! ( '#' ) ,
151
- Dollar => op ! ( '$' ) ,
152
- Question => op ! ( '?' ) ,
153
- SingleQuote => op ! ( '\'' ) ,
154
-
155
- Ident ( name, false ) if name == kw:: DollarCrate => tt ! ( Ident :: dollar_crate( ) ) ,
156
- Ident ( name, is_raw) => tt ! ( Ident :: new( rustc. sess( ) , name, is_raw) ) ,
90
+ Eq => op ( "=" ) ,
91
+ Lt => op ( "<" ) ,
92
+ Le => op ( "<=" ) ,
93
+ EqEq => op ( "==" ) ,
94
+ Ne => op ( "!=" ) ,
95
+ Ge => op ( ">=" ) ,
96
+ Gt => op ( ">" ) ,
97
+ AndAnd => op ( "&&" ) ,
98
+ OrOr => op ( "||" ) ,
99
+ Not => op ( "!" ) ,
100
+ Tilde => op ( "~" ) ,
101
+ BinOp ( Plus ) => op ( "+" ) ,
102
+ BinOp ( Minus ) => op ( "-" ) ,
103
+ BinOp ( Star ) => op ( "*" ) ,
104
+ BinOp ( Slash ) => op ( "/" ) ,
105
+ BinOp ( Percent ) => op ( "%" ) ,
106
+ BinOp ( Caret ) => op ( "^" ) ,
107
+ BinOp ( And ) => op ( "&" ) ,
108
+ BinOp ( Or ) => op ( "|" ) ,
109
+ BinOp ( Shl ) => op ( "<<" ) ,
110
+ BinOp ( Shr ) => op ( ">>" ) ,
111
+ BinOpEq ( Plus ) => op ( "+=" ) ,
112
+ BinOpEq ( Minus ) => op ( "-=" ) ,
113
+ BinOpEq ( Star ) => op ( "*=" ) ,
114
+ BinOpEq ( Slash ) => op ( "/=" ) ,
115
+ BinOpEq ( Percent ) => op ( "%=" ) ,
116
+ BinOpEq ( Caret ) => op ( "^=" ) ,
117
+ BinOpEq ( And ) => op ( "&=" ) ,
118
+ BinOpEq ( Or ) => op ( "|=" ) ,
119
+ BinOpEq ( Shl ) => op ( "<<=" ) ,
120
+ BinOpEq ( Shr ) => op ( ">>=" ) ,
121
+ At => op ( "@" ) ,
122
+ Dot => op ( "." ) ,
123
+ DotDot => op ( ".." ) ,
124
+ DotDotDot => op ( "..." ) ,
125
+ DotDotEq => op ( "..=" ) ,
126
+ Comma => op ( "," ) ,
127
+ Semi => op ( ";" ) ,
128
+ Colon => op ( ":" ) ,
129
+ ModSep => op ( "::" ) ,
130
+ RArrow => op ( "->" ) ,
131
+ LArrow => op ( "<-" ) ,
132
+ FatArrow => op ( "=>" ) ,
133
+ Pound => op ( "#" ) ,
134
+ Dollar => op ( "$" ) ,
135
+ Question => op ( "?" ) ,
136
+ SingleQuote => op ( "'" ) ,
137
+
138
+ Ident ( name, false ) if name == kw:: DollarCrate => trees . push ( TokenTree :: Ident ( Ident :: dollar_crate ( span ) ) ) ,
139
+ Ident ( name, is_raw) => trees . push ( TokenTree :: Ident ( Ident :: new ( rustc. sess ( ) , name, is_raw, span ) ) ) ,
157
140
Lifetime ( name) => {
158
141
let ident = symbol:: Ident :: new ( name, span) . without_first_quote ( ) ;
159
- tt ! ( Punct { ch: '\'' , joint: true } ) ;
160
- tt ! ( Ident :: new( rustc. sess( ) , ident. name, false ) ) ;
142
+ trees. extend ( [
143
+ TokenTree :: Punct ( Punct { ch : b'\'' , joint : true , span } ) ,
144
+ TokenTree :: Ident ( Ident :: new ( rustc. sess ( ) , ident. name , false , span) ) ,
145
+ ] ) ;
161
146
}
162
- Literal ( lit) => tt ! ( Literal { lit } ) ,
147
+ Literal ( lit) => trees . push ( TokenTree :: Literal ( self :: Literal { lit, span } ) ) ,
163
148
DocComment ( _, attr_style, data) => {
164
149
let mut escaped = String :: new ( ) ;
165
150
for ch in data. as_str ( ) . chars ( ) {
166
151
escaped. extend ( ch. escape_debug ( ) ) ;
167
152
}
168
- let stream = vec ! [
153
+ let stream = [
169
154
Ident ( sym:: doc, false ) ,
170
155
Eq ,
171
156
TokenKind :: lit ( token:: Str , Symbol :: intern ( & escaped) , None ) ,
172
157
]
173
158
. into_iter ( )
174
159
. map ( |kind| tokenstream:: TokenTree :: token ( kind, span) )
175
160
. collect ( ) ;
176
- tt ! ( Punct { ch: '#' , joint: false } ) ;
161
+ trees . push ( TokenTree :: Punct ( Punct { ch : b '#', joint : false , span } ) ) ;
177
162
if attr_style == ast:: AttrStyle :: Inner {
178
- tt ! ( Punct { ch: '!' , joint: false } ) ;
163
+ trees . push ( TokenTree :: Punct ( Punct { ch : b '!', joint : false , span } ) ) ;
179
164
}
180
165
trees. push ( TokenTree :: Group ( Group {
181
166
delimiter : pm:: Delimiter :: Bracket ,
@@ -190,6 +175,12 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
190
175
191
176
Interpolated ( nt) => {
192
177
let stream = TokenStream :: from_nonterminal_ast ( & nt) ;
178
+ // A hack used to pass AST fragments to attribute and derive
179
+ // macros as a single nonterminal token instead of a token
180
+ // stream. Such token needs to be "unwrapped" and not
181
+ // represented as a delimited group.
182
+ // FIXME: It needs to be removed, but there are some
183
+ // compatibility issues (see #73345).
193
184
if crate :: base:: nt_pretty_printing_compatibility_hack ( & nt, rustc. sess ( ) ) {
194
185
trees. extend ( Self :: from_internal ( ( stream, rustc) ) ) ;
195
186
} else {
@@ -254,28 +245,28 @@ impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Ident, Literal> {
254
245
} ;
255
246
256
247
let kind = match ch {
257
- '=' => Eq ,
258
- '<' => Lt ,
259
- '>' => Gt ,
260
- '!' => Not ,
261
- '~' => Tilde ,
262
- '+' => BinOp ( Plus ) ,
263
- '-' => BinOp ( Minus ) ,
264
- '*' => BinOp ( Star ) ,
265
- '/' => BinOp ( Slash ) ,
266
- '%' => BinOp ( Percent ) ,
267
- '^' => BinOp ( Caret ) ,
268
- '&' => BinOp ( And ) ,
269
- '|' => BinOp ( Or ) ,
270
- '@' => At ,
271
- '.' => Dot ,
272
- ',' => Comma ,
273
- ';' => Semi ,
274
- ':' => Colon ,
275
- '#' => Pound ,
276
- '$' => Dollar ,
277
- '?' => Question ,
278
- '\'' => SingleQuote ,
248
+ b '=' => Eq ,
249
+ b '<' => Lt ,
250
+ b '>' => Gt ,
251
+ b '!' => Not ,
252
+ b '~' => Tilde ,
253
+ b '+' => BinOp ( Plus ) ,
254
+ b '-' => BinOp ( Minus ) ,
255
+ b '*' => BinOp ( Star ) ,
256
+ b '/' => BinOp ( Slash ) ,
257
+ b '%' => BinOp ( Percent ) ,
258
+ b '^' => BinOp ( Caret ) ,
259
+ b '&' => BinOp ( And ) ,
260
+ b '|' => BinOp ( Or ) ,
261
+ b '@' => At ,
262
+ b '.' => Dot ,
263
+ b ',' => Comma ,
264
+ b ';' => Semi ,
265
+ b ':' => Colon ,
266
+ b '#' => Pound ,
267
+ b '$' => Dollar ,
268
+ b '?' => Question ,
269
+ b '\'' => SingleQuote ,
279
270
_ => unreachable ! ( ) ,
280
271
} ;
281
272
0 commit comments