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 => {
_ => 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 {
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);
}
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;
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);
// 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() {
}
// 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() {
// 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() {
fn f() {}
#[inline] //~ ERROR: attribute should be applied to function
-struct S;
+struct S; //~ not a function
fn main() {}
#![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);
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 }
#[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
}