@@ -120,6 +120,13 @@ macro_rules! quote { () => {} }
120120#[ doc( hidden) ]
121121mod quote;
122122
123+ /// Quote a `TokenStream` into a `TokenStream`.
124+ /// This is needed to implement a custom quoter.
125+ #[ unstable( feature = "proc_macro" , issue = "38356" ) ]
126+ pub fn quote_token_stream ( stream : TokenStream ) -> TokenStream {
127+ quote:: Quote :: quote ( stream)
128+ }
129+
123130#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
124131impl From < TokenTree > for TokenStream {
125132 fn from ( tree : TokenTree ) -> TokenStream {
@@ -512,6 +519,70 @@ impl Literal {
512519 }
513520}
514521
522+ macro_rules! literals {
523+ ( $( $i: ident) ,* ; $( $raw: ident) ,* ) => {
524+ #[ unstable( feature = "proc_macro_internals" , issue = "27812" ) ]
525+ #[ doc( hidden) ]
526+ pub enum LiteralKind {
527+ $( $i, ) *
528+ $( $raw( usize ) , ) *
529+ }
530+
531+ impl LiteralKind {
532+ #[ unstable( feature = "proc_macro_internals" , issue = "27812" ) ]
533+ #[ doc( hidden) ]
534+ pub fn with_contents_and_suffix( self , contents: Term , suffix: Option <Term >)
535+ -> Literal {
536+ let contents = contents. 0 ;
537+ let suffix = suffix. map( |t| t. 0 ) ;
538+ match self {
539+ $( LiteralKind :: $i => {
540+ Literal ( token:: Literal ( token:: Lit :: $i( contents) , suffix) )
541+ } ) *
542+ $( LiteralKind :: $raw( n) => {
543+ Literal ( token:: Literal ( token:: Lit :: $raw( contents, n) , suffix) )
544+ } ) *
545+ }
546+ }
547+ }
548+
549+ impl Literal {
550+ fn kind( & self ) -> LiteralKind {
551+ let lit = match self . 0 {
552+ token:: Literal ( lit, _) => lit,
553+ _ => panic!( "unsupported literal {:?}" , self . 0 ) ,
554+ } ;
555+
556+ match lit {
557+ $( token:: Lit :: $i( _) => LiteralKind :: $i, ) *
558+ $( token:: Lit :: $raw( _, n) => LiteralKind :: $raw( n) , ) *
559+ }
560+ }
561+
562+ fn contents( & self ) -> Term {
563+ let lit = match self . 0 {
564+ token:: Literal ( lit, _) => lit,
565+ _ => panic!( "unsupported literal {:?}" , self . 0 ) ,
566+ } ;
567+
568+ match lit {
569+ $( token:: Lit :: $i( contents) ) |* |
570+ $( token:: Lit :: $raw( contents, _) ) |* => Term ( contents)
571+ }
572+ }
573+
574+ fn suffix( & self ) -> Option <Term > {
575+ match self . 0 {
576+ token:: Literal ( _, suffix) => suffix. map( Term ) ,
577+ _ => panic!( "unsupported literal {:?}" , self . 0 ) ,
578+ }
579+ }
580+ }
581+ }
582+ }
583+
584+ literals ! ( Byte , Char , Float , Str_ , Integer , ByteStr ; StrRaw , ByteStrRaw ) ;
585+
515586/// An iterator over `TokenTree`s.
516587#[ derive( Clone ) ]
517588#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
@@ -543,78 +614,3 @@ impl Iterator for TokenTreeIter {
543614 } )
544615 }
545616}
546-
547- /// Permanently unstable internal implementation details of this crate. This
548- /// should not be used.
549- ///
550- /// These methods are used by the rest of the compiler to generate instances of
551- /// `TokenStream` to hand to macro definitions, as well as consume the output.
552- ///
553- /// Note that this module is also intentionally separate from the rest of the
554- /// crate. This allows the `#[unstable]` directive below to naturally apply to
555- /// all of the contents.
556- #[ unstable( feature = "proc_macro_internals" , issue = "27812" ) ]
557- #[ doc( hidden) ]
558- pub mod __internal {
559- pub use bridge:: { Expand1 , Expand2 , Registry } ;
560- pub use quote:: { LiteralKind , unquote} ;
561-
562- use std:: cell:: Cell ;
563-
564- use syntax:: errors:: DiagnosticBuilder ;
565- use syntax:: ext:: base:: ExtCtxt ;
566- use syntax:: ext:: hygiene:: Mark ;
567- use syntax:: parse:: ParseSess ;
568- use syntax_pos:: { BytePos , Loc } ;
569-
570- use super :: LexError ;
571-
572- pub fn lookup_char_pos ( pos : BytePos ) -> Loc {
573- with_sess ( |( sess, _) | sess. codemap ( ) . lookup_char_pos ( pos) )
574- }
575-
576- pub fn parse_to_lex_err ( mut err : DiagnosticBuilder ) -> LexError {
577- err. cancel ( ) ;
578- LexError { _inner : ( ) }
579- }
580-
581- // Emulate scoped_thread_local!() here essentially
582- thread_local ! {
583- static CURRENT_SESS : Cell <( * const ParseSess , Mark ) > =
584- Cell :: new( ( 0 as * const _, Mark :: root( ) ) ) ;
585- }
586-
587- pub fn set_sess < F , R > ( cx : & ExtCtxt , f : F ) -> R
588- where F : FnOnce ( ) -> R
589- {
590- struct Reset { prev : ( * const ParseSess , Mark ) }
591-
592- impl Drop for Reset {
593- fn drop ( & mut self ) {
594- CURRENT_SESS . with ( |p| p. set ( self . prev ) ) ;
595- }
596- }
597-
598- CURRENT_SESS . with ( |p| {
599- let _reset = Reset { prev : p. get ( ) } ;
600- p. set ( ( cx. parse_sess , cx. current_expansion . mark ) ) ;
601-
602- f ( )
603- } )
604- }
605-
606- pub fn in_sess ( ) -> bool
607- {
608- let p = CURRENT_SESS . with ( |p| p. get ( ) ) ;
609- !p. 0 . is_null ( )
610- }
611-
612- pub fn with_sess < F , R > ( f : F ) -> R
613- where F : FnOnce ( ( & ParseSess , Mark ) ) -> R
614- {
615- let p = CURRENT_SESS . with ( |p| p. get ( ) ) ;
616- assert ! ( !p. 0 . is_null( ) , "proc_macro::__internal::with_sess() called \
617- before set_parse_sess()!") ;
618- f ( unsafe { ( & * p. 0 , p. 1 ) } )
619- }
620- }
0 commit comments