@@ -137,7 +137,7 @@ impl NestedMetaItem {
137137 /// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
138138 /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
139139 pub fn name ( & self ) -> Option < Name > {
140- self . meta_item ( ) . and_then ( |meta_item| Some ( meta_item. ident . name ) )
140+ self . meta_item ( ) . and_then ( |meta_item| Some ( meta_item. name ( ) ) )
141141 }
142142
143143 /// Gets the string value if self is a MetaItem and the MetaItem is a
@@ -154,7 +154,7 @@ impl NestedMetaItem {
154154 if meta_item_list. len ( ) == 1 {
155155 let nested_item = & meta_item_list[ 0 ] ;
156156 if nested_item. is_literal ( ) {
157- Some ( ( meta_item. ident . name , nested_item. literal ( ) . unwrap ( ) ) )
157+ Some ( ( meta_item. name ( ) , nested_item. literal ( ) . unwrap ( ) ) )
158158 } else {
159159 None
160160 }
@@ -204,6 +204,10 @@ impl NestedMetaItem {
204204 }
205205}
206206
207+ fn name_from_path ( path : & ast:: Path ) -> Name {
208+ path. segments . iter ( ) . next ( ) . unwrap ( ) . identifier . name
209+ }
210+
207211impl Attribute {
208212 pub fn check_name ( & self , name : & str ) -> bool {
209213 let matches = self . path == name;
@@ -215,7 +219,7 @@ impl Attribute {
215219
216220 pub fn name ( & self ) -> Option < Name > {
217221 match self . path . segments . len ( ) {
218- 1 => Some ( self . path . segments [ 0 ] . ident . name ) ,
222+ 1 => Some ( self . path . segments [ 0 ] . identifier . name ) ,
219223 _ => None ,
220224 }
221225 }
@@ -250,6 +254,10 @@ impl Attribute {
250254}
251255
252256impl MetaItem {
257+ pub fn name ( & self ) -> Name {
258+ name_from_path ( & self . name )
259+ }
260+
253261 pub fn value_str ( & self ) -> Option < Symbol > {
254262 match self . node {
255263 MetaItemKind :: NameValue ( ref v) => {
@@ -279,7 +287,7 @@ impl MetaItem {
279287 pub fn span ( & self ) -> Span { self . span }
280288
281289 pub fn check_name ( & self , name : & str ) -> bool {
282- self . ident . name == name
290+ self . name ( ) == name
283291 }
284292
285293 pub fn is_value_str ( & self ) -> bool {
@@ -296,10 +304,7 @@ impl Attribute {
296304 pub fn meta ( & self ) -> Option < MetaItem > {
297305 let mut tokens = self . tokens . trees ( ) . peekable ( ) ;
298306 Some ( MetaItem {
299- ident : match self . path . segments . len ( ) {
300- 1 => self . path . segments [ 0 ] . ident ,
301- _ => return None ,
302- } ,
307+ name : self . path . clone ( ) ,
303308 node : if let Some ( node) = MetaItemKind :: from_tokens ( & mut tokens) {
304309 if tokens. peek ( ) . is_some ( ) {
305310 return None ;
@@ -344,12 +349,8 @@ impl Attribute {
344349 }
345350
346351 pub fn parse_meta < ' a > ( & self , sess : & ' a ParseSess ) -> PResult < ' a , MetaItem > {
347- if self . path . segments . len ( ) > 1 {
348- sess. span_diagnostic . span_err ( self . path . span , "expected ident, found path" ) ;
349- }
350-
351352 Ok ( MetaItem {
352- ident : self . path . segments . last ( ) . unwrap ( ) . ident ,
353+ name : self . path . clone ( ) ,
353354 node : self . parse ( sess, |parser| parser. parse_meta_item_kind ( ) ) ?,
354355 span : self . span ,
355356 } )
@@ -397,8 +398,31 @@ pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> Met
397398pub fn mk_word_item ( ident : Ident ) -> MetaItem {
398399 MetaItem { ident, span : ident. span , node : MetaItemKind :: Word }
399400}
400- pub fn mk_nested_word_item ( ident : Ident ) -> NestedMetaItem {
401- respan ( ident. span , NestedMetaItemKind :: MetaItem ( mk_word_item ( ident) ) )
401+
402+ pub fn mk_word_item ( name : Name ) -> MetaItem {
403+ mk_spanned_word_item ( DUMMY_SP , name)
404+ }
405+
406+ macro_rules! mk_spanned_meta_item {
407+ ( $sp: ident, $name: ident, $node: expr) => {
408+ MetaItem {
409+ span: $sp,
410+ name: ast:: Path :: from_ident( $sp, ast:: Ident :: with_empty_ctxt( $name) ) ,
411+ node: $node,
412+ }
413+ }
414+ }
415+
416+ pub fn mk_spanned_name_value_item ( sp : Span , name : Name , value : ast:: Lit ) -> MetaItem {
417+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: NameValue ( value) )
418+ }
419+
420+ pub fn mk_spanned_list_item ( sp : Span , name : Name , items : Vec < NestedMetaItem > ) -> MetaItem {
421+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: List ( items) )
422+ }
423+
424+ pub fn mk_spanned_word_item ( sp : Span , name : Name ) -> MetaItem {
425+ mk_spanned_meta_item ! ( sp, name, MetaItemKind :: Word )
402426}
403427
404428pub fn mk_attr_id ( ) -> AttrId {
@@ -422,7 +446,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute
422446 Attribute {
423447 id,
424448 style : ast:: AttrStyle :: Inner ,
425- path : ast :: Path :: from_ident ( item. ident ) ,
449+ path : item. name ,
426450 tokens : item. node . tokens ( item. span ) ,
427451 is_sugared_doc : false ,
428452 span : sp,
@@ -440,7 +464,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
440464 Attribute {
441465 id,
442466 style : ast:: AttrStyle :: Outer ,
443- path : ast :: Path :: from_ident ( item. ident ) ,
467+ path : item. name ,
444468 tokens : item. node . tokens ( item. span ) ,
445469 is_sugared_doc : false ,
446470 span : sp,
@@ -489,7 +513,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
489513 item. check_name ( "feature" ) &&
490514 item. meta_item_list ( ) . map ( |list| {
491515 list. iter ( ) . any ( |mi| {
492- mi. word ( ) . map ( |w| w. ident . name == feature_name)
516+ mi. word ( ) . map ( |w| w. name ( ) == feature_name)
493517 . unwrap_or ( false )
494518 } )
495519 } ) . unwrap_or ( false )
@@ -562,7 +586,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
562586 if let ( Some ( feats) , Some ( gated_cfg) ) = ( features, GatedCfg :: gate ( cfg) ) {
563587 gated_cfg. check_and_emit ( sess, feats) ;
564588 }
565- sess. config . contains ( & ( cfg. ident . name , cfg. value_str ( ) ) )
589+ sess. config . contains ( & ( cfg. name ( ) , cfg. value_str ( ) ) )
566590 } )
567591}
568592
@@ -583,7 +607,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
583607
584608 // The unwraps below may look dangerous, but we've already asserted
585609 // that they won't fail with the loop above.
586- match & * cfg. ident . name . as_str ( ) {
610+ match & * cfg. name ( ) . as_str ( ) {
587611 "any" => mis. iter ( ) . any ( |mi| {
588612 eval_condition ( mi. meta_item ( ) . unwrap ( ) , sess, eval)
589613 } ) ,
@@ -676,7 +700,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
676700 let meta = meta. as_ref ( ) . unwrap ( ) ;
677701 let get = |meta : & MetaItem , item : & mut Option < Symbol > | {
678702 if item. is_some ( ) {
679- handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. ident . name ) ) ;
703+ handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) ) ;
680704 return false
681705 }
682706 if let Some ( v) = meta. value_str ( ) {
@@ -695,14 +719,14 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
695719 ) +
696720 for meta in metas {
697721 if let Some ( mi) = meta. meta_item( ) {
698- match & * mi. ident . name. as_str( ) {
722+ match & * mi. name( ) . as_str( ) {
699723 $(
700724 stringify!( $name)
701725 => if !get( mi, & mut $name) { continue ' outer } ,
702726 ) +
703727 _ => {
704728 handle_errors( diagnostic, mi. span,
705- AttrError :: UnknownMetaItem ( mi. ident . name) ) ;
729+ AttrError :: UnknownMetaItem ( mi. name( ) ) ) ;
706730 continue ' outer
707731 }
708732 }
@@ -714,7 +738,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
714738 }
715739 }
716740
717- match & * meta. ident . name . as_str ( ) {
741+ match & * meta. name ( ) . as_str ( ) {
718742 "rustc_deprecated" => {
719743 if rustc_depr. is_some ( ) {
720744 span_err ! ( diagnostic, item_sp, E0540 ,
@@ -769,13 +793,13 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
769793 let mut issue = None ;
770794 for meta in metas {
771795 if let Some ( mi) = meta. meta_item ( ) {
772- match & * mi. ident . name . as_str ( ) {
796+ match & * mi. name ( ) . as_str ( ) {
773797 "feature" => if !get ( mi, & mut feature) { continue ' outer } ,
774798 "reason" => if !get ( mi, & mut reason) { continue ' outer } ,
775799 "issue" => if !get ( mi, & mut issue) { continue ' outer } ,
776800 _ => {
777801 handle_errors ( diagnostic, meta. span ,
778- AttrError :: UnknownMetaItem ( mi. ident . name ) ) ;
802+ AttrError :: UnknownMetaItem ( mi. name ( ) ) ) ;
779803 continue ' outer
780804 }
781805 }
@@ -825,12 +849,12 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
825849 let mut since = None ;
826850 for meta in metas {
827851 if let NestedMetaItemKind :: MetaItem ( ref mi) = meta. node {
828- match & * mi. ident . name . as_str ( ) {
852+ match & * mi. name ( ) . as_str ( ) {
829853 "feature" => if !get ( mi, & mut feature) { continue ' outer } ,
830854 "since" => if !get ( mi, & mut since) { continue ' outer } ,
831855 _ => {
832856 handle_errors ( diagnostic, meta. span ,
833- AttrError :: UnknownMetaItem ( mi. ident . name ) ) ;
857+ AttrError :: UnknownMetaItem ( mi. name ( ) ) ) ;
834858 continue ' outer
835859 }
836860 }
@@ -917,7 +941,7 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
917941 depr = if let Some ( metas) = attr. meta_item_list ( ) {
918942 let get = |meta : & MetaItem , item : & mut Option < Symbol > | {
919943 if item. is_some ( ) {
920- handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. ident . name ) ) ;
944+ handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) ) ;
921945 return false
922946 }
923947 if let Some ( v) = meta. value_str ( ) {
@@ -933,12 +957,12 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
933957 let mut note = None ;
934958 for meta in metas {
935959 if let NestedMetaItemKind :: MetaItem ( ref mi) = meta. node {
936- match & * mi. ident . name . as_str ( ) {
960+ match & * mi. name ( ) . as_str ( ) {
937961 "since" => if !get ( mi, & mut since) { continue ' outer } ,
938962 "note" => if !get ( mi, & mut note) { continue ' outer } ,
939963 _ => {
940964 handle_errors ( diagnostic, meta. span ,
941- AttrError :: UnknownMetaItem ( mi. ident . name ) ) ;
965+ AttrError :: UnknownMetaItem ( mi. name ( ) ) ) ;
942966 continue ' outer
943967 }
944968 }
@@ -990,7 +1014,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
9901014
9911015 let mut recognised = false ;
9921016 if let Some ( mi) = item. word ( ) {
993- let word = & * mi. ident . name . as_str ( ) ;
1017+ let word = & * mi. name ( ) . as_str ( ) ;
9941018 let hint = match word {
9951019 "C" => Some ( ReprC ) ,
9961020 "packed" => Some ( ReprPacked ( 1 ) ) ,
@@ -1127,18 +1151,52 @@ impl IntType {
11271151
11281152impl MetaItem {
11291153 fn tokens ( & self ) -> TokenStream {
1130- let ident = TokenTree :: Token ( self . span , Token :: from_ast_ident ( self . ident ) ) ;
1131- TokenStream :: concat ( vec ! [ ident. into( ) , self . node. tokens( self . span) ] )
1154+ let mut idents = vec ! [ ] ;
1155+ let mut last_pos = BytePos ( 0 as u32 ) ;
1156+ for ( i, segment) in self . name . segments . iter ( ) . enumerate ( ) {
1157+ let is_first = i == 0 ;
1158+ if !is_first {
1159+ let mod_sep_span = Span :: new ( last_pos, segment. span . lo ( ) , segment. span . ctxt ( ) ) ;
1160+ idents. push ( TokenTree :: Token ( mod_sep_span, Token :: ModSep ) . into ( ) ) ;
1161+ }
1162+ idents. push ( TokenTree :: Token ( segment. span , Token :: Ident ( segment. identifier ) ) . into ( ) ) ;
1163+ last_pos = segment. span . hi ( ) ;
1164+ }
1165+ idents. push ( self . node . tokens ( self . span ) ) ;
1166+ TokenStream :: concat ( idents)
11321167 }
11331168
11341169 fn from_tokens < I > ( tokens : & mut iter:: Peekable < I > ) -> Option < MetaItem >
11351170 where I : Iterator < Item = TokenTree > ,
11361171 {
1137- let ( span, ident) = match tokens. next ( ) {
1138- Some ( TokenTree :: Token ( span, Token :: Ident ( ident, _) ) ) => ( span, ident) ,
1172+ let name = match tokens. next ( ) {
1173+ Some ( TokenTree :: Token ( span, Token :: Ident ( ident) ) ) => {
1174+ if let Some ( TokenTree :: Token ( _, Token :: ModSep ) ) = tokens. peek ( ) {
1175+ tokens. next ( ) ;
1176+ let mut segments = vec ! [ ] ;
1177+ loop {
1178+ if let Some ( TokenTree :: Token ( span, Token :: Ident ( ident) ) ) = tokens. next ( ) {
1179+ segments. push ( ast:: PathSegment :: from_ident ( ident, span) ) ;
1180+ } else {
1181+ return None ;
1182+ }
1183+ if let Some ( TokenTree :: Token ( _, Token :: ModSep ) ) = tokens. peek ( ) {
1184+ tokens. next ( ) ;
1185+ } else {
1186+ break ;
1187+ }
1188+ }
1189+ ast:: Path { span, segments }
1190+ } else {
1191+ ast:: Path :: from_ident ( span, ident)
1192+ }
1193+ }
11391194 Some ( TokenTree :: Token ( _, Token :: Interpolated ( ref nt) ) ) => match nt. 0 {
1140- token:: Nonterminal :: NtIdent ( ident, _) => ( ident. span , ident) ,
1195+ token:: Nonterminal :: NtIdent ( ident) => {
1196+ ast:: Path :: from_ident ( ident. span , ident. node )
1197+ }
11411198 token:: Nonterminal :: NtMeta ( ref meta) => return Some ( meta. clone ( ) ) ,
1199+ token:: Nonterminal :: NtPath ( ref path) => path. clone ( ) ,
11421200 _ => return None ,
11431201 } ,
11441202 _ => return None ,
@@ -1147,10 +1205,11 @@ impl MetaItem {
11471205 let node = MetaItemKind :: from_tokens ( tokens) ?;
11481206 let hi = match node {
11491207 MetaItemKind :: NameValue ( ref lit) => lit. span . hi ( ) ,
1150- MetaItemKind :: List ( ..) => list_closing_paren_pos. unwrap_or ( span. hi ( ) ) ,
1151- _ => span. hi ( ) ,
1208+ MetaItemKind :: List ( ..) => list_closing_paren_pos. unwrap_or ( name . span . hi ( ) ) ,
1209+ _ => name . span . hi ( ) ,
11521210 } ;
1153- Some ( MetaItem { ident, node, span : span. with_hi ( hi) } )
1211+ let span = name. span . with_hi ( hi) ;
1212+ Some ( MetaItem { name, node, span } )
11541213 }
11551214}
11561215
0 commit comments