@@ -14,7 +14,7 @@ pub use StabilityLevel::*;
14
14
use crate :: ast;
15
15
use crate :: ast:: { AttrId , Attribute , AttrStyle , Name , Ident , Path , PathSegment } ;
16
16
use crate :: ast:: { MetaItem , MetaItemKind , NestedMetaItem } ;
17
- use crate :: ast:: { Lit , LitKind , Expr , ExprKind , Item , Local , Stmt , StmtKind , GenericParam } ;
17
+ use crate :: ast:: { Lit , LitKind , Expr , Item , Local , Stmt , StmtKind , GenericParam } ;
18
18
use crate :: mut_visit:: visit_clobber;
19
19
use crate :: source_map:: { BytePos , Spanned , dummy_spanned} ;
20
20
use crate :: parse:: lexer:: comments:: { doc_comment_style, strip_doc_comment_decoration} ;
@@ -27,9 +27,11 @@ use crate::ThinVec;
27
27
use crate :: tokenstream:: { TokenStream , TokenTree , DelimSpan } ;
28
28
use crate :: GLOBALS ;
29
29
30
+ use errors:: Handler ;
30
31
use log:: debug;
31
32
use syntax_pos:: { FileName , Span } ;
32
33
34
+ use std:: ascii;
33
35
use std:: iter;
34
36
use std:: ops:: DerefMut ;
35
37
@@ -350,14 +352,13 @@ impl Attribute {
350
352
/* Constructors */
351
353
352
354
pub fn mk_name_value_item_str ( ident : Ident , value : Spanned < Symbol > ) -> MetaItem {
353
- let node = LitKind :: Str ( value. node , ast:: StrStyle :: Cooked ) ;
354
- let ( token, suffix) = node. lit_token ( ) ;
355
- let value = Lit { node, token, suffix, span : value. span } ;
356
- mk_name_value_item ( ident. span . to ( value. span ) , ident, value)
355
+ let lit_kind = LitKind :: Str ( value. node , ast:: StrStyle :: Cooked ) ;
356
+ mk_name_value_item ( ident. span . to ( value. span ) , ident, lit_kind, value. span )
357
357
}
358
358
359
- pub fn mk_name_value_item ( span : Span , ident : Ident , value : Lit ) -> MetaItem {
360
- MetaItem { path : Path :: from_ident ( ident) , span, node : MetaItemKind :: NameValue ( value) }
359
+ pub fn mk_name_value_item ( span : Span , ident : Ident , lit_kind : LitKind , lit_span : Span ) -> MetaItem {
360
+ let lit = Lit :: from_lit_kind ( lit_kind, lit_span) ;
361
+ MetaItem { path : Path :: from_ident ( ident) , span, node : MetaItemKind :: NameValue ( lit) }
361
362
}
362
363
363
364
pub fn mk_list_item ( span : Span , ident : Ident , items : Vec < NestedMetaItem > ) -> MetaItem {
@@ -419,9 +420,8 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
419
420
420
421
pub fn mk_sugared_doc_attr ( id : AttrId , text : Symbol , span : Span ) -> Attribute {
421
422
let style = doc_comment_style ( & text. as_str ( ) ) ;
422
- let node = LitKind :: Str ( text, ast:: StrStyle :: Cooked ) ;
423
- let ( token, suffix) = node. lit_token ( ) ;
424
- let lit = Lit { node, token, suffix, span } ;
423
+ let lit_kind = LitKind :: Str ( text, ast:: StrStyle :: Cooked ) ;
424
+ let lit = Lit :: from_lit_kind ( lit_kind, span) ;
425
425
Attribute {
426
426
id,
427
427
style,
@@ -565,9 +565,7 @@ impl MetaItemKind {
565
565
Some ( TokenTree :: Token ( _, token:: Eq ) ) => {
566
566
tokens. next ( ) ;
567
567
return if let Some ( TokenTree :: Token ( span, token) ) = tokens. next ( ) {
568
- LitKind :: from_token ( token) . map ( |( node, token, suffix) | {
569
- MetaItemKind :: NameValue ( Lit { node, token, suffix, span } )
570
- } )
568
+ Lit :: from_token ( & token, span, None ) . map ( MetaItemKind :: NameValue )
571
569
} else {
572
570
None
573
571
} ;
@@ -612,9 +610,9 @@ impl NestedMetaItem {
612
610
where I : Iterator < Item = TokenTree > ,
613
611
{
614
612
if let Some ( TokenTree :: Token ( span, token) ) = tokens. peek ( ) . cloned ( ) {
615
- if let Some ( ( node , token , suffix ) ) = LitKind :: from_token ( token) {
613
+ if let Some ( lit ) = Lit :: from_token ( & token, span , None ) {
616
614
tokens. next ( ) ;
617
- return Some ( NestedMetaItem :: Literal ( Lit { node , token , suffix , span } ) ) ;
615
+ return Some ( NestedMetaItem :: Literal ( lit ) ) ;
618
616
}
619
617
}
620
618
@@ -624,21 +622,19 @@ impl NestedMetaItem {
624
622
625
623
impl Lit {
626
624
crate fn tokens ( & self ) -> TokenStream {
627
- TokenTree :: Token ( self . span , self . node . token ( ) ) . into ( )
625
+ let token = match self . token {
626
+ token:: Bool ( symbol) => Token :: Ident ( Ident :: with_empty_ctxt ( symbol) , false ) ,
627
+ token => Token :: Literal ( token, self . suffix ) ,
628
+ } ;
629
+ TokenTree :: Token ( self . span , token) . into ( )
628
630
}
629
631
}
630
632
631
633
impl LitKind {
632
- fn token ( & self ) -> Token {
633
- match self . lit_token ( ) {
634
- ( token:: Bool ( symbol) , _) => Token :: Ident ( Ident :: with_empty_ctxt ( symbol) , false ) ,
635
- ( lit, suffix) => Token :: Literal ( lit, suffix) ,
636
- }
637
- }
638
-
639
- pub fn lit_token ( & self ) -> ( token:: Lit , Option < Symbol > ) {
640
- use std:: ascii;
641
-
634
+ /// Attempts to recover a token from semantic literal.
635
+ /// This function is used when the original token doesn't exist (e.g. the literal is created
636
+ /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
637
+ pub fn to_lit_token ( & self ) -> ( token:: Lit , Option < Symbol > ) {
642
638
match * self {
643
639
LitKind :: Str ( string, ast:: StrStyle :: Cooked ) => {
644
640
let escaped = string. as_str ( ) . escape_default ( ) . to_string ( ) ;
@@ -679,29 +675,45 @@ impl LitKind {
679
675
LitKind :: Err ( val) => ( token:: Lit :: Err ( val) , None ) ,
680
676
}
681
677
}
678
+ }
682
679
683
- fn from_token ( token : Token ) -> Option < ( LitKind , token:: Lit , Option < Symbol > ) > {
684
- match token {
685
- Token :: Ident ( ident, false ) if ident. name == keywords:: True . name ( ) =>
686
- Some ( ( LitKind :: Bool ( true ) , token:: Bool ( ident. name ) , None ) ) ,
687
- Token :: Ident ( ident, false ) if ident. name == keywords:: False . name ( ) =>
688
- Some ( ( LitKind :: Bool ( false ) , token:: Bool ( ident. name ) , None ) ) ,
689
- Token :: Interpolated ( nt) => match * nt {
690
- token:: NtExpr ( ref v) | token:: NtLiteral ( ref v) => match v. node {
691
- ExprKind :: Lit ( ref lit) => Some ( ( lit. node . clone ( ) , lit. token , lit. suffix ) ) ,
692
- _ => None ,
693
- } ,
694
- _ => None ,
695
- } ,
696
- Token :: Literal ( lit, suf) => {
697
- let ( suffix_illegal, result) = parse:: lit_token ( lit, suf, None ) ;
698
- if result. is_none ( ) || suffix_illegal && suf. is_some ( ) {
699
- return None ;
680
+ impl Lit {
681
+ /// Converts literal token with a suffix into an AST literal.
682
+ /// Works speculatively and may return `None` is diagnostic handler is not passed.
683
+ /// If diagnostic handler is passed, may return `Some`,
684
+ /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors.
685
+ crate fn from_token (
686
+ token : & token:: Token ,
687
+ span : Span ,
688
+ diag : Option < ( Span , & Handler ) > ,
689
+ ) -> Option < Lit > {
690
+ let ( token, suffix) = match * token {
691
+ token:: Ident ( ident, false ) if ident. name == keywords:: True . name ( ) ||
692
+ ident. name == keywords:: False . name ( ) =>
693
+ ( token:: Bool ( ident. name ) , None ) ,
694
+ token:: Literal ( token, suffix) =>
695
+ ( token, suffix) ,
696
+ token:: Interpolated ( ref nt) => {
697
+ if let token:: NtExpr ( expr) | token:: NtLiteral ( expr) = & * * nt {
698
+ if let ast:: ExprKind :: Lit ( lit) = & expr. node {
699
+ return Some ( lit. clone ( ) ) ;
700
+ }
700
701
}
701
- Some ( ( result . unwrap ( ) , lit , suf ) )
702
+ return None ;
702
703
}
703
- _ => None ,
704
- }
704
+ _ => return None ,
705
+ } ;
706
+
707
+ let node = LitKind :: from_lit_token ( token, suffix, diag) ?;
708
+ Some ( Lit { node, token, suffix, span } )
709
+ }
710
+
711
+ /// Attempts to recover an AST literal from semantic literal.
712
+ /// This function is used when the original token doesn't exist (e.g. the literal is created
713
+ /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
714
+ pub fn from_lit_kind ( node : LitKind , span : Span ) -> Lit {
715
+ let ( token, suffix) = node. to_lit_token ( ) ;
716
+ Lit { node, token, suffix, span }
705
717
}
706
718
}
707
719
0 commit comments