Skip to content

Commit dcbedf7

Browse files
committed
Add context to E0084, E00517, E0518
Show both the attribute and the item
1 parent 24840da commit dcbedf7

File tree

8 files changed

+49
-42
lines changed

8 files changed

+49
-42
lines changed

src/librustc/hir/check_attr.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,27 +47,27 @@ struct CheckAttrVisitor<'a> {
4747

4848
impl<'a> CheckAttrVisitor<'a> {
4949
/// Check any attribute.
50-
fn check_attribute(&self, attr: &ast::Attribute, target: Target) {
50+
fn check_attribute(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) {
5151
if let Some(name) = attr.name() {
5252
match &*name.as_str() {
53-
"inline" => self.check_inline(attr, target),
54-
"repr" => self.check_repr(attr, target),
53+
"inline" => self.check_inline(attr, item, target),
54+
"repr" => self.check_repr(attr, item, target),
5555
_ => (),
5656
}
5757
}
5858
}
5959

6060
/// Check if an `#[inline]` is applied to a function.
61-
fn check_inline(&self, attr: &ast::Attribute, target: Target) {
61+
fn check_inline(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) {
6262
if target != Target::Fn {
6363
struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function")
64-
.span_label(attr.span, "requires a function")
64+
.span_label(item.span, "not a function")
6565
.emit();
6666
}
6767
}
6868

6969
/// Check if an `#[repr]` attr is valid.
70-
fn check_repr(&self, attr: &ast::Attribute, target: Target) {
70+
fn check_repr(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) {
7171
let words = match attr.meta_item_list() {
7272
Some(words) => words,
7373
None => {
@@ -139,7 +139,7 @@ impl<'a> CheckAttrVisitor<'a> {
139139
_ => continue,
140140
};
141141
struct_span_err!(self.sess, attr.span, E0517, "{}", message)
142-
.span_label(attr.span, format!("requires {}", label))
142+
.span_label(item.span, format!("not {}", label))
143143
.emit();
144144
}
145145
if conflicting_reprs > 1 {
@@ -153,7 +153,7 @@ impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
153153
fn visit_item(&mut self, item: &'a ast::Item) {
154154
let target = Target::from_item(item);
155155
for attr in &item.attrs {
156-
self.check_attribute(attr, target);
156+
self.check_attribute(attr, item, target);
157157
}
158158
visit::walk_item(self, item);
159159
}

src/librustc_typeck/check/mod.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ use std::mem::replace;
117117
use std::ops::{self, Deref};
118118
use syntax::abi::Abi;
119119
use syntax::ast;
120+
use syntax::attr;
120121
use syntax::codemap::{self, original_sp, Spanned};
121122
use syntax::feature_gate::{GateIssue, emit_feature_err};
122123
use syntax::ptr::P;
@@ -1561,12 +1562,15 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
15611562
let def = tcx.adt_def(def_id);
15621563
def.destructor(tcx); // force the destructor to be evaluated
15631564

1564-
if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1565-
struct_span_err!(
1566-
tcx.sess, sp, E0084,
1567-
"unsupported representation for zero-variant enum")
1568-
.span_label(sp, "unsupported enum representation")
1569-
.emit();
1565+
if vs.is_empty() {
1566+
let attributes = tcx.get_attrs(def_id);
1567+
if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1568+
struct_span_err!(
1569+
tcx.sess, attr.span, E0084,
1570+
"unsupported representation for zero-variant enum")
1571+
.span_label(sp, "zero-variant enum")
1572+
.emit();
1573+
}
15701574
}
15711575

15721576
let repr_type_ty = def.repr.discr_type().to_ty(tcx);

src/test/compile-fail/E0084.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[repr(i32)]
12-
enum Foo {}
13-
//~^ ERROR E0084
14-
//~| unsupported enum representation
11+
#[repr(i32)] //~ ERROR E0084
12+
enum Foo {} //~ zero-variant enum
1513

1614
fn main() {
1715
}

src/test/compile-fail/E0517.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,16 @@
99
// except according to those terms.
1010

1111
#[repr(C)] //~ ERROR E0517
12-
//~| requires a struct, enum or union
13-
type Foo = u8;
12+
type Foo = u8; //~ not a struct, enum or union
1413

1514
#[repr(packed)] //~ ERROR E0517
16-
//~| requires a struct
17-
enum Foo2 {Bar, Baz}
15+
enum Foo2 {Bar, Baz} //~ not a struct
1816

1917
#[repr(u8)] //~ ERROR E0517
20-
//~| requires an enum
21-
struct Foo3 {bar: bool, baz: bool}
18+
struct Foo3 {bar: bool, baz: bool} //~ not an enum
2219

2320
#[repr(C)] //~ ERROR E0517
24-
//~| requires a struct, enum or union
25-
impl Foo3 {
21+
impl Foo3 { //~ not a struct, enum or union
2622
}
2723

2824
fn main() {

src/test/compile-fail/E0518.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99
// except according to those terms.
1010

1111
#[inline(always)] //~ ERROR E0518
12-
//~| requires a function
13-
struct Foo;
12+
struct Foo; //~ not a function
1413

1514
#[inline(never)] //~ ERROR E0518
16-
//~| requires a function
17-
impl Foo {
15+
impl Foo { //~ not a function
1816
}
1917

2018
fn main() {

src/test/compile-fail/attr-usage-inline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
fn f() {}
1515

1616
#[inline] //~ ERROR: attribute should be applied to function
17-
struct S;
17+
struct S; //~ not a function
1818

1919
fn main() {}

src/test/compile-fail/attr-usage-repr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#![feature(repr_simd)]
1414

1515
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
16-
fn f() {}
16+
fn f() {} //~ not a struct, enum or union
1717

1818
#[repr(C)]
1919
struct SExtern(f64, f64);
@@ -25,19 +25,19 @@ struct SPacked(f64, f64);
2525
struct SSimd(f64, f64);
2626

2727
#[repr(i8)] //~ ERROR: attribute should be applied to enum
28-
struct SInt(f64, f64);
28+
struct SInt(f64, f64); //~ not an enum
2929

3030
#[repr(C)]
3131
enum EExtern { A, B }
3232

3333
#[repr(align(8))] //~ ERROR: attribute should be applied to struct
34-
enum EAlign { A, B }
34+
enum EAlign { A, B } // not a struct
3535

3636
#[repr(packed)] //~ ERROR: attribute should be applied to struct
37-
enum EPacked { A, B }
37+
enum EPacked { A, B } // not a struct
3838

3939
#[repr(simd)] //~ ERROR: attribute should be applied to struct
40-
enum ESimd { A, B }
40+
enum ESimd { A, B } // not a struct
4141

4242
#[repr(i8)]
4343
enum EInt { A, B }

src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,28 @@
2121
#[inline = "2100"]
2222
//~^ ERROR attribute should be applied to function
2323
mod inline {
24-
mod inner { #![inline="2100"] }
25-
//~^ ERROR attribute should be applied to function
24+
//~^ not a function
25+
mod inner {
26+
//~^ not a function
27+
#![inline="2100"]
28+
//~^ ERROR attribute should be applied to function
29+
}
2630

27-
#[inline = "2100"] fn f() { }
31+
#[inline = "2100"]
32+
fn f() { }
2833

29-
#[inline = "2100"] struct S;
34+
#[inline = "2100"]
3035
//~^ ERROR attribute should be applied to function
36+
struct S;
37+
//~^ not a function
3138

32-
#[inline = "2100"] type T = S;
39+
#[inline = "2100"]
3340
//~^ ERROR attribute should be applied to function
41+
type T = S;
42+
//~^ not a function
3443

35-
#[inline = "2100"] impl S { }
44+
#[inline = "2100"]
3645
//~^ ERROR attribute should be applied to function
46+
impl S { }
47+
//~^ not a function
3748
}

0 commit comments

Comments
 (0)