mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 08:05:12 +00:00
Add context to E0084, E00517, E0518
Show both the attribute and the item
This commit is contained in:
parent
24840dab0b
commit
dcbedf78a0
@ -47,27 +47,27 @@ struct CheckAttrVisitor<'a> {
|
|||||||
|
|
||||||
impl<'a> CheckAttrVisitor<'a> {
|
impl<'a> CheckAttrVisitor<'a> {
|
||||||
/// Check any attribute.
|
/// 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() {
|
if let Some(name) = attr.name() {
|
||||||
match &*name.as_str() {
|
match &*name.as_str() {
|
||||||
"inline" => self.check_inline(attr, target),
|
"inline" => self.check_inline(attr, item, target),
|
||||||
"repr" => self.check_repr(attr, target),
|
"repr" => self.check_repr(attr, item, target),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if an `#[inline]` is applied to a function.
|
/// 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 {
|
if target != Target::Fn {
|
||||||
struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function")
|
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();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if an `#[repr]` attr is valid.
|
/// 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() {
|
let words = match attr.meta_item_list() {
|
||||||
Some(words) => words,
|
Some(words) => words,
|
||||||
None => {
|
None => {
|
||||||
@ -139,7 +139,7 @@ impl<'a> CheckAttrVisitor<'a> {
|
|||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
struct_span_err!(self.sess, attr.span, E0517, "{}", message)
|
struct_span_err!(self.sess, attr.span, E0517, "{}", message)
|
||||||
.span_label(attr.span, format!("requires {}", label))
|
.span_label(item.span, format!("not {}", label))
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
if conflicting_reprs > 1 {
|
if conflicting_reprs > 1 {
|
||||||
@ -153,7 +153,7 @@ impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
|
|||||||
fn visit_item(&mut self, item: &'a ast::Item) {
|
fn visit_item(&mut self, item: &'a ast::Item) {
|
||||||
let target = Target::from_item(item);
|
let target = Target::from_item(item);
|
||||||
for attr in &item.attrs {
|
for attr in &item.attrs {
|
||||||
self.check_attribute(attr, target);
|
self.check_attribute(attr, item, target);
|
||||||
}
|
}
|
||||||
visit::walk_item(self, item);
|
visit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,7 @@ use std::mem::replace;
|
|||||||
use std::ops::{self, Deref};
|
use std::ops::{self, Deref};
|
||||||
use syntax::abi::Abi;
|
use syntax::abi::Abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::attr;
|
||||||
use syntax::codemap::{self, original_sp, Spanned};
|
use syntax::codemap::{self, original_sp, Spanned};
|
||||||
use syntax::feature_gate::{GateIssue, emit_feature_err};
|
use syntax::feature_gate::{GateIssue, emit_feature_err};
|
||||||
use syntax::ptr::P;
|
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);
|
let def = tcx.adt_def(def_id);
|
||||||
def.destructor(tcx); // force the destructor to be evaluated
|
def.destructor(tcx); // force the destructor to be evaluated
|
||||||
|
|
||||||
if vs.is_empty() && tcx.has_attr(def_id, "repr") {
|
if vs.is_empty() {
|
||||||
struct_span_err!(
|
let attributes = tcx.get_attrs(def_id);
|
||||||
tcx.sess, sp, E0084,
|
if let Some(attr) = attr::find_by_name(&attributes, "repr") {
|
||||||
"unsupported representation for zero-variant enum")
|
struct_span_err!(
|
||||||
.span_label(sp, "unsupported enum representation")
|
tcx.sess, attr.span, E0084,
|
||||||
.emit();
|
"unsupported representation for zero-variant enum")
|
||||||
|
.span_label(sp, "zero-variant enum")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let repr_type_ty = def.repr.discr_type().to_ty(tcx);
|
let repr_type_ty = def.repr.discr_type().to_ty(tcx);
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[repr(i32)]
|
#[repr(i32)] //~ ERROR E0084
|
||||||
enum Foo {}
|
enum Foo {} //~ zero-variant enum
|
||||||
//~^ ERROR E0084
|
|
||||||
//~| unsupported enum representation
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,16 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[repr(C)] //~ ERROR E0517
|
#[repr(C)] //~ ERROR E0517
|
||||||
//~| requires a struct, enum or union
|
type Foo = u8; //~ not a struct, enum or union
|
||||||
type Foo = u8;
|
|
||||||
|
|
||||||
#[repr(packed)] //~ ERROR E0517
|
#[repr(packed)] //~ ERROR E0517
|
||||||
//~| requires a struct
|
enum Foo2 {Bar, Baz} //~ not a struct
|
||||||
enum Foo2 {Bar, Baz}
|
|
||||||
|
|
||||||
#[repr(u8)] //~ ERROR E0517
|
#[repr(u8)] //~ ERROR E0517
|
||||||
//~| requires an enum
|
struct Foo3 {bar: bool, baz: bool} //~ not an enum
|
||||||
struct Foo3 {bar: bool, baz: bool}
|
|
||||||
|
|
||||||
#[repr(C)] //~ ERROR E0517
|
#[repr(C)] //~ ERROR E0517
|
||||||
//~| requires a struct, enum or union
|
impl Foo3 { //~ not a struct, enum or union
|
||||||
impl Foo3 {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -9,12 +9,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[inline(always)] //~ ERROR E0518
|
#[inline(always)] //~ ERROR E0518
|
||||||
//~| requires a function
|
struct Foo; //~ not a function
|
||||||
struct Foo;
|
|
||||||
|
|
||||||
#[inline(never)] //~ ERROR E0518
|
#[inline(never)] //~ ERROR E0518
|
||||||
//~| requires a function
|
impl Foo { //~ not a function
|
||||||
impl Foo {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -14,6 +14,6 @@
|
|||||||
fn f() {}
|
fn f() {}
|
||||||
|
|
||||||
#[inline] //~ ERROR: attribute should be applied to function
|
#[inline] //~ ERROR: attribute should be applied to function
|
||||||
struct S;
|
struct S; //~ not a function
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#![feature(repr_simd)]
|
#![feature(repr_simd)]
|
||||||
|
|
||||||
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
|
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
|
||||||
fn f() {}
|
fn f() {} //~ not a struct, enum or union
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct SExtern(f64, f64);
|
struct SExtern(f64, f64);
|
||||||
@ -25,19 +25,19 @@ struct SPacked(f64, f64);
|
|||||||
struct SSimd(f64, f64);
|
struct SSimd(f64, f64);
|
||||||
|
|
||||||
#[repr(i8)] //~ ERROR: attribute should be applied to enum
|
#[repr(i8)] //~ ERROR: attribute should be applied to enum
|
||||||
struct SInt(f64, f64);
|
struct SInt(f64, f64); //~ not an enum
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
enum EExtern { A, B }
|
enum EExtern { A, B }
|
||||||
|
|
||||||
#[repr(align(8))] //~ ERROR: attribute should be applied to struct
|
#[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
|
#[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
|
#[repr(simd)] //~ ERROR: attribute should be applied to struct
|
||||||
enum ESimd { A, B }
|
enum ESimd { A, B } // not a struct
|
||||||
|
|
||||||
#[repr(i8)]
|
#[repr(i8)]
|
||||||
enum EInt { A, B }
|
enum EInt { A, B }
|
||||||
|
@ -21,17 +21,28 @@
|
|||||||
#[inline = "2100"]
|
#[inline = "2100"]
|
||||||
//~^ ERROR attribute should be applied to function
|
//~^ ERROR attribute should be applied to function
|
||||||
mod inline {
|
mod inline {
|
||||||
mod inner { #![inline="2100"] }
|
//~^ not a function
|
||||||
//~^ ERROR attribute should be applied to 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
|
//~^ 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
|
//~^ 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
|
//~^ ERROR attribute should be applied to function
|
||||||
|
impl S { }
|
||||||
|
//~^ not a function
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user