diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2017-11-16 10:05:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-16 10:05:04 +0100 |
| commit | ed64b97d613f32d9f1ba889068c2dd71883b8c87 (patch) | |
| tree | c8955bf0ec23b2142154d6d441b63f410a05139f | |
| parent | 3c1ea047da61fd6b389849492bfcd362bbc6c0d1 (diff) | |
| parent | ead9ac3b51639c71f7d41f89721e0a8bee0136df (diff) | |
Rollup merge of #45984 - ExpHP:attr-error-context, r=estebank
Add context to E0084, E0517, E0518 A small diagnostic enhancement to get my feet wet. Please scrutinize! This modifies errors E0084, E0517, and E0518 to include both the annotation and the annotated item. All of these errors already had labels; I moved the label to the other span, and rephrased it as necessary. Fixes #45886
| -rw-r--r-- | src/librustc/hir/check_attr.rs | 16 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 16 | ||||
| -rw-r--r-- | src/test/compile-fail/E0084.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/E0517.rs | 20 | ||||
| -rw-r--r-- | src/test/compile-fail/E0518.rs | 10 |
5 files changed, 32 insertions, 36 deletions
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() { |
