@@ -81,29 +81,23 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
8181 $( $field $( : $value) * , ) *
8282 span,
8383 } )
84- )
84+ ) ;
85+ ( $ty: ident:: $method: ident( $( $value: expr) ,* ) ) => (
86+ TokenTree :: $ty( self :: $ty:: $method( $( $value, ) * span) )
87+ ) ;
8588 }
8689 macro_rules! op {
8790 ( $a: expr) => {
88- tt!( Punct { ch : $a, joint } )
91+ tt!( Punct :: new ( $a, joint) )
8992 } ;
9093 ( $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 ) )
9696 } } ;
9797 ( $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 ) )
107101 } } ;
108102 }
109103
@@ -156,20 +150,11 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
156150 Question => op ! ( '?' ) ,
157151 SingleQuote => op ! ( '\'' ) ,
158152
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) ) ,
163154 Lifetime ( ident) => {
164155 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 ) )
173158 }
174159 Literal ( lit, suffix) => tt ! ( Literal { lit, suffix } ) ,
175160 DocComment ( c) => {
@@ -193,15 +178,9 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
193178 span : DelimSpan :: from_single ( span) ,
194179 } ) ) ;
195180 if style == ast:: AttrStyle :: Inner {
196- stack. push ( tt ! ( Punct {
197- ch: '!' ,
198- joint: false
199- } ) ) ;
181+ stack. push ( tt ! ( Punct :: new( '!' , false ) ) ) ;
200182 }
201- tt ! ( Punct {
202- ch: '#' ,
203- joint: false
204- } )
183+ tt ! ( Punct :: new( '#' , false ) )
205184 }
206185
207186 Interpolated ( _) => {
@@ -237,7 +216,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
237216 )
238217 . into ( ) ;
239218 }
240- TokenTree :: Ident ( self :: Ident { sym, span , is_raw } ) => {
219+ TokenTree :: Ident ( self :: Ident { sym, is_raw , span } ) => {
241220 let token = Ident ( ast:: Ident :: new ( sym, span) , is_raw) ;
242221 return tokenstream:: TokenTree :: Token ( span, token) . into ( ) ;
243222 }
@@ -338,11 +317,48 @@ pub struct Punct {
338317 span : Span ,
339318}
340319
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+
341331#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
342332pub struct Ident {
343333 sym : Symbol ,
344- span : Span ,
345334 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+ }
346362}
347363
348364// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
@@ -492,11 +508,7 @@ impl server::Group for Rustc<'_> {
492508
493509impl server:: Punct for Rustc < ' _ > {
494510 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 ) )
500512 }
501513 fn as_char ( & mut self , punct : Self :: Punct ) -> char {
502514 punct. ch
@@ -518,14 +530,7 @@ impl server::Punct for Rustc<'_> {
518530
519531impl server:: Ident for Rustc < ' _ > {
520532 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)
529534 }
530535 fn span ( & mut self , ident : Self :: Ident ) -> Self :: Span {
531536 ident. span
0 commit comments