Skip to content

Commit 57e8fc5

Browse files
committed
passes: check_attr on more targets
This commit modifies `check_attr` so that: - Enum variants are now checked (some attributes would not have been prohibited on variants previously). - `check_expr_attributes` and `check_stmt_attributes` are removed as `check_attributes` can perform the same checks. Signed-off-by: David Wood <[email protected]>
1 parent 96555ba commit 57e8fc5

20 files changed

+114
-131
lines changed

compiler/rustc_passes/src/check_attr.rs

+33-58
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl CheckAttrVisitor<'tcx> {
9494
return;
9595
}
9696

97-
if matches!(target, Target::Fn | Target::Method(_) | Target::ForeignFn) {
97+
if matches!(target, Target::Closure | Target::Fn | Target::Method(_) | Target::ForeignFn) {
9898
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
9999
}
100100

@@ -185,7 +185,7 @@ impl CheckAttrVisitor<'tcx> {
185185
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
186186
fn check_non_exhaustive(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
187187
match target {
188-
Target::Struct | Target::Enum => true,
188+
Target::Struct | Target::Enum | Target::Variant => true,
189189
_ => {
190190
struct_span_err!(
191191
self.tcx.sess,
@@ -470,6 +470,9 @@ impl CheckAttrVisitor<'tcx> {
470470

471471
for hint in &hints {
472472
let (article, allowed_targets) = match hint.name_or_empty() {
473+
_ if !matches!(target, Target::Struct | Target::Enum | Target::Union) => {
474+
("a", "struct, enum, or union")
475+
}
473476
name @ sym::C | name @ sym::align => {
474477
is_c |= name == sym::C;
475478
match target {
@@ -535,12 +538,16 @@ impl CheckAttrVisitor<'tcx> {
535538
}
536539
_ => continue,
537540
};
538-
self.emit_repr_error(
541+
542+
struct_span_err!(
543+
self.tcx.sess,
539544
hint.span(),
540-
*span,
541-
&format!("attribute should be applied to {}", allowed_targets),
542-
&format!("not {} {}", article, allowed_targets),
545+
E0517,
546+
"{}",
547+
&format!("attribute should be applied to {} {}", article, allowed_targets)
543548
)
549+
.span_label(*span, &format!("not {} {}", article, allowed_targets))
550+
.emit();
544551
}
545552

546553
// Just point at all repr hints if there are any incompatibilities.
@@ -579,56 +586,6 @@ impl CheckAttrVisitor<'tcx> {
579586
}
580587
}
581588

582-
fn emit_repr_error(
583-
&self,
584-
hint_span: Span,
585-
label_span: Span,
586-
hint_message: &str,
587-
label_message: &str,
588-
) {
589-
struct_span_err!(self.tcx.sess, hint_span, E0517, "{}", hint_message)
590-
.span_label(label_span, label_message)
591-
.emit();
592-
}
593-
594-
fn check_stmt_attributes(&self, stmt: &hir::Stmt<'_>) {
595-
// When checking statements ignore expressions, they will be checked later
596-
if let hir::StmtKind::Local(ref l) = stmt.kind {
597-
self.check_attributes(l.hir_id, &l.attrs, &stmt.span, Target::Statement, None);
598-
for attr in l.attrs.iter() {
599-
if self.tcx.sess.check_name(attr, sym::repr) {
600-
self.emit_repr_error(
601-
attr.span,
602-
stmt.span,
603-
"attribute should not be applied to a statement",
604-
"not a struct, enum, or union",
605-
);
606-
}
607-
}
608-
}
609-
}
610-
611-
fn check_expr_attributes(&self, expr: &hir::Expr<'_>) {
612-
let target = match expr.kind {
613-
hir::ExprKind::Closure(..) => Target::Closure,
614-
_ => Target::Expression,
615-
};
616-
self.check_attributes(expr.hir_id, &expr.attrs, &expr.span, target, None);
617-
for attr in expr.attrs.iter() {
618-
if self.tcx.sess.check_name(attr, sym::repr) {
619-
self.emit_repr_error(
620-
attr.span,
621-
expr.span,
622-
"attribute should not be applied to an expression",
623-
"not defining a struct, enum, or union",
624-
);
625-
}
626-
}
627-
if target == Target::Closure {
628-
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(expr.hir_id));
629-
}
630-
}
631-
632589
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {
633590
for attr in attrs {
634591
if self.tcx.sess.check_name(attr, sym::used) && target != Target::Static {
@@ -672,14 +629,32 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
672629
}
673630

674631
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
675-
self.check_stmt_attributes(stmt);
632+
// When checking statements ignore expressions, they will be checked later.
633+
if let hir::StmtKind::Local(ref l) = stmt.kind {
634+
self.check_attributes(l.hir_id, &l.attrs, &stmt.span, Target::Statement, None);
635+
}
676636
intravisit::walk_stmt(self, stmt)
677637
}
678638

679639
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
680-
self.check_expr_attributes(expr);
640+
let target = match expr.kind {
641+
hir::ExprKind::Closure(..) => Target::Closure,
642+
_ => Target::Expression,
643+
};
644+
645+
self.check_attributes(expr.hir_id, &expr.attrs, &expr.span, target, None);
681646
intravisit::walk_expr(self, expr)
682647
}
648+
649+
fn visit_variant(
650+
&mut self,
651+
variant: &'tcx hir::Variant<'tcx>,
652+
generics: &'tcx hir::Generics<'tcx>,
653+
item_id: HirId,
654+
) {
655+
self.check_attributes(variant.id, variant.attrs, &variant.span, Target::Variant, None);
656+
intravisit::walk_variant(self, variant, generics, item_id)
657+
}
683658
}
684659

685660
fn is_c_like_enum(item: &Item<'_>) -> bool {

src/test/ui/attr-usage-repr.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![feature(repr_simd)]
22

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

66
#[repr(C)]
@@ -12,7 +12,7 @@ struct SPacked(f64, f64);
1212
#[repr(simd)]
1313
struct SSimd(f64, f64);
1414

15-
#[repr(i8)] //~ ERROR: attribute should be applied to enum
15+
#[repr(i8)] //~ ERROR: attribute should be applied to an enum
1616
struct SInt(f64, f64);
1717

1818
#[repr(C)]
@@ -21,10 +21,10 @@ enum EExtern { A, B }
2121
#[repr(align(8))]
2222
enum EAlign { A, B }
2323

24-
#[repr(packed)] //~ ERROR: attribute should be applied to struct
24+
#[repr(packed)] //~ ERROR: attribute should be applied to a struct
2525
enum EPacked { A, B }
2626

27-
#[repr(simd)] //~ ERROR: attribute should be applied to struct
27+
#[repr(simd)] //~ ERROR: attribute should be applied to a struct
2828
enum ESimd { A, B }
2929

3030
#[repr(i8)]

src/test/ui/attr-usage-repr.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
error[E0517]: attribute should be applied to struct, enum, or union
1+
error[E0517]: attribute should be applied to a struct, enum, or union
22
--> $DIR/attr-usage-repr.rs:3:8
33
|
44
LL | #[repr(C)]
55
| ^
66
LL | fn f() {}
77
| --------- not a struct, enum, or union
88

9-
error[E0517]: attribute should be applied to enum
9+
error[E0517]: attribute should be applied to an enum
1010
--> $DIR/attr-usage-repr.rs:15:8
1111
|
1212
LL | #[repr(i8)]
1313
| ^^
1414
LL | struct SInt(f64, f64);
1515
| ---------------------- not an enum
1616

17-
error[E0517]: attribute should be applied to struct or union
17+
error[E0517]: attribute should be applied to a struct or union
1818
--> $DIR/attr-usage-repr.rs:24:8
1919
|
2020
LL | #[repr(packed)]
2121
| ^^^^^^
2222
LL | enum EPacked { A, B }
2323
| --------------------- not a struct or union
2424

25-
error[E0517]: attribute should be applied to struct
25+
error[E0517]: attribute should be applied to a struct
2626
--> $DIR/attr-usage-repr.rs:27:8
2727
|
2828
LL | #[repr(simd)]

src/test/ui/error-codes/E0517.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
error[E0517]: attribute should be applied to struct, enum, or union
1+
error[E0517]: attribute should be applied to a struct, enum, or union
22
--> $DIR/E0517.rs:1:8
33
|
44
LL | #[repr(C)]
55
| ^
66
LL | type Foo = u8;
77
| -------------- not a struct, enum, or union
88

9-
error[E0517]: attribute should be applied to struct or union
9+
error[E0517]: attribute should be applied to a struct or union
1010
--> $DIR/E0517.rs:4:8
1111
|
1212
LL | #[repr(packed)]
1313
| ^^^^^^
1414
LL | enum Foo2 {Bar, Baz}
1515
| -------------------- not a struct or union
1616

17-
error[E0517]: attribute should be applied to enum
17+
error[E0517]: attribute should be applied to an enum
1818
--> $DIR/E0517.rs:7:8
1919
|
2020
LL | #[repr(u8)]
2121
| ^^
2222
LL | struct Foo3 {bar: bool, baz: bool}
2323
| ---------------------------------- not an enum
2424

25-
error[E0517]: attribute should be applied to struct, enum, or union
25+
error[E0517]: attribute should be applied to a struct, enum, or union
2626
--> $DIR/E0517.rs:10:8
2727
|
2828
LL | #[repr(C)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
enum Foo {
2+
#[inline]
3+
//~^ ERROR attribute should be applied
4+
Variant,
5+
}
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0518]: attribute should be applied to function or closure
2+
--> $DIR/inline-disallow-on-variant.rs:2:5
3+
|
4+
LL | #[inline]
5+
| ^^^^^^^^^
6+
LL |
7+
LL | Variant,
8+
| ------- not a function or closure
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0518`.

src/test/ui/issues/issue-31769.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fn main() {
22
#[inline] struct Foo; //~ ERROR attribute should be applied to function or closure
3-
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum, or union
3+
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to a struct, enum, or union
44
}

src/test/ui/issues/issue-31769.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0518]: attribute should be applied to function or closure
44
LL | #[inline] struct Foo;
55
| ^^^^^^^^^ ----------- not a function or closure
66

7-
error[E0517]: attribute should be applied to struct, enum, or union
7+
error[E0517]: attribute should be applied to a struct, enum, or union
88
--> $DIR/issue-31769.rs:3:12
99
|
1010
LL | #[repr(C)] fn foo() {}

src/test/ui/issues/issue-43988.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,17 @@ fn main() {
1313

1414
#[repr(nothing)]
1515
let _x = 0;
16-
//~^^ ERROR attribute should not be applied to a statement
16+
//~^^ ERROR attribute should be applied to a struct, enum, or union
1717

1818
#[repr(something_not_real)]
1919
loop {
2020
()
2121
};
22-
//~^^^^ ERROR attribute should not be applied to an expression
22+
//~^^^^ ERROR attribute should be applied to a struct, enum, or union
2323

2424
#[repr]
2525
let _y = "123";
26-
//~^^ ERROR attribute should not be applied to a statement
27-
//~| ERROR malformed `repr` attribute
26+
//~^^ ERROR malformed `repr` attribute
2827

2928
fn foo() {}
3029

@@ -33,6 +32,5 @@ fn main() {
3332
//~^^ ERROR attribute should be applied to function or closure
3433

3534
let _z = #[repr] 1;
36-
//~^ ERROR attribute should not be applied to an expression
37-
//~| ERROR malformed `repr` attribute
35+
//~^ ERROR malformed `repr` attribute
3836
}

src/test/ui/issues/issue-43988.stderr

+10-24
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | #[repr]
55
| ^^^^^^^ help: must be of the form: `#[repr(C)]`
66

77
error: malformed `repr` attribute input
8-
--> $DIR/issue-43988.rs:35:14
8+
--> $DIR/issue-43988.rs:34:14
99
|
1010
LL | let _z = #[repr] 1;
1111
| ^^^^^^^ help: must be of the form: `#[repr(C)]`
@@ -26,47 +26,33 @@ LL | #[inline(XYZ)]
2626
LL | let _b = 4;
2727
| ----------- not a function or closure
2828

29-
error[E0517]: attribute should not be applied to a statement
30-
--> $DIR/issue-43988.rs:14:5
29+
error[E0517]: attribute should be applied to a struct, enum, or union
30+
--> $DIR/issue-43988.rs:14:12
3131
|
3232
LL | #[repr(nothing)]
33-
| ^^^^^^^^^^^^^^^^
33+
| ^^^^^^^
3434
LL | let _x = 0;
3535
| ----------- not a struct, enum, or union
3636

37-
error[E0517]: attribute should not be applied to an expression
38-
--> $DIR/issue-43988.rs:18:5
37+
error[E0517]: attribute should be applied to a struct, enum, or union
38+
--> $DIR/issue-43988.rs:18:12
3939
|
4040
LL | #[repr(something_not_real)]
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
| ^^^^^^^^^^^^^^^^^^
4242
LL | / loop {
4343
LL | | ()
4444
LL | | };
45-
| |_____- not defining a struct, enum, or union
46-
47-
error[E0517]: attribute should not be applied to a statement
48-
--> $DIR/issue-43988.rs:24:5
49-
|
50-
LL | #[repr]
51-
| ^^^^^^^
52-
LL | let _y = "123";
53-
| --------------- not a struct, enum, or union
45+
| |_____- not a struct, enum, or union
5446

5547
error[E0518]: attribute should be applied to function or closure
56-
--> $DIR/issue-43988.rs:31:5
48+
--> $DIR/issue-43988.rs:30:5
5749
|
5850
LL | #[inline(ABC)]
5951
| ^^^^^^^^^^^^^^
6052
LL | foo();
6153
| ----- not a function or closure
6254

63-
error[E0517]: attribute should not be applied to an expression
64-
--> $DIR/issue-43988.rs:35:14
65-
|
66-
LL | let _z = #[repr] 1;
67-
| ^^^^^^^ - not defining a struct, enum, or union
68-
69-
error: aborting due to 9 previous errors
55+
error: aborting due to 7 previous errors
7056

7157
Some errors have detailed explanations: E0517, E0518.
7258
For more information about an error, try `rustc --explain E0517`.

src/test/ui/issues/issue-74082.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![allow(dead_code)]
22

3-
#[repr(i128)] //~ ERROR: attribute should be applied to enum
3+
#[repr(i128)] //~ ERROR: attribute should be applied to an enum
44
struct Foo;
55

6-
#[repr(u128)] //~ ERROR: attribute should be applied to enum
6+
#[repr(u128)] //~ ERROR: attribute should be applied to an enum
77
struct Bar;
88

99
fn main() {}

src/test/ui/issues/issue-74082.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0517]: attribute should be applied to enum
1+
error[E0517]: attribute should be applied to an enum
22
--> $DIR/issue-74082.rs:3:8
33
|
44
LL | #[repr(i128)]
55
| ^^^^
66
LL | struct Foo;
77
| ----------- not an enum
88

9-
error[E0517]: attribute should be applied to enum
9+
error[E0517]: attribute should be applied to an enum
1010
--> $DIR/issue-74082.rs:6:8
1111
|
1212
LL | #[repr(u128)]

0 commit comments

Comments
 (0)