Skip to content

Commit 3b5f818

Browse files
committed
syntax: use MetaPath (a simpler version of Path) for Attribute and MetaItem.
1 parent cf242fc commit 3b5f818

24 files changed

+170
-88
lines changed

src/librustc/ich/impls_syntax.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
221221
}
222222
}
223223

224-
impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
224+
impl<'a> HashStable<StableHashingContext<'a>> for ast::MetaPath {
225225
fn hash_stable<W: StableHasherResult>(&self,
226226
hcx: &mut StableHashingContext<'a>,
227227
hasher: &mut StableHasher<W>) {
228228
self.segments.len().hash_stable(hcx, hasher);
229-
for segment in &self.segments {
230-
segment.ident.name.hash_stable(hcx, hasher);
229+
for ident in &self.segments {
230+
ident.name.hash_stable(hcx, hasher);
231231
}
232232
}
233233
}

src/librustc_driver/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ impl RustcDefaultCalls {
10711071

10721072
let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
10731073
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
1074-
path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
1074+
path: ast::MetaPath::from_ident(ast::Ident::with_empty_ctxt(name)),
10751075
node: ast::MetaItemKind::Word,
10761076
span: DUMMY_SP,
10771077
});

src/librustc_resolve/build_reduced_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> {
10211021
derives: Vec::new(),
10221022
};
10231023
parent_scope.module.builtin_attrs.borrow_mut().push((
1024-
attr.path.segments[0].ident, parent_scope
1024+
attr.path.segments[0], parent_scope
10251025
));
10261026
}
10271027
visit::walk_attribute(self, attr);

src/librustc_resolve/macros.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
299299
}).into();
300300
}
301301
return Some(ast::Attribute {
302-
path: ast::Path::from_ident(Ident::new(legacy_name, span)),
302+
path: ast::MetaPath::from_ident(Ident::new(legacy_name, span)),
303303
tokens: TokenStream::empty(),
304304
id: attr::mk_attr_id(),
305305
style: ast::AttrStyle::Outer,
@@ -315,11 +315,14 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
315315

316316
fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
317317
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
318+
let path;
318319
let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
319320
InvocationKind::Attr { attr: None, .. } =>
320321
return Ok(None),
321-
InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } =>
322-
(&attr.path, MacroKind::Attr, traits.clone(), after_derive),
322+
InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } => {
323+
path = attr.path.to_regular_path();
324+
(&path, MacroKind::Attr, traits.clone(), after_derive)
325+
}
323326
InvocationKind::Bang { ref mac, .. } =>
324327
(&mac.node.path, MacroKind::Bang, Vec::new(), false),
325328
InvocationKind::Derive { ref path, .. } =>

src/libsyntax/ast.rs

+62-2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,66 @@ impl fmt::Debug for Lifetime {
6363
}
6464
}
6565

66+
/// Simpler version of `Path` for `Attribute` and `MetaItem`.
67+
#[derive(Clone, RustcEncodable, RustcDecodable)]
68+
pub struct MetaPath {
69+
pub span: Span,
70+
pub segments: Vec<Ident>,
71+
}
72+
73+
impl<'a> PartialEq<&'a str> for MetaPath {
74+
fn eq(&self, string: &&'a str) -> bool {
75+
self.segments.len() == 1 && self.segments[0].name == *string
76+
}
77+
}
78+
79+
impl fmt::Debug for MetaPath {
80+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81+
write!(f, "path({})", pprust::meta_path_to_string(self))
82+
}
83+
}
84+
85+
impl fmt::Display for MetaPath {
86+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87+
write!(f, "{}", pprust::meta_path_to_string(self))
88+
}
89+
}
90+
91+
impl MetaPath {
92+
// convert a span and an identifier to the corresponding
93+
// 1-segment path
94+
pub fn from_ident(ident: Ident) -> MetaPath {
95+
MetaPath {
96+
span: ident.span,
97+
segments: vec![ident],
98+
}
99+
}
100+
101+
/// Try to convert a `Path` into a `MetaPath`, returning `None`
102+
/// if any of the path's segments had any generic arguments.
103+
pub fn from_regular_path(path: &Path) -> Option<MetaPath> {
104+
Some(MetaPath {
105+
span: path.span,
106+
segments: path.segments.iter().map(|segment| {
107+
if segment.args.is_none() {
108+
Some(segment.ident)
109+
} else {
110+
None
111+
}
112+
}).collect::<Option<_>>()?,
113+
})
114+
}
115+
116+
pub fn to_regular_path(&self) -> Path {
117+
Path {
118+
span: self.span,
119+
segments: self.segments.iter().map(|&ident| {
120+
PathSegment::from_ident(ident)
121+
}).collect(),
122+
}
123+
}
124+
}
125+
66126
/// A "Path" is essentially Rust's notion of a name.
67127
///
68128
/// It's represented as a sequence of identifiers,
@@ -430,7 +490,7 @@ pub enum NestedMetaItemKind {
430490
/// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
431491
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
432492
pub struct MetaItem {
433-
pub path: Path,
493+
pub path: MetaPath,
434494
pub node: MetaItemKind,
435495
pub span: Span,
436496
}
@@ -1988,7 +2048,7 @@ impl Idx for AttrId {
19882048
pub struct Attribute {
19892049
pub id: AttrId,
19902050
pub style: AttrStyle,
1991-
pub path: Path,
2051+
pub path: MetaPath,
19922052
pub tokens: TokenStream,
19932053
pub is_sugared_doc: bool,
19942054
pub span: Span,

src/libsyntax/attr/mod.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub use self::ReprAttr::*;
2222
pub use self::StabilityLevel::*;
2323

2424
use ast;
25-
use ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
25+
use ast::{AttrId, Attribute, AttrStyle, Name, Ident, MetaPath};
2626
use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
2727
use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
2828
use source_map::{BytePos, Spanned, respan, dummy_spanned};
@@ -166,8 +166,8 @@ impl NestedMetaItem {
166166
}
167167
}
168168

169-
fn name_from_path(path: &Path) -> Name {
170-
path.segments.last().expect("empty path in attribute").ident.name
169+
fn name_from_path(path: &MetaPath) -> Name {
170+
path.segments.last().expect("empty path in attribute").name
171171
}
172172

173173
impl Attribute {
@@ -270,7 +270,7 @@ impl MetaItem {
270270

271271
pub fn is_scoped(&self) -> Option<Ident> {
272272
if self.path.segments.len() > 1 {
273-
Some(self.path.segments[0].ident)
273+
Some(self.path.segments[0])
274274
} else {
275275
None
276276
}
@@ -366,15 +366,15 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem
366366
}
367367

368368
pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
369-
MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
369+
MetaItem { path: MetaPath::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
370370
}
371371

372372
pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
373-
MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
373+
MetaItem { path: MetaPath::from_ident(ident), span, node: MetaItemKind::List(items) }
374374
}
375375

376376
pub fn mk_word_item(ident: Ident) -> MetaItem {
377-
MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
377+
MetaItem { path: MetaPath::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
378378
}
379379

380380
pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
@@ -432,7 +432,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
432432
Attribute {
433433
id,
434434
style,
435-
path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
435+
path: MetaPath::from_ident(Ident::from_str("doc").with_span_pos(span)),
436436
tokens: MetaItemKind::NameValue(lit).tokens(span),
437437
is_sugared_doc: true,
438438
span,
@@ -470,17 +470,17 @@ impl MetaItem {
470470
fn tokens(&self) -> TokenStream {
471471
let mut idents = vec![];
472472
let mut last_pos = BytePos(0 as u32);
473-
for (i, segment) in self.path.segments.iter().enumerate() {
473+
for (i, &ident) in self.path.segments.iter().enumerate() {
474474
let is_first = i == 0;
475475
if !is_first {
476476
let mod_sep_span = Span::new(last_pos,
477-
segment.ident.span.lo(),
478-
segment.ident.span.ctxt());
477+
ident.span.lo(),
478+
ident.span.ctxt());
479479
idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
480480
}
481-
idents.push(TokenTree::Token(segment.ident.span,
482-
Token::from_ast_ident(segment.ident)).into());
483-
last_pos = segment.ident.span.hi();
481+
idents.push(TokenTree::Token(ident.span,
482+
Token::from_ast_ident(ident)).into());
483+
last_pos = ident.span.hi();
484484
}
485485
idents.push(self.node.tokens(self.span));
486486
TokenStream::concat(idents)
@@ -493,12 +493,12 @@ impl MetaItem {
493493
let path = match tokens.next() {
494494
Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
495495
if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
496-
let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
496+
let mut segments = vec![ident.with_span_pos(span)];
497497
tokens.next();
498498
loop {
499499
if let Some(TokenTree::Token(span,
500500
Token::Ident(ident, _))) = tokens.next() {
501-
segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
501+
segments.push(ident.with_span_pos(span));
502502
} else {
503503
return None;
504504
}
@@ -508,16 +508,18 @@ impl MetaItem {
508508
break;
509509
}
510510
}
511-
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
512-
Path { span, segments }
511+
let span = span.with_hi(segments.last().unwrap().span.hi());
512+
MetaPath { span, segments }
513513
} else {
514-
Path::from_ident(ident.with_span_pos(span))
514+
MetaPath::from_ident(ident.with_span_pos(span))
515515
}
516516
}
517517
Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
518-
token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
518+
token::Nonterminal::NtIdent(ident, _) => MetaPath::from_ident(ident),
519519
token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
520-
token::Nonterminal::NtPath(ref path) => path.clone(),
520+
token::Nonterminal::NtPath(ref path) => {
521+
ast::MetaPath::from_regular_path(path)?
522+
}
521523
_ => return None,
522524
},
523525
_ => return None,

src/libsyntax/ext/expand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
601601
let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span);
602602
let tok_result = mac.expand(self.cx, attr.span, input, item_tok);
603603
let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind,
604-
&attr.path, attr.span);
604+
&attr.path.to_regular_path(), attr.span);
605605
self.gate_proc_macro_expansion(attr.span, &res);
606606
res
607607
}
@@ -928,7 +928,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
928928
invoc.expansion_data.mark.set_expn_info(expn_info);
929929
let span = span.with_ctxt(self.cx.backtrace());
930930
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
931-
path: Path::from_ident(keywords::Invalid.ident()),
931+
path: ast::MetaPath::from_ident(keywords::Invalid.ident()),
932932
span: DUMMY_SP,
933933
node: ast::MetaItemKind::Word,
934934
};

src/libsyntax/ext/quote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,12 @@ pub mod rt {
235235
r.push(TokenTree::Token(self.span, token::Not));
236236
}
237237
let mut inner = Vec::new();
238-
for (i, segment) in self.path.segments.iter().enumerate() {
238+
for (i, &ident) in self.path.segments.iter().enumerate() {
239239
if i > 0 {
240240
inner.push(TokenTree::Token(self.span, token::Colon).into());
241241
}
242242
inner.push(TokenTree::Token(
243-
self.span, token::Token::from_ast_ident(segment.ident)
243+
self.span, token::Token::from_ast_ident(ident)
244244
).into());
245245
}
246246
inner.push(self.tokens.clone());

src/libsyntax/fold.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ pub fn noop_fold_attribute<T: Folder>(attr: Attribute, fld: &mut T) -> Option<At
541541
Some(Attribute {
542542
id: attr.id,
543543
style: attr.style,
544-
path: fld.fold_path(attr.path),
544+
path: attr.path.clone(),
545545
tokens: fld.fold_tts(attr.tokens),
546546
is_sugared_doc: attr.is_sugared_doc,
547547
span: fld.new_span(attr.span),
@@ -581,7 +581,7 @@ pub fn noop_fold_meta_list_item<T: Folder>(li: NestedMetaItem, fld: &mut T)
581581

582582
pub fn noop_fold_meta_item<T: Folder>(mi: MetaItem, fld: &mut T) -> MetaItem {
583583
MetaItem {
584-
path: fld.fold_path(mi.path),
584+
path: mi.path.clone(),
585585
node: match mi.node {
586586
MetaItemKind::Word => MetaItemKind::Word,
587587
MetaItemKind::List(mis) => {

src/libsyntax/parse/attr.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl<'a> Parser<'a> {
147147
/// PATH
148148
/// PATH `=` TOKEN_TREE
149149
/// The delimiters or `=` are still put into the resulting token stream.
150-
crate fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
150+
crate fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::MetaPath, TokenStream)> {
151151
let meta = match self.token {
152152
token::Interpolated(ref nt) => match nt.0 {
153153
Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
@@ -174,7 +174,7 @@ impl<'a> Parser<'a> {
174174
} else {
175175
TokenStream::empty()
176176
};
177-
(path, tokens)
177+
(ast::MetaPath::from_regular_path(&path).unwrap(), tokens)
178178
})
179179
}
180180

@@ -251,7 +251,11 @@ impl<'a> Parser<'a> {
251251
let path = self.parse_path(PathStyle::Mod)?;
252252
let node = self.parse_meta_item_kind()?;
253253
let span = lo.to(self.prev_span);
254-
Ok(ast::MetaItem { path, node, span })
254+
Ok(ast::MetaItem {
255+
path: ast::MetaPath::from_regular_path(&path).unwrap(),
256+
node,
257+
span,
258+
})
255259
}
256260

257261
crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {

0 commit comments

Comments
 (0)