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 82d59ecfc92..002c003eabf 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..8d0cf20008c 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 {} //~ zero-variant enum fn main() { } diff --git a/src/test/compile-fail/E0517.rs b/src/test/compile-fail/E0517.rs index b79cb2c44af..0de2ec12fa3 100644 --- a/src/test/compile-fail/E0517.rs +++ b/src/test/compile-fail/E0517.rs @@ -9,20 +9,16 @@ // except according to those terms. #[repr(C)] //~ ERROR E0517 - //~| requires a struct, enum or union -type Foo = u8; +type Foo = u8; //~ not a struct, enum or union #[repr(packed)] //~ ERROR E0517 - //~| requires a struct -enum Foo2 {Bar, Baz} +enum Foo2 {Bar, Baz} //~ not a struct #[repr(u8)] //~ ERROR E0517 - //~| requires an enum -struct Foo3 {bar: bool, baz: bool} +struct Foo3 {bar: bool, baz: bool} //~ not an enum #[repr(C)] //~ ERROR E0517 - //~| requires a struct, enum or union -impl Foo3 { +impl Foo3 { //~ 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..8de32bd3b77 100644 --- a/src/test/compile-fail/E0518.rs +++ b/src/test/compile-fail/E0518.rs @@ -9,12 +9,10 @@ // except according to those terms. #[inline(always)] //~ ERROR E0518 - //~| requires a function -struct Foo; +struct Foo; //~ not a function #[inline(never)] //~ ERROR E0518 - //~| requires a function -impl Foo { +impl Foo { //~ not a function } fn main() { diff --git a/src/test/compile-fail/attr-usage-inline.rs b/src/test/compile-fail/attr-usage-inline.rs index c6b9b016331..40edbe86c7b 100644 --- a/src/test/compile-fail/attr-usage-inline.rs +++ b/src/test/compile-fail/attr-usage-inline.rs @@ -14,6 +14,6 @@ fn f() {} #[inline] //~ ERROR: attribute should be applied to function -struct S; +struct S; //~ not a function fn main() {} diff --git a/src/test/compile-fail/attr-usage-repr.rs b/src/test/compile-fail/attr-usage-repr.rs index c0bfd3690c8..5e0259cb229 100644 --- a/src/test/compile-fail/attr-usage-repr.rs +++ b/src/test/compile-fail/attr-usage-repr.rs @@ -13,7 +13,7 @@ #![feature(repr_simd)] #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union -fn f() {} +fn f() {} //~ not a struct, enum or union #[repr(C)] struct SExtern(f64, f64); @@ -25,19 +25,19 @@ struct SPacked(f64, f64); struct SSimd(f64, f64); #[repr(i8)] //~ ERROR: attribute should be applied to enum -struct SInt(f64, f64); +struct SInt(f64, f64); //~ not an enum #[repr(C)] enum EExtern { A, B } #[repr(align(8))] //~ ERROR: attribute should be applied to struct -enum EAlign { A, B } +enum EAlign { A, B } // not a struct #[repr(packed)] //~ ERROR: attribute should be applied to struct -enum EPacked { A, B } +enum EPacked { A, B } // not a struct #[repr(simd)] //~ ERROR: attribute should be applied to struct -enum ESimd { A, B } +enum ESimd { A, B } // not a struct #[repr(i8)] enum EInt { A, B } diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs index 24e77bf60a8..d86eb50c4ae 100644 --- a/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs +++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs @@ -21,17 +21,28 @@ #[inline = "2100"] //~^ ERROR attribute should be applied to function mod inline { - mod inner { #![inline="2100"] } - //~^ ERROR attribute should be applied to function +//~^ not a function + mod inner { + //~^ not a function + #![inline="2100"] + //~^ ERROR attribute should be applied to function + } - #[inline = "2100"] fn f() { } + #[inline = "2100"] + fn f() { } - #[inline = "2100"] struct S; + #[inline = "2100"] //~^ ERROR attribute should be applied to function + struct S; + //~^ not a function - #[inline = "2100"] type T = S; + #[inline = "2100"] //~^ ERROR attribute should be applied to function + type T = S; + //~^ not a function - #[inline = "2100"] impl S { } + #[inline = "2100"] //~^ ERROR attribute should be applied to function + impl S { } + //~^ not a function }