@@ -18,7 +18,7 @@ use ast;
1818use ast:: { AttrId , Attribute , Name , Ident } ;
1919use ast:: { MetaItem , MetaItemKind , NestedMetaItem , NestedMetaItemKind } ;
2020use ast:: { Lit , LitKind , Expr , ExprKind , Item , Local , Stmt , StmtKind } ;
21- use codemap:: { Spanned , respan, dummy_spanned} ;
21+ use codemap:: { BytePos , Spanned , respan, dummy_spanned} ;
2222use syntax_pos:: { Span , DUMMY_SP } ;
2323use errors:: Handler ;
2424use feature_gate:: { Features , GatedCfg } ;
@@ -205,6 +205,10 @@ impl NestedMetaItem {
205205 }
206206}
207207
208+ fn name_from_path ( path : & ast:: Path ) -> Name {
209+ path. segments . iter ( ) . next ( ) . unwrap ( ) . identifier . name
210+ }
211+
208212impl Attribute {
209213 pub fn check_name ( & self , name : & str ) -> bool {
210214 let matches = self . path == name;
@@ -252,7 +256,7 @@ impl Attribute {
252256
253257impl MetaItem {
254258 pub fn name ( & self ) -> Name {
255- self . name
259+ name_from_path ( & self . name )
256260 }
257261
258262 pub fn value_str ( & self ) -> Option < Symbol > {
@@ -301,10 +305,7 @@ impl Attribute {
301305 pub fn meta ( & self ) -> Option < MetaItem > {
302306 let mut tokens = self . tokens . trees ( ) . peekable ( ) ;
303307 Some ( MetaItem {
304- name : match self . path . segments . len ( ) {
305- 1 => self . path . segments [ 0 ] . identifier . name ,
306- _ => return None ,
307- } ,
308+ name : self . path . clone ( ) ,
308309 node : if let Some ( node) = MetaItemKind :: from_tokens ( & mut tokens) {
309310 if tokens. peek ( ) . is_some ( ) {
310311 return None ;
@@ -349,12 +350,8 @@ impl Attribute {
349350 }
350351
351352 pub fn parse_meta < ' a > ( & self , sess : & ' a ParseSess ) -> PResult < ' a , MetaItem > {
352- if self . path . segments . len ( ) > 1 {
353- sess. span_diagnostic . span_err ( self . path . span , "expected ident, found path" ) ;
354- }
355-
356353 Ok ( MetaItem {
357- name : self . path . segments . last ( ) . unwrap ( ) . identifier . name ,
354+ name : self . path . clone ( ) ,
358355 node : self . parse ( sess, |parser| parser. parse_meta_item_kind ( ) ) ?,
359356 span : self . span ,
360357 } )
@@ -407,16 +404,26 @@ pub fn mk_word_item(name: Name) -> MetaItem {
407404 mk_spanned_word_item ( DUMMY_SP , name)
408405}
409406
407+ macro_rules! mk_spanned_meta_item {
408+ ( $sp: ident, $name: ident, $node: expr) => {
409+ MetaItem {
410+ span: $sp,
411+ name: ast:: Path :: from_ident( $sp, ast:: Ident :: with_empty_ctxt( $name) ) ,
412+ node: $node,
413+ }
414+ }
415+ }
416+
410417pub fn mk_spanned_name_value_item ( sp : Span , name : Name , value : ast:: Lit ) -> MetaItem {
411- MetaItem { span : sp, name : name , node : MetaItemKind :: NameValue ( value) }
418+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: NameValue ( value) )
412419}
413420
414421pub fn mk_spanned_list_item ( sp : Span , name : Name , items : Vec < NestedMetaItem > ) -> MetaItem {
415- MetaItem { span : sp, name : name , node : MetaItemKind :: List ( items) }
422+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: List ( items) )
416423}
417424
418425pub fn mk_spanned_word_item ( sp : Span , name : Name ) -> MetaItem {
419- MetaItem { span : sp, name : name , node : MetaItemKind :: Word }
426+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: Word )
420427}
421428
422429pub fn mk_attr_id ( ) -> AttrId {
@@ -440,7 +447,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute
440447 Attribute {
441448 id,
442449 style : ast:: AttrStyle :: Inner ,
443- path : ast :: Path :: from_ident ( item. span , ast :: Ident :: with_empty_ctxt ( item . name ) ) ,
450+ path : item. name ,
444451 tokens : item. node . tokens ( item. span ) ,
445452 is_sugared_doc : false ,
446453 span : sp,
@@ -458,7 +465,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
458465 Attribute {
459466 id,
460467 style : ast:: AttrStyle :: Outer ,
461- path : ast :: Path :: from_ident ( item. span , ast :: Ident :: with_empty_ctxt ( item . name ) ) ,
468+ path : item. name ,
462469 tokens : item. node . tokens ( item. span ) ,
463470 is_sugared_doc : false ,
464471 span : sp,
@@ -600,7 +607,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
600607
601608 // The unwraps below may look dangerous, but we've already asserted
602609 // that they won't fail with the loop above.
603- match & * cfg. name . as_str ( ) {
610+ match & * cfg. name ( ) . as_str ( ) {
604611 "any" => mis. iter ( ) . any ( |mi| {
605612 eval_condition ( mi. meta_item ( ) . unwrap ( ) , sess, eval)
606613 } ) ,
@@ -731,7 +738,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
731738 }
732739 }
733740
734- match & * meta. name . as_str ( ) {
741+ match & * meta. name ( ) . as_str ( ) {
735742 "rustc_deprecated" => {
736743 if rustc_depr. is_some ( ) {
737744 span_err ! ( diagnostic, item_sp, E0540 ,
@@ -1106,18 +1113,52 @@ impl IntType {
11061113
11071114impl MetaItem {
11081115 fn tokens ( & self ) -> TokenStream {
1109- let ident = TokenTree :: Token ( self . span , Token :: Ident ( Ident :: with_empty_ctxt ( self . name ) ) ) ;
1110- TokenStream :: concat ( vec ! [ ident. into( ) , self . node. tokens( self . span) ] )
1116+ let mut idents = vec ! [ ] ;
1117+ let mut last_pos = BytePos ( 0 as u32 ) ;
1118+ for ( i, segment) in self . name . segments . iter ( ) . enumerate ( ) {
1119+ let is_first = i == 0 ;
1120+ if !is_first {
1121+ let mod_sep_span = Span :: new ( last_pos, segment. span . lo ( ) , segment. span . ctxt ( ) ) ;
1122+ idents. push ( TokenTree :: Token ( mod_sep_span, Token :: ModSep ) . into ( ) ) ;
1123+ }
1124+ idents. push ( TokenTree :: Token ( segment. span , Token :: Ident ( segment. identifier ) ) . into ( ) ) ;
1125+ last_pos = segment. span . hi ( ) ;
1126+ }
1127+ idents. push ( self . node . tokens ( self . span ) ) ;
1128+ TokenStream :: concat ( idents)
11111129 }
11121130
11131131 fn from_tokens < I > ( tokens : & mut iter:: Peekable < I > ) -> Option < MetaItem >
11141132 where I : Iterator < Item = TokenTree > ,
11151133 {
1116- let ( span, name) = match tokens. next ( ) {
1117- Some ( TokenTree :: Token ( span, Token :: Ident ( ident) ) ) => ( span, ident. name ) ,
1134+ let name = match tokens. next ( ) {
1135+ Some ( TokenTree :: Token ( span, Token :: Ident ( ident) ) ) => {
1136+ if let Some ( TokenTree :: Token ( _, Token :: ModSep ) ) = tokens. peek ( ) {
1137+ tokens. next ( ) ;
1138+ let mut segments = vec ! [ ] ;
1139+ loop {
1140+ if let Some ( TokenTree :: Token ( span, Token :: Ident ( ident) ) ) = tokens. next ( ) {
1141+ segments. push ( ast:: PathSegment :: from_ident ( ident, span) ) ;
1142+ } else {
1143+ return None ;
1144+ }
1145+ if let Some ( TokenTree :: Token ( _, Token :: ModSep ) ) = tokens. peek ( ) {
1146+ tokens. next ( ) ;
1147+ } else {
1148+ break ;
1149+ }
1150+ }
1151+ ast:: Path { span, segments }
1152+ } else {
1153+ ast:: Path :: from_ident ( span, ident)
1154+ }
1155+ }
11181156 Some ( TokenTree :: Token ( _, Token :: Interpolated ( ref nt) ) ) => match nt. 0 {
1119- token:: Nonterminal :: NtIdent ( ident) => ( ident. span , ident. node . name ) ,
1157+ token:: Nonterminal :: NtIdent ( ident) => {
1158+ ast:: Path :: from_ident ( ident. span , ident. node )
1159+ }
11201160 token:: Nonterminal :: NtMeta ( ref meta) => return Some ( meta. clone ( ) ) ,
1161+ token:: Nonterminal :: NtPath ( ref path) => path. clone ( ) ,
11211162 _ => return None ,
11221163 } ,
11231164 _ => return None ,
@@ -1126,10 +1167,11 @@ impl MetaItem {
11261167 let node = MetaItemKind :: from_tokens ( tokens) ?;
11271168 let hi = match node {
11281169 MetaItemKind :: NameValue ( ref lit) => lit. span . hi ( ) ,
1129- MetaItemKind :: List ( ..) => list_closing_paren_pos. unwrap_or ( span. hi ( ) ) ,
1130- _ => span. hi ( ) ,
1170+ MetaItemKind :: List ( ..) => list_closing_paren_pos. unwrap_or ( name . span . hi ( ) ) ,
1171+ _ => name . span . hi ( ) ,
11311172 } ;
1132- Some ( MetaItem { name, node, span : span. with_hi ( hi) } )
1173+ let span = name. span . with_hi ( hi) ;
1174+ Some ( MetaItem { name, node, span } )
11331175 }
11341176}
11351177
0 commit comments