Skip to content
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

TokenStream-based attributes, paths in attribute and derive macro invocations #40346

Merged
merged 4 commits into from
Mar 19, 2017
Merged
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
11 changes: 6 additions & 5 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,12 @@ impl<'a> CheckAttrVisitor<'a> {
}

fn check_attribute(&self, attr: &ast::Attribute, target: Target) {
let name: &str = &attr.name().as_str();
match name {
"inline" => self.check_inline(attr, target),
"repr" => self.check_repr(attr, target),
_ => (),
if let Some(name) = attr.name() {
match &*name.as_str() {
"inline" => self.check_inline(attr, target),
"repr" => self.check_repr(attr, target),
_ => (),
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ impl<'a> LoweringContext<'a> {
let attrs = self.lower_attrs(&i.attrs);
let mut vis = self.lower_visibility(&i.vis);
if let ItemKind::MacroDef(ref tts) = i.node {
if i.attrs.iter().any(|attr| attr.name() == "macro_export") {
if i.attrs.iter().any(|attr| attr.path == "macro_export") {
self.exported_macros.push(hir::MacroDef {
name: name, attrs: attrs, id: i.id, span: i.span, body: tts.clone().into(),
});
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,14 @@ pub fn gather_attrs(attrs: &[ast::Attribute]) -> Vec<Result<(ast::Name, Level, S
pub fn gather_attr(attr: &ast::Attribute) -> Vec<Result<(ast::Name, Level, Span), Span>> {
let mut out = vec![];

let level = match Level::from_str(&attr.name().as_str()) {
let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
None => return out,
Some(lvl) => lvl,
};

let meta = unwrap_or!(attr.meta(), return out);
attr::mark_used(attr);

let meta = &attr.value;
let metas = if let Some(metas) = meta.meta_item_list() {
metas
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
} else {
// Emit errors for non-staged-api crates.
for attr in attrs {
let tag = attr.name();
let tag = unwrap_or!(attr.name(), continue);
if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
attr::mark_used(attr);
self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
Expand Down Expand Up @@ -402,7 +402,7 @@ impl<'a, 'tcx> Index<'tcx> {

let mut is_staged_api = false;
for attr in &krate.attrs {
if attr.name() == "stable" || attr.name() == "unstable" {
if attr.path == "stable" || attr.path == "unstable" {
is_staged_api = true;
break
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.filter(|a| a.check_name("rustc_on_unimplemented"))
.next()
{
let err_sp = item.meta().span.substitute_dummy(span);
let err_sp = item.span.substitute_dummy(span);
let trait_str = self.tcx.item_path_str(trait_ref.def_id);
if let Some(istring) = item.value_str() {
let istring = &*istring.as_str();
Expand Down
55 changes: 14 additions & 41 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@ use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
use syntax::parse::token;
use syntax::symbol::{Symbol, InternedString};
use syntax::symbol::InternedString;
use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
use syntax::tokenstream;
use rustc::hir;
use rustc::hir::*;
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit as visit;
use rustc::hir::intravisit::{self as visit, Visitor};
use rustc::ty::TyCtxt;
use rustc_data_structures::fnv;
use std::hash::{Hash, Hasher};

use super::def_path_hash::DefPathHashes;
Expand Down Expand Up @@ -559,7 +558,7 @@ macro_rules! hash_span {
});
}

impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
impl<'a, 'hash, 'tcx> Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> visit::NestedVisitorMap<'this, 'tcx> {
if self.hash_bodies {
visit::NestedVisitorMap::OnlyBodies(&self.tcx.hir)
Expand Down Expand Up @@ -960,50 +959,24 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
}
}

fn hash_meta_item(&mut self, meta_item: &ast::MetaItem) {
debug!("hash_meta_item: st={:?}", self.st);

// ignoring span information, it doesn't matter here
self.hash_discriminant(&meta_item.node);
meta_item.name.as_str().len().hash(self.st);
meta_item.name.as_str().hash(self.st);

match meta_item.node {
ast::MetaItemKind::Word => {}
ast::MetaItemKind::NameValue(ref lit) => saw_lit(lit).hash(self.st),
ast::MetaItemKind::List(ref items) => {
// Sort subitems so the hash does not depend on their order
let indices = self.indices_sorted_by(&items, |p| {
(p.name().map(Symbol::as_str), fnv::hash(&p.literal().map(saw_lit)))
});
items.len().hash(self.st);
for (index, &item_index) in indices.iter().enumerate() {
index.hash(self.st);
let nested_meta_item: &ast::NestedMetaItemKind = &items[item_index].node;
self.hash_discriminant(nested_meta_item);
match *nested_meta_item {
ast::NestedMetaItemKind::MetaItem(ref meta_item) => {
self.hash_meta_item(meta_item);
}
ast::NestedMetaItemKind::Literal(ref lit) => {
saw_lit(lit).hash(self.st);
}
}
}
}
}
}

pub fn hash_attributes(&mut self, attributes: &[ast::Attribute]) {
debug!("hash_attributes: st={:?}", self.st);
let indices = self.indices_sorted_by(attributes, |attr| attr.name());

for i in indices {
let attr = &attributes[i];
if !attr.is_sugared_doc &&
!IGNORED_ATTRIBUTES.contains(&&*attr.value.name().as_str()) {
match attr.name() {
Some(name) if IGNORED_ATTRIBUTES.contains(&&*name.as_str()) => continue,
_ => {}
};
if !attr.is_sugared_doc {
SawAttribute(attr.style).hash(self.st);
self.hash_meta_item(&attr.value);
for segment in &attr.path.segments {
SawIdent(segment.identifier.name.as_str()).hash(self.st);
}
for tt in attr.tokens.trees() {
self.hash_token_tree(&tt);
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_incremental/persist/dirty_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ pub struct DirtyCleanVisitor<'a, 'tcx:'a> {

impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
fn dep_node(&self, attr: &Attribute, def_id: DefId) -> DepNode<DefId> {
for item in attr.meta_item_list().unwrap_or(&[]) {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
if item.check_name(LABEL) {
let value = expect_associated_value(self.tcx, item);
let value = expect_associated_value(self.tcx, &item);
match DepNode::from_label_string(&value.as_str(), def_id) {
Ok(def_id) => return def_id,
Err(()) => {
Expand Down Expand Up @@ -331,9 +331,9 @@ fn check_config(tcx: TyCtxt, attr: &Attribute) -> bool {
debug!("check_config(attr={:?})", attr);
let config = &tcx.sess.parse_sess.config;
debug!("check_config: config={:?}", config);
for item in attr.meta_item_list().unwrap_or(&[]) {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
if item.check_name(CFG) {
let value = expect_associated_value(tcx, item);
let value = expect_associated_value(tcx, &item);
debug!("check_config: searching for cfg {:?}", value);
return config.contains(&(value, None));
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ impl MissingDoc {
}
}

let has_doc = attrs.iter().any(|a| a.is_value_str() && a.name() == "doc");
let has_doc = attrs.iter().any(|a| a.is_value_str() && a.check_name("doc"));
if !has_doc {
cx.span_lint(MISSING_DOCS,
sp,
Expand Down Expand Up @@ -635,7 +635,7 @@ impl LintPass for DeprecatedAttr {

impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
let name = attr.name();
let name = unwrap_or!(attr.name(), return);
for &&(n, _, ref g) in &self.depr_attrs {
if name == n {
if let &AttributeGate::Gated(Stability::Deprecated(link),
Expand Down Expand Up @@ -1121,8 +1121,8 @@ impl LintPass for UnstableFeatures {

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) {
if attr.meta().check_name("feature") {
if let Some(items) = attr.meta().meta_item_list() {
if attr.check_name("feature") {
if let Some(items) = attr.meta_item_list() {
for item in items {
ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#![feature(slice_patterns)]
#![feature(staged_api)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ impl LintPass for UnusedAttributes {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
debug!("checking attribute: {:?}", attr);
let name = unwrap_or!(attr.name(), return);

// Note that check_name() marks the attribute as used if it matches.
for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
Expand All @@ -294,13 +295,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
// Is it a builtin attribute that must be used at the crate level?
let known_crate = BUILTIN_ATTRIBUTES.iter()
.find(|&&(name, ty, _)| attr.name() == name && ty == AttributeType::CrateLevel)
.find(|&&(builtin, ty, _)| name == builtin && ty == AttributeType::CrateLevel)
.is_some();

// Has a plugin registered this attribute as one which must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
.find(|&&(ref x, t)| attr.name() == &**x && AttributeType::CrateLevel == t)
.find(|&&(ref x, t)| name == &**x && AttributeType::CrateLevel == t)
.is_some();
if known_crate || plugin_crate {
let msg = match attr.style {
Expand Down
8 changes: 5 additions & 3 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,9 +973,11 @@ impl<'a> CrateLoader<'a> {

impl<'a> CrateLoader<'a> {
pub fn preprocess(&mut self, krate: &ast::Crate) {
for attr in krate.attrs.iter().filter(|m| m.name() == "link_args") {
if let Some(linkarg) = attr.value_str() {
self.cstore.add_used_link_args(&linkarg.as_str());
for attr in &krate.attrs {
if attr.path == "link_args" {
if let Some(linkarg) = attr.value_str() {
self.cstore.add_used_link_args(&linkarg.as_str());
}
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ impl CrateMetadata {
}

pub fn is_staged_api(&self) -> bool {
self.get_item_attrs(CRATE_DEF_INDEX)
.iter()
.any(|attr| attr.name() == "stable" || attr.name() == "unstable")
for attr in self.get_item_attrs(CRATE_DEF_INDEX) {
if attr.path == "stable" || attr.path == "unstable" {
return true;
}
}
false
}

pub fn is_allocator(&self) -> bool {
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ItemKind::Mod(_) => {
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
attr::first_attr_value_str_by_name(&item.attrs, "path");
if let Some(attr) =
item.attrs.iter().find(|attr| attr.name() == "warn_directory_ownership") {
if item.attrs.iter().any(|attr| attr.check_name("warn_directory_ownership")) {
let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
let msg = "cannot declare a new module at this location";
self.session.add_lint(lint, item.id, item.span, msg.to_string());
attr::mark_used(attr);
}
}
ItemKind::Union(ref vdata, _) => {
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,7 @@ pub struct Resolver<'a> {

privacy_errors: Vec<PrivacyError<'a>>,
ambiguity_errors: Vec<AmbiguityError<'a>>,
gated_errors: FxHashSet<Span>,
disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,

arenas: &'a ResolverArenas<'a>,
Expand Down Expand Up @@ -1355,6 +1356,7 @@ impl<'a> Resolver<'a> {

privacy_errors: Vec::new(),
ambiguity_errors: Vec::new(),
gated_errors: FxHashSet(),
disallowed_shadowing: Vec::new(),

arenas: arenas,
Expand Down Expand Up @@ -3360,8 +3362,9 @@ impl<'a> Resolver<'a> {
if self.proc_macro_enabled { return; }

for attr in attrs {
let maybe_binding = self.builtin_macros.get(&attr.name()).cloned().or_else(|| {
let ident = Ident::with_empty_ctxt(attr.name());
let name = unwrap_or!(attr.name(), continue);
let maybe_binding = self.builtin_macros.get(&name).cloned().or_else(|| {
let ident = Ident::with_empty_ctxt(name);
self.resolve_lexical_macro_path_segment(ident, MacroNS, None).ok()
});

Expand Down
Loading