diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index cad6ff8ae9f..e8bdb9d5d5f 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -153,10 +153,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { // ``` let hints: Vec<_> = item.attrs .iter() - .filter(|attr| match attr.name() { - Some(name) => name == "repr", - None => false, - }) + .filter(|attr| attr.name() == "repr") .filter_map(|attr| attr.meta_item_list()) .flat_map(|hints| hints) .collect(); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index ed7b79b392d..d90dba2ff04 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -199,8 +199,7 @@ impl<'a> HashStable> for [ast::Attribute] { let filtered: AccumulateVec<[&ast::Attribute; 8]> = self .iter() .filter(|attr| { - !attr.is_sugared_doc && - attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true) + !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name()) }) .collect(); @@ -227,7 +226,7 @@ impl<'a> HashStable> for ast::Attribute { hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { // Make sure that these have been filtered out. - debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)); + debug_assert!(!hcx.is_ignored_attr(self.name())); debug_assert!(!self.is_sugared_doc); let ast::Attribute { diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index e8b536d5267..0eeb0cf6c37 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -198,7 +198,7 @@ impl<'a> LintLevelsBuilder<'a> { "malformed lint attribute"); }; for attr in attrs { - let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) { + let level = match Level::from_str(&attr.name().as_str()) { None => continue, Some(lvl) => lvl, }; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 328b2db2b58..279908d2b67 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -205,7 +205,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } else { // Emit errors for non-staged-api crates. for attr in attrs { - let tag = unwrap_or!(attr.name(), continue); + let tag = attr.name(); 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 \ diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 91ce6f3854a..f06062fa4ac 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -675,9 +675,8 @@ impl LintPass for DeprecatedAttr { impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { - let name = unwrap_or!(attr.name(), return); for &&(n, _, ref g) in &self.depr_attrs { - if name == n { + if attr.name() == n { if let &AttributeGate::Gated(Stability::Deprecated(link), ref name, ref reason, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 65b340d6568..4f6d23dce6d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -30,7 +30,6 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#[macro_use] extern crate syntax; #[macro_use] extern crate rustc; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 9e1b75ba336..8df40b62ddd 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -192,8 +192,6 @@ 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 { match ty { @@ -213,6 +211,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { } } + let name = attr.name(); if !attr::is_used(attr) { debug!("Emitting warning for: {:?}", attr); cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute"); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 35228748f06..4afc621ad8b 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -209,7 +209,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec, allow_derive: bool) -> Option { for i in 0..attrs.len() { - let name = unwrap_or!(attrs[i].name(), continue); + let name = attrs[i].name(); if self.session.plugin_attributes.borrow().iter() .any(|&(ref attr_nm, _)| name == &**attr_nm) { @@ -231,11 +231,11 @@ impl<'a> base::Resolver for Resolver<'a> { // Check for legacy derives for i in 0..attrs.len() { - let name = unwrap_or!(attrs[i].name(), continue); + let name = attrs[i].name(); if name == "derive" { let result = attrs[i].parse_list(&self.session.parse_sess, |parser| { - parser.parse_path(PathStyle::Mod) + parser.parse_path_allowing_meta(PathStyle::Mod) }); let mut traits = match result { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd64ac67ac9..d124a17b421 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3661,7 +3661,7 @@ impl Clean> for doctree::Import { // #[doc(no_inline)] attribute is present. // Don't inline doc(hidden) imports so they can be stripped at a later stage. let denied = self.vis != hir::Public || self.attrs.iter().any(|a| { - a.name().unwrap() == "doc" && match a.meta_item_list() { + a.name() == "doc" && match a.meta_item_list() { Some(l) => attr::list_contains_name(&l, "no_inline") || attr::list_contains_name(&l, "hidden"), None => false, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4e9781cc560..9248210c269 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3319,7 +3319,7 @@ fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { let mut attrs = String::new(); for attr in &it.attrs.other_attrs { - let name = attr.name().unwrap(); + let name = attr.name(); if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) { continue; } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 7a0231dc3f4..f805ba80885 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -217,11 +217,10 @@ impl Attribute { matches } - pub fn name(&self) -> Option { - match self.path.segments.len() { - 1 => Some(self.path.segments[0].identifier.name), - _ => None, - } + /// Returns the first segment of the name of this attribute. + /// E.g. `foo` for `#[foo]`, `rustfmt` for `#[rustfmt::skip]`. + pub fn name(&self) -> Name { + name_from_path(&self.path) } pub fn value_str(&self) -> Option { diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index afb233533ba..6bf166dfe95 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -26,7 +26,8 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec) -> Vec return true; } - match attr.parse_list(cx.parse_sess, |parser| parser.parse_path(PathStyle::Mod)) { + match attr.parse_list(cx.parse_sess, + |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) { Ok(ref traits) if traits.is_empty() => { cx.span_warn(attr.span, "empty trait list in `derive`"); false diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b1f3c74d9f7..9bae8e73c7f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1132,7 +1132,7 @@ macro_rules! gate_feature { impl<'a> Context<'a> { fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) { debug!("check_attribute(attr = {:?})", attr); - let name = unwrap_or!(attr.name(), return).as_str(); + let name = attr.name().as_str(); for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES { if name == n { if let Gated(_, name, desc, ref has_feature) = *gateage { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 324cadc84e8..d8fd3870495 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1955,19 +1955,19 @@ impl<'a> Parser<'a> { /// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat. /// This is used when parsing derive macro paths in `#[derive]` attributes. pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast::Path> { - let meta_ident = match self.token { + let meta_name = match self.token { token::Interpolated(ref nt) => match nt.0 { token::NtMeta(ref meta) => match meta.node { - ast::MetaItemKind::Word => Some(meta.ident), + ast::MetaItemKind::Word => Some(meta.name.clone()), _ => None, }, _ => None, }, _ => None, }; - if let Some(ident) = meta_ident { + if let Some(path) = meta_name { self.bump(); - return Ok(ast::Path::from_ident(ident)); + return Ok(path); } self.parse_path(style) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e8beb7e442c..96f7caf165c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -776,6 +776,7 @@ pub trait PrintState<'a> { ast::MetaItemKind::Word => self.print_attribute_path(&item.name)?, ast::MetaItemKind::NameValue(ref value) => { self.print_attribute_path(&item.name)?; + self.writer().space()?; self.word_space("=")?; self.print_literal(value)?; } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 5fd5e299488..76da1746a03 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -22,11 +22,9 @@ struct MarkAttrs<'a>(&'a [ast::Name]); impl<'a> Visitor<'a> for MarkAttrs<'a> { fn visit_attribute(&mut self, attr: &Attribute) { - if let Some(name) = attr.name() { - if self.0.contains(&name) { - mark_used(attr); - mark_known(attr); - } + if self.0.contains(&attr.name()) { + mark_used(attr); + mark_known(attr); } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index becd70149fd..80f65957c39 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -472,7 +472,7 @@ impl<'a> TraitDef<'a> { attrs.extend(item.attrs .iter() .filter(|a| { - a.name().is_some() && match &*a.name().unwrap().as_str() { + match &*a.name().as_str() { "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true, _ => false, }