@@ -55,8 +55,10 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
5555 fn from_internal ( ( stream, rustc) : ( TokenStream , & mut Rustc < ' _ , ' _ > ) ) -> Self {
5656 use rustc_ast:: token:: * ;
5757
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 ( ) ) ;
5861 let mut cursor = stream. into_trees ( ) ;
59- let mut trees = Vec :: new ( ) ;
6062
6163 while let Some ( ( tree, spacing) ) = cursor. next_with_spacing ( ) {
6264 let joint = spacing == Joint ;
@@ -77,105 +79,88 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
7779 tokenstream:: TokenTree :: Token ( token) => token,
7880 } ;
7981
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+ } ;
10588
10689 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 ) ) ) ,
157140 Lifetime ( name) => {
158141 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+ ] ) ;
161146 }
162- Literal ( lit) => tt ! ( Literal { lit } ) ,
147+ Literal ( lit) => trees . push ( TokenTree :: Literal ( self :: Literal { lit, span } ) ) ,
163148 DocComment ( _, attr_style, data) => {
164149 let mut escaped = String :: new ( ) ;
165150 for ch in data. as_str ( ) . chars ( ) {
166151 escaped. extend ( ch. escape_debug ( ) ) ;
167152 }
168- let stream = vec ! [
153+ let stream = [
169154 Ident ( sym:: doc, false ) ,
170155 Eq ,
171156 TokenKind :: lit ( token:: Str , Symbol :: intern ( & escaped) , None ) ,
172157 ]
173158 . into_iter ( )
174159 . map ( |kind| tokenstream:: TokenTree :: token ( kind, span) )
175160 . collect ( ) ;
176- tt ! ( Punct { ch: '#' , joint: false } ) ;
161+ trees . push ( TokenTree :: Punct ( Punct { ch : b '#', joint : false , span } ) ) ;
177162 if attr_style == ast:: AttrStyle :: Inner {
178- tt ! ( Punct { ch: '!' , joint: false } ) ;
163+ trees . push ( TokenTree :: Punct ( Punct { ch : b '!', joint : false , span } ) ) ;
179164 }
180165 trees. push ( TokenTree :: Group ( Group {
181166 delimiter : pm:: Delimiter :: Bracket ,
@@ -190,6 +175,12 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)>
190175
191176 Interpolated ( nt) => {
192177 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).
193184 if crate :: base:: nt_pretty_printing_compatibility_hack ( & nt, rustc. sess ( ) ) {
194185 trees. extend ( Self :: from_internal ( ( stream, rustc) ) ) ;
195186 } else {
@@ -254,28 +245,28 @@ impl ToInternal<TokenStream> for TokenTree<TokenStream, Span, Ident, Literal> {
254245 } ;
255246
256247 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 ,
279270 _ => unreachable ! ( ) ,
280271 } ;
281272
0 commit comments