From 8bb29465d0cba5216ba6e8ec34d5b379392f78aa Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 26 Aug 2017 18:00:33 -0700 Subject: feature error span on attr. for fn_must_use, SIMD/align, macro reƫxport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were several feature-gated attributes for which the feature-not-available error spans would point to the item annotated with the gated attribute, when it would make more sense for the span to point to the attribute itself: if the attribute is removed, the function/struct/&c. likely still makes sense and the program will compile. (Note that we decline to make the analogous change for the `main`, `start`, and `plugin_registrar` features, for in those cases it makes sense for the span to implicate the entire function, of which there is little hope of using without the gated attribute.) --- src/libsyntax/attr.rs | 4 ++++ src/libsyntax/feature_gate.rs | 42 +++++++++++++++++++----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index ca87c807103..f97a8f67e22 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -490,6 +490,10 @@ pub fn contains_name(attrs: &[Attribute], name: &str) -> bool { }) } +pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> { + attrs.iter().find(|attr| attr.check_name(name)) +} + pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option { attrs.iter() .find(|at| at.check_name(name)) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 09574d5ba12..2526ac3021a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1248,8 +1248,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &'a ast::Item) { match i.node { ast::ItemKind::ExternCrate(_) => { - if attr::contains_name(&i.attrs[..], "macro_reexport") { - gate_feature_post!(&self, macro_reexport, i.span, + if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") { + gate_feature_post!(&self, macro_reexport, attr.span, "macros reexports are experimental \ and possibly buggy"); } @@ -1276,36 +1276,32 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { function may change over time, for now \ a top-level `fn main()` is required"); } - if attr::contains_name(&i.attrs[..], "must_use") { - gate_feature_post!(&self, fn_must_use, i.span, + if let Some(attr) = attr::find_by_name(&i.attrs[..], "must_use") { + gate_feature_post!(&self, fn_must_use, attr.span, "`#[must_use]` on functions is experimental", GateStrength::Soft); } } ast::ItemKind::Struct(..) => { - if attr::contains_name(&i.attrs[..], "simd") { - gate_feature_post!(&self, simd, i.span, + if let Some(attr) = attr::find_by_name(&i.attrs[..], "simd") { + gate_feature_post!(&self, simd, attr.span, "SIMD types are experimental and possibly buggy"); - self.context.parse_sess.span_diagnostic.span_warn(i.span, + self.context.parse_sess.span_diagnostic.span_warn(attr.span, "the `#[simd]` attribute \ is deprecated, use \ `#[repr(simd)]` instead"); } - for attr in &i.attrs { - if attr.path == "repr" { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name("simd") { - gate_feature_post!(&self, repr_simd, i.span, - "SIMD types are experimental \ - and possibly buggy"); - - } - if item.check_name("align") { - gate_feature_post!(&self, repr_align, i.span, - "the struct `#[repr(align(u16))]` attribute \ - is experimental"); - } + if let Some(attr) = attr::find_by_name(&i.attrs[..], "repr") { + for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + if item.check_name("simd") { + gate_feature_post!(&self, repr_simd, attr.span, + "SIMD types are experimental and possibly buggy"); + } + if item.check_name("align") { + gate_feature_post!(&self, repr_align, attr.span, + "the struct `#[repr(align(u16))]` attribute \ + is experimental"); } } } @@ -1334,8 +1330,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { for impl_item in impl_items { if let ast::ImplItemKind::Method(..) = impl_item.node { - if attr::contains_name(&impl_item.attrs[..], "must_use") { - gate_feature_post!(&self, fn_must_use, impl_item.span, + if let Some(attr) = attr::find_by_name(&impl_item.attrs[..], "must_use") { + gate_feature_post!(&self, fn_must_use, attr.span, "`#[must_use]` on methods is experimental", GateStrength::Soft); } -- cgit 1.4.1-3-g733a5