@@ -81,29 +81,23 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
81
81
$( $field $( : $value) * , ) *
82
82
span,
83
83
} )
84
- )
84
+ ) ;
85
+ ( $ty: ident:: $method: ident( $( $value: expr) ,* ) ) => (
86
+ TokenTree :: $ty( self :: $ty:: $method( $( $value, ) * span) )
87
+ ) ;
85
88
}
86
89
macro_rules! op {
87
90
( $a: expr) => {
88
- tt!( Punct { ch : $a, joint } )
91
+ tt!( Punct :: new ( $a, joint) )
89
92
} ;
90
93
( $a: expr, $b: expr) => { {
91
- stack. push( tt!( Punct { ch: $b, joint } ) ) ;
92
- tt!( Punct {
93
- ch: $a,
94
- joint: true
95
- } )
94
+ stack. push( tt!( Punct :: new( $b, joint) ) ) ;
95
+ tt!( Punct :: new( $a, true ) )
96
96
} } ;
97
97
( $a: expr, $b: expr, $c: expr) => { {
98
- stack. push( tt!( Punct { ch: $c, joint } ) ) ;
99
- stack. push( tt!( Punct {
100
- ch: $b,
101
- joint: true
102
- } ) ) ;
103
- tt!( Punct {
104
- ch: $a,
105
- joint: true
106
- } )
98
+ stack. push( tt!( Punct :: new( $c, joint) ) ) ;
99
+ stack. push( tt!( Punct :: new( $b, true ) ) ) ;
100
+ tt!( Punct :: new( $a, true ) )
107
101
} } ;
108
102
}
109
103
@@ -156,20 +150,11 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
156
150
Question => op ! ( '?' ) ,
157
151
SingleQuote => op ! ( '\'' ) ,
158
152
159
- Ident ( ident, is_raw) => tt ! ( Ident {
160
- sym: ident. name,
161
- is_raw
162
- } ) ,
153
+ Ident ( ident, is_raw) => tt ! ( Ident :: new( ident. name, is_raw) ) ,
163
154
Lifetime ( ident) => {
164
155
let ident = ident. without_first_quote ( ) ;
165
- stack. push ( tt ! ( Ident {
166
- sym: ident. name,
167
- is_raw: false
168
- } ) ) ;
169
- tt ! ( Punct {
170
- ch: '\'' ,
171
- joint: true
172
- } )
156
+ stack. push ( tt ! ( Ident :: new( ident. name, false ) ) ) ;
157
+ tt ! ( Punct :: new( '\'' , true ) )
173
158
}
174
159
Literal ( lit, suffix) => tt ! ( Literal { lit, suffix } ) ,
175
160
DocComment ( c) => {
@@ -193,15 +178,9 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
193
178
span : DelimSpan :: from_single ( span) ,
194
179
} ) ) ;
195
180
if style == ast:: AttrStyle :: Inner {
196
- stack. push ( tt ! ( Punct {
197
- ch: '!' ,
198
- joint: false
199
- } ) ) ;
181
+ stack. push ( tt ! ( Punct :: new( '!' , false ) ) ) ;
200
182
}
201
- tt ! ( Punct {
202
- ch: '#' ,
203
- joint: false
204
- } )
183
+ tt ! ( Punct :: new( '#' , false ) )
205
184
}
206
185
207
186
Interpolated ( _) => {
@@ -237,7 +216,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
237
216
)
238
217
. into ( ) ;
239
218
}
240
- TokenTree :: Ident ( self :: Ident { sym, span , is_raw } ) => {
219
+ TokenTree :: Ident ( self :: Ident { sym, is_raw , span } ) => {
241
220
let token = Ident ( ast:: Ident :: new ( sym, span) , is_raw) ;
242
221
return tokenstream:: TokenTree :: Token ( span, token) . into ( ) ;
243
222
}
@@ -338,11 +317,48 @@ pub struct Punct {
338
317
span : Span ,
339
318
}
340
319
320
+ impl Punct {
321
+ fn new ( ch : char , joint : bool , span : Span ) -> Punct {
322
+ const LEGAL_CHARS : & [ char ] = & [ '=' , '<' , '>' , '!' , '~' , '+' , '-' , '*' , '/' , '%' , '^' ,
323
+ '&' , '|' , '@' , '.' , ',' , ';' , ':' , '#' , '$' , '?' , '\'' ] ;
324
+ if !LEGAL_CHARS . contains ( & ch) {
325
+ panic ! ( "unsupported character `{:?}`" , ch)
326
+ }
327
+ Punct { ch, joint, span }
328
+ }
329
+ }
330
+
341
331
#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
342
332
pub struct Ident {
343
333
sym : Symbol ,
344
- span : Span ,
345
334
is_raw : bool ,
335
+ span : Span ,
336
+ }
337
+
338
+ impl Ident {
339
+ fn is_valid ( string : & str ) -> bool {
340
+ let mut chars = string. chars ( ) ;
341
+ if let Some ( start) = chars. next ( ) {
342
+ ( start == '_' || start. is_xid_start ( ) )
343
+ && chars. all ( |cont| cont == '_' || cont. is_xid_continue ( ) )
344
+ } else {
345
+ false
346
+ }
347
+ }
348
+ fn new ( sym : Symbol , is_raw : bool , span : Span ) -> Ident {
349
+ let string = sym. as_str ( ) . get ( ) ;
350
+ if !Self :: is_valid ( string) {
351
+ panic ! ( "`{:?}` is not a valid identifier" , string)
352
+ }
353
+ if is_raw {
354
+ let normalized_sym = Symbol :: intern ( string) ;
355
+ if normalized_sym == keywords:: Underscore . name ( ) ||
356
+ ast:: Ident :: with_empty_ctxt ( normalized_sym) . is_path_segment_keyword ( ) {
357
+ panic ! ( "`{:?}` is not a valid raw identifier" , string)
358
+ }
359
+ }
360
+ Ident { sym, is_raw, span }
361
+ }
346
362
}
347
363
348
364
// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
@@ -492,11 +508,7 @@ impl server::Group for Rustc<'_> {
492
508
493
509
impl server:: Punct for Rustc < ' _ > {
494
510
fn new ( & mut self , ch : char , spacing : Spacing ) -> Self :: Punct {
495
- Punct {
496
- ch,
497
- joint : spacing == Spacing :: Joint ,
498
- span : server:: Span :: call_site ( self ) ,
499
- }
511
+ Punct :: new ( ch, spacing == Spacing :: Joint , server:: Span :: call_site ( self ) )
500
512
}
501
513
fn as_char ( & mut self , punct : Self :: Punct ) -> char {
502
514
punct. ch
@@ -518,14 +530,7 @@ impl server::Punct for Rustc<'_> {
518
530
519
531
impl server:: Ident for Rustc < ' _ > {
520
532
fn new ( & mut self , string : & str , span : Self :: Span , is_raw : bool ) -> Self :: Ident {
521
- let sym = Symbol :: intern ( string) ;
522
- if is_raw
523
- && ( sym == keywords:: Underscore . name ( )
524
- || ast:: Ident :: with_empty_ctxt ( sym) . is_path_segment_keyword ( ) )
525
- {
526
- panic ! ( "`{:?}` is not a valid raw identifier" , string)
527
- }
528
- Ident { sym, span, is_raw }
533
+ Ident :: new ( Symbol :: intern ( string) , is_raw, span)
529
534
}
530
535
fn span ( & mut self , ident : Self :: Ident ) -> Self :: Span {
531
536
ident. span
0 commit comments