@@ -18,7 +18,7 @@ use ast;
18
18
use ast:: { AttrId , Attribute , Name , Ident } ;
19
19
use ast:: { MetaItem , MetaItemKind , NestedMetaItem , NestedMetaItemKind } ;
20
20
use ast:: { Lit , LitKind , Expr , ExprKind , Item , Local , Stmt , StmtKind } ;
21
- use codemap:: { Spanned , respan, dummy_spanned} ;
21
+ use codemap:: { BytePos , Spanned , respan, dummy_spanned} ;
22
22
use syntax_pos:: { Span , DUMMY_SP } ;
23
23
use errors:: Handler ;
24
24
use feature_gate:: { Features , GatedCfg } ;
@@ -205,6 +205,10 @@ impl NestedMetaItem {
205
205
}
206
206
}
207
207
208
+ fn name_from_path ( path : & ast:: Path ) -> Name {
209
+ path. segments . iter ( ) . next ( ) . unwrap ( ) . identifier . name
210
+ }
211
+
208
212
impl Attribute {
209
213
pub fn check_name ( & self , name : & str ) -> bool {
210
214
let matches = self . path == name;
@@ -252,7 +256,7 @@ impl Attribute {
252
256
253
257
impl MetaItem {
254
258
pub fn name ( & self ) -> Name {
255
- self . name
259
+ name_from_path ( & self . name )
256
260
}
257
261
258
262
pub fn value_str ( & self ) -> Option < Symbol > {
@@ -301,10 +305,7 @@ impl Attribute {
301
305
pub fn meta ( & self ) -> Option < MetaItem > {
302
306
let mut tokens = self . tokens . trees ( ) . peekable ( ) ;
303
307
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 ( ) ,
308
309
node : if let Some ( node) = MetaItemKind :: from_tokens ( & mut tokens) {
309
310
if tokens. peek ( ) . is_some ( ) {
310
311
return None ;
@@ -349,12 +350,8 @@ impl Attribute {
349
350
}
350
351
351
352
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
-
356
353
Ok ( MetaItem {
357
- name : self . path . segments . last ( ) . unwrap ( ) . identifier . name ,
354
+ name : self . path . clone ( ) ,
358
355
node : self . parse ( sess, |parser| parser. parse_meta_item_kind ( ) ) ?,
359
356
span : self . span ,
360
357
} )
@@ -407,16 +404,26 @@ pub fn mk_word_item(name: Name) -> MetaItem {
407
404
mk_spanned_word_item ( DUMMY_SP , name)
408
405
}
409
406
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
+
410
417
pub 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) )
412
419
}
413
420
414
421
pub 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) )
416
423
}
417
424
418
425
pub 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 )
420
427
}
421
428
422
429
pub fn mk_attr_id ( ) -> AttrId {
@@ -440,7 +447,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute
440
447
Attribute {
441
448
id,
442
449
style : ast:: AttrStyle :: Inner ,
443
- path : ast :: Path :: from_ident ( item. span , ast :: Ident :: with_empty_ctxt ( item . name ) ) ,
450
+ path : item. name ,
444
451
tokens : item. node . tokens ( item. span ) ,
445
452
is_sugared_doc : false ,
446
453
span : sp,
@@ -458,7 +465,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
458
465
Attribute {
459
466
id,
460
467
style : ast:: AttrStyle :: Outer ,
461
- path : ast :: Path :: from_ident ( item. span , ast :: Ident :: with_empty_ctxt ( item . name ) ) ,
468
+ path : item. name ,
462
469
tokens : item. node . tokens ( item. span ) ,
463
470
is_sugared_doc : false ,
464
471
span : sp,
@@ -600,7 +607,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
600
607
601
608
// The unwraps below may look dangerous, but we've already asserted
602
609
// that they won't fail with the loop above.
603
- match & * cfg. name . as_str ( ) {
610
+ match & * cfg. name ( ) . as_str ( ) {
604
611
"any" => mis. iter ( ) . any ( |mi| {
605
612
eval_condition ( mi. meta_item ( ) . unwrap ( ) , sess, eval)
606
613
} ) ,
@@ -731,7 +738,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
731
738
}
732
739
}
733
740
734
- match & * meta. name . as_str ( ) {
741
+ match & * meta. name ( ) . as_str ( ) {
735
742
"rustc_deprecated" => {
736
743
if rustc_depr. is_some ( ) {
737
744
span_err ! ( diagnostic, item_sp, E0540 ,
@@ -1106,18 +1113,52 @@ impl IntType {
1106
1113
1107
1114
impl MetaItem {
1108
1115
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)
1111
1129
}
1112
1130
1113
1131
fn from_tokens < I > ( tokens : & mut iter:: Peekable < I > ) -> Option < MetaItem >
1114
1132
where I : Iterator < Item = TokenTree > ,
1115
1133
{
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
+ }
1118
1156
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
+ }
1120
1160
token:: Nonterminal :: NtMeta ( ref meta) => return Some ( meta. clone ( ) ) ,
1161
+ token:: Nonterminal :: NtPath ( ref path) => path. clone ( ) ,
1121
1162
_ => return None ,
1122
1163
} ,
1123
1164
_ => return None ,
@@ -1126,10 +1167,11 @@ impl MetaItem {
1126
1167
let node = MetaItemKind :: from_tokens ( tokens) ?;
1127
1168
let hi = match node {
1128
1169
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 ( ) ,
1131
1172
} ;
1132
- Some ( MetaItem { name, node, span : span. with_hi ( hi) } )
1173
+ let span = name. span . with_hi ( hi) ;
1174
+ Some ( MetaItem { name, node, span } )
1133
1175
}
1134
1176
}
1135
1177
0 commit comments