diff options
| author | Zack M. Davis <code@zackmdavis.net> | 2017-08-26 18:00:33 -0700 |
|---|---|---|
| committer | Zack M. Davis <code@zackmdavis.net> | 2017-08-28 00:58:41 -0700 |
| commit | 8bb29465d0cba5216ba6e8ec34d5b379392f78aa (patch) | |
| tree | 835a273cf33ff0cb3a33fe039cc21ec0ea488d4c /src/libsyntax | |
| parent | e2668882406b68739c6ed33d420358d5d710e67b (diff) | |
feature error span on attr. for fn_must_use, SIMD/align, macro reëxport
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.)
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 42 |
2 files changed, 23 insertions, 23 deletions
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<Symbol> { 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); } |
