diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 946cbb7960b..05c371113b4 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -47,27 +47,27 @@ struct CheckAttrVisitor<'a> { impl<'a> CheckAttrVisitor<'a> { /// Check any attribute. - fn check_attribute(&self, attr: &ast::Attribute, target: Target) { + fn check_attribute(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) { if let Some(name) = attr.name() { match &*name.as_str() { - "inline" => self.check_inline(attr, target), - "repr" => self.check_repr(attr, target), + "inline" => self.check_inline(attr, item, target), + "repr" => self.check_repr(attr, item, target), _ => (), } } } /// Check if an `#[inline]` is applied to a function. - fn check_inline(&self, attr: &ast::Attribute, target: Target) { + fn check_inline(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) { if target != Target::Fn { struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function") - .span_label(attr.span, "requires a function") + .span_label(item.span, "not a function") .emit(); } } /// Check if an `#[repr]` attr is valid. - fn check_repr(&self, attr: &ast::Attribute, target: Target) { + fn check_repr(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) { let words = match attr.meta_item_list() { Some(words) => words, None => { @@ -139,7 +139,7 @@ impl<'a> CheckAttrVisitor<'a> { _ => continue, }; struct_span_err!(self.sess, attr.span, E0517, "{}", message) - .span_label(attr.span, format!("requires {}", label)) + .span_label(item.span, format!("not {}", label)) .emit(); } if conflicting_reprs > 1 { @@ -153,7 +153,7 @@ impl<'a> Visitor<'a> for CheckAttrVisitor<'a> { fn visit_item(&mut self, item: &'a ast::Item) { let target = Target::from_item(item); for attr in &item.attrs { - self.check_attribute(attr, target); + self.check_attribute(attr, item, target); } visit::walk_item(self, item); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4cc1e83d6e3..d9f502cbdee 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -117,6 +117,7 @@ use std::mem::replace; use std::ops::{self, Deref}; use syntax::abi::Abi; use syntax::ast; +use syntax::attr; use syntax::codemap::{self, original_sp, Spanned}; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::ptr::P; @@ -1561,12 +1562,15 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let def = tcx.adt_def(def_id); def.destructor(tcx); // force the destructor to be evaluated - if vs.is_empty() && tcx.has_attr(def_id, "repr") { - struct_span_err!( - tcx.sess, sp, E0084, - "unsupported representation for zero-variant enum") - .span_label(sp, "unsupported enum representation") - .emit(); + if vs.is_empty() { + let attributes = tcx.get_attrs(def_id); + if let Some(attr) = attr::find_by_name(&attributes, "repr") { + struct_span_err!( + tcx.sess, attr.span, E0084, + "unsupported representation for zero-variant enum") + .span_label(sp, "zero-variant enum") + .emit(); + } } let repr_type_ty = def.repr.discr_type().to_ty(tcx); diff --git a/src/test/compile-fail/E0084.rs b/src/test/compile-fail/E0084.rs index c7c5662f1fe..d19eed7124e 100644 --- a/src/test/compile-fail/E0084.rs +++ b/src/test/compile-fail/E0084.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[repr(i32)] -enum Foo {} -//~^ ERROR E0084 -//~| unsupported enum representation +#[repr(i32)] //~ ERROR: E0084 +enum Foo {} //~ NOTE: zero-variant enum fn main() { } diff --git a/src/test/compile-fail/E0517.rs b/src/test/compile-fail/E0517.rs index b79cb2c44af..7feda670f52 100644 --- a/src/test/compile-fail/E0517.rs +++ b/src/test/compile-fail/E0517.rs @@ -8,21 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[repr(C)] //~ ERROR E0517 - //~| requires a struct, enum or union -type Foo = u8; +#[repr(C)] //~ ERROR: E0517 +type Foo = u8; //~ NOTE: not a struct, enum or union -#[repr(packed)] //~ ERROR E0517 - //~| requires a struct -enum Foo2 {Bar, Baz} +#[repr(packed)] //~ ERROR: E0517 +enum Foo2 {Bar, Baz} //~ NOTE: not a struct -#[repr(u8)] //~ ERROR E0517 - //~| requires an enum -struct Foo3 {bar: bool, baz: bool} +#[repr(u8)] //~ ERROR: E0517 +struct Foo3 {bar: bool, baz: bool} //~ NOTE: not an enum -#[repr(C)] //~ ERROR E0517 - //~| requires a struct, enum or union -impl Foo3 { +#[repr(C)] //~ ERROR: E0517 +impl Foo3 { //~ NOTE: not a struct, enum or union } fn main() { diff --git a/src/test/compile-fail/E0518.rs b/src/test/compile-fail/E0518.rs index f9494e0bcb5..63d40db0049 100644 --- a/src/test/compile-fail/E0518.rs +++ b/src/test/compile-fail/E0518.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[inline(always)] //~ ERROR E0518 - //~| requires a function -struct Foo; +#[inline(always)] //~ ERROR: E0518 +struct Foo; //~ NOTE: not a function -#[inline(never)] //~ ERROR E0518 - //~| requires a function -impl Foo { +#[inline(never)] //~ ERROR: E0518 +impl Foo { //~ NOTE: not a function } fn main() {