Skip to content

syntax: use MetaPath (a simpler version of Path) for Attribute and MetaItem. #56492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/librustc/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
}
}

impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
impl<'a> HashStable<StableHashingContext<'a>> for ast::MetaPath {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.segments.len().hash_stable(hcx, hasher);
for segment in &self.segments {
segment.ident.name.hash_stable(hcx, hasher);
for ident in &self.segments {
ident.name.hash_stable(hcx, hasher);
}
}
}
Expand Down Expand Up @@ -380,7 +380,7 @@ impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
});

impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
ident,
path,
node,
span
});
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/lint/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ impl<'a> LintLevelsBuilder<'a> {
ast::MetaItemKind::Word => {} // actual lint names handled later
ast::MetaItemKind::NameValue(ref name_value) => {
let gate_reasons = !self.sess.features_untracked().lint_reasons;
if item.ident == "reason" {
if item.path == "reason" {
// found reason, reslice meta list to exclude it
metas = &metas[0..metas.len()-1];
// FIXME (#55112): issue unused-attributes lint if we thereby
Expand Down Expand Up @@ -274,7 +274,7 @@ impl<'a> LintLevelsBuilder<'a> {
let mut err = bad_attr(li.span);
if let Some(item) = li.meta_item() {
if let ast::MetaItemKind::NameValue(_) = item.node {
if item.ident == "reason" {
if item.path == "reason" {
err.help("reason in lint attribute must come last");
}
}
Expand All @@ -290,7 +290,7 @@ impl<'a> LintLevelsBuilder<'a> {
lint_tool.span,
E0710,
"an unknown tool name found in scoped lint: `{}`",
word.ident
word.path
);
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> ast::CrateConfig {

match &mut parser.parse_meta_item() {
Ok(meta_item) if parser.token == token::Eof => {
if meta_item.ident.segments.len() != 1 {
if meta_item.path.segments.len() != 1 {
error!("argument key must be an identifier");
}
match &meta_item.node {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ impl RustcDefaultCalls {

let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
path: ast::MetaPath::from_ident(ast::Ident::with_empty_ctxt(name)),
node: ast::MetaItemKind::Word,
span: DUMMY_SP,
});
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD
} else {
sess.span_err(
item.span,
&format!("{} attribute requires a path", item.ident));
&format!("{} attribute requires a path", item.path));
return None;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> {
derives: Vec::new(),
};
parent_scope.module.builtin_attrs.borrow_mut().push((
attr.path.segments[0].ident, parent_scope
attr.path.segments[0], parent_scope
));
}
visit::walk_attribute(self, attr);
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
}).into();
}
return Some(ast::Attribute {
path: ast::Path::from_ident(Ident::new(legacy_name, span)),
path: ast::MetaPath::from_ident(Ident::new(legacy_name, span)),
tokens: TokenStream::empty(),
id: attr::mk_attr_id(),
style: ast::AttrStyle::Outer,
Expand All @@ -315,11 +315,14 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {

fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
let path;
let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
InvocationKind::Attr { attr: None, .. } =>
return Ok(None),
InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } =>
(&attr.path, MacroKind::Attr, traits.clone(), after_derive),
InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } => {
path = attr.path.to_regular_path();
(&path, MacroKind::Attr, traits.clone(), after_derive)
}
InvocationKind::Bang { ref mac, .. } =>
(&mac.node.path, MacroKind::Bang, Vec::new(), false),
InvocationKind::Derive { ref path, .. } =>
Expand Down
64 changes: 62 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,66 @@ impl fmt::Debug for Lifetime {
}
}

/// Simpler version of `Path` for `Attribute` and `MetaItem`.
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct MetaPath {
pub span: Span,
pub segments: Vec<Ident>,
}

impl<'a> PartialEq<&'a str> for MetaPath {
fn eq(&self, string: &&'a str) -> bool {
self.segments.len() == 1 && self.segments[0].name == *string
}
}

impl fmt::Debug for MetaPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "path({})", pprust::meta_path_to_string(self))
}
}

impl fmt::Display for MetaPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", pprust::meta_path_to_string(self))
}
}

impl MetaPath {
// convert a span and an identifier to the corresponding
// 1-segment path
pub fn from_ident(ident: Ident) -> MetaPath {
MetaPath {
span: ident.span,
segments: vec![ident],
}
}

/// Try to convert a `Path` into a `MetaPath`, returning `None`
/// if any of the path's segments had any generic arguments.
pub fn from_regular_path(path: &Path) -> Option<MetaPath> {
Some(MetaPath {
span: path.span,
segments: path.segments.iter().map(|segment| {
if segment.args.is_none() {
Some(segment.ident)
} else {
None
}
}).collect::<Option<_>>()?,
})
}

pub fn to_regular_path(&self) -> Path {
Path {
span: self.span,
segments: self.segments.iter().map(|&ident| {
PathSegment::from_ident(ident)
}).collect(),
}
}
}

/// A "Path" is essentially Rust's notion of a name.
///
/// It's represented as a sequence of identifiers,
Expand Down Expand Up @@ -430,7 +490,7 @@ pub enum NestedMetaItemKind {
/// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct MetaItem {
pub ident: Path,
pub path: MetaPath,
pub node: MetaItemKind,
pub span: Span,
}
Expand Down Expand Up @@ -1988,7 +2048,7 @@ impl Idx for AttrId {
pub struct Attribute {
pub id: AttrId,
pub style: AttrStyle,
pub path: Path,
pub path: MetaPath,
pub tokens: TokenStream,
pub is_sugared_doc: bool,
pub span: Span,
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/attr/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,8 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
gated_cfg.check_and_emit(sess, feats);
}
let error = |span, msg| { sess.span_diagnostic.span_err(span, msg); true };
if cfg.ident.segments.len() != 1 {
return error(cfg.ident.span, "`cfg` predicate key must be an identifier");
if cfg.path.segments.len() != 1 {
return error(cfg.path.span, "`cfg` predicate key must be an identifier");
}
match &cfg.node {
MetaItemKind::List(..) => {
Expand Down
66 changes: 34 additions & 32 deletions src/libsyntax/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use self::ReprAttr::*;
pub use self::StabilityLevel::*;

use ast;
use ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
use ast::{AttrId, Attribute, AttrStyle, Name, Ident, MetaPath};
use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
use source_map::{BytePos, Spanned, respan, dummy_spanned};
Expand Down Expand Up @@ -166,8 +166,8 @@ impl NestedMetaItem {
}
}

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

impl Attribute {
Expand Down Expand Up @@ -216,7 +216,7 @@ impl Attribute {

impl MetaItem {
pub fn name(&self) -> Name {
name_from_path(&self.ident)
name_from_path(&self.path)
}

// #[attribute(name = "value")]
Expand Down Expand Up @@ -269,8 +269,8 @@ impl MetaItem {
}

pub fn is_scoped(&self) -> Option<Ident> {
if self.ident.segments.len() > 1 {
Some(self.ident.segments[0].ident)
if self.path.segments.len() > 1 {
Some(self.path.segments[0])
} else {
None
}
Expand All @@ -282,7 +282,7 @@ impl Attribute {
pub fn meta(&self) -> Option<MetaItem> {
let mut tokens = self.tokens.trees().peekable();
Some(MetaItem {
ident: self.path.clone(),
path: self.path.clone(),
node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
if tokens.peek().is_some() {
return None;
Expand Down Expand Up @@ -328,7 +328,7 @@ impl Attribute {

pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
Ok(MetaItem {
ident: self.path.clone(),
path: self.path.clone(),
node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
span: self.span,
})
Expand Down Expand Up @@ -366,15 +366,15 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem
}

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

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

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

pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
Expand Down Expand Up @@ -402,7 +402,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute
Attribute {
id,
style: ast::AttrStyle::Inner,
path: item.ident,
path: item.path,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
Expand All @@ -419,7 +419,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
Attribute {
id,
style: ast::AttrStyle::Outer,
path: item.ident,
path: item.path,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
Expand All @@ -432,7 +432,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
Attribute {
id,
style,
path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
path: MetaPath::from_ident(Ident::from_str("doc").with_span_pos(span)),
tokens: MetaItemKind::NameValue(lit).tokens(span),
is_sugared_doc: true,
span,
Expand Down Expand Up @@ -470,17 +470,17 @@ impl MetaItem {
fn tokens(&self) -> TokenStream {
let mut idents = vec![];
let mut last_pos = BytePos(0 as u32);
for (i, segment) in self.ident.segments.iter().enumerate() {
for (i, &ident) in self.path.segments.iter().enumerate() {
let is_first = i == 0;
if !is_first {
let mod_sep_span = Span::new(last_pos,
segment.ident.span.lo(),
segment.ident.span.ctxt());
ident.span.lo(),
ident.span.ctxt());
idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
}
idents.push(TokenTree::Token(segment.ident.span,
Token::from_ast_ident(segment.ident)).into());
last_pos = segment.ident.span.hi();
idents.push(TokenTree::Token(ident.span,
Token::from_ast_ident(ident)).into());
last_pos = ident.span.hi();
}
idents.push(self.node.tokens(self.span));
TokenStream::concat(idents)
Expand All @@ -490,15 +490,15 @@ impl MetaItem {
where I: Iterator<Item = TokenTree>,
{
// FIXME: Share code with `parse_path`.
let ident = match tokens.next() {
let path = match tokens.next() {
Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
let mut segments = vec![ident.with_span_pos(span)];
tokens.next();
loop {
if let Some(TokenTree::Token(span,
Token::Ident(ident, _))) = tokens.next() {
segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
segments.push(ident.with_span_pos(span));
} else {
return None;
}
Expand All @@ -508,16 +508,18 @@ impl MetaItem {
break;
}
}
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
Path { span, segments }
let span = span.with_hi(segments.last().unwrap().span.hi());
MetaPath { span, segments }
} else {
Path::from_ident(ident.with_span_pos(span))
MetaPath::from_ident(ident.with_span_pos(span))
}
}
Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
token::Nonterminal::NtIdent(ident, _) => MetaPath::from_ident(ident),
token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
token::Nonterminal::NtPath(ref path) => path.clone(),
token::Nonterminal::NtPath(ref path) => {
ast::MetaPath::from_regular_path(path)?
}
_ => return None,
},
_ => return None,
Expand All @@ -526,11 +528,11 @@ impl MetaItem {
let node = MetaItemKind::from_tokens(tokens)?;
let hi = match node {
MetaItemKind::NameValue(ref lit) => lit.span.hi(),
MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
_ => ident.span.hi(),
MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()),
_ => path.span.hi(),
};
let span = ident.span.with_hi(hi);
Some(MetaItem { ident, node, span })
let span = path.span.with_hi(hi);
Some(MetaItem { path, node, span })
}
}

Expand Down
Loading