Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e66913f

Browse files
committed
rustc_layout/abi: error when attribute is applied to the wrong thing
1 parent 9570cac commit e66913f

File tree

8 files changed

+134
-63
lines changed

8 files changed

+134
-63
lines changed

compiler/rustc_passes/messages.ftl

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@
44
-passes_see_issue =
55
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
66
7-
passes_abi =
8-
abi: {$abi}
9-
7+
passes_abi_invalid_attribute =
8+
`#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
109
passes_abi_of =
1110
fn_abi_of({$fn_name}) = {$fn_abi}
1211
13-
passes_align =
14-
align: {$align}
15-
1612
passes_allow_incoherent_impl =
1713
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
1814
.label = the only currently supported targets are inherent methods
@@ -318,9 +314,6 @@ passes_has_incoherent_inherent_impl =
318314
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
319315
.label = only adts, extern types and traits are supported
320316
321-
passes_homogeneous_aggregate =
322-
homogeneous_aggregate: {$homogeneous_aggregate}
323-
324317
passes_ignored_attr =
325318
`#[{$sym}]` is ignored on struct fields and match arms
326319
.warn = {-passes_previously_accepted}
@@ -404,9 +397,18 @@ passes_lang_item_on_incorrect_target =
404397
405398
passes_layout =
406399
layout error: {$layout_error}
407-
400+
passes_layout_abi =
401+
abi: {$abi}
402+
passes_layout_align =
403+
align: {$align}
404+
passes_layout_homogeneous_aggregate =
405+
homogeneous_aggregate: {$homogeneous_aggregate}
406+
passes_layout_invalid_attribute =
407+
`#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
408408
passes_layout_of =
409409
layout_of({$normalized_ty}) = {$ty_layout}
410+
passes_layout_size =
411+
size: {$size}
410412
411413
passes_link =
412414
attribute should be applied to an `extern` block with non-Rust ABI
@@ -662,9 +664,6 @@ passes_should_be_applied_to_trait =
662664
attribute should be applied to a trait
663665
.label = not a trait
664666
665-
passes_size =
666-
size: {$size}
667-
668667
passes_skipping_const_checks = skipping const checks
669668
670669
passes_stability_promotable =

compiler/rustc_passes/src/abi_test.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,41 @@ use rustc_span::source_map::Spanned;
77
use rustc_span::symbol::sym;
88
use rustc_target::abi::call::FnAbi;
99

10-
use crate::errors::{AbiOf, UnrecognizedField};
10+
use crate::errors::{AbiInvalidAttribute, AbiOf, UnrecognizedField};
1111

1212
pub fn test_abi(tcx: TyCtxt<'_>) {
1313
if !tcx.features().rustc_attrs {
1414
// if the `rustc_attrs` feature is not enabled, don't bother testing ABI
1515
return;
1616
}
1717
for id in tcx.hir().items() {
18-
match tcx.def_kind(id.owner_id) {
19-
DefKind::Fn => {
20-
for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
18+
for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
19+
match tcx.def_kind(id.owner_id) {
20+
DefKind::Fn => {
2121
dump_abi_of_fn_item(tcx, id.owner_id.def_id.into(), attr);
2222
}
23-
}
24-
DefKind::TyAlias { .. } => {
25-
for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
23+
DefKind::TyAlias { .. } => {
2624
dump_abi_of_fn_type(tcx, id.owner_id.def_id.into(), attr);
2725
}
26+
_ => {
27+
tcx.sess.emit_err(AbiInvalidAttribute { span: tcx.def_span(id.owner_id) });
28+
}
2829
}
29-
DefKind::Impl { .. } => {
30-
// To find associated functions we need to go into the child items here.
31-
for &id in tcx.associated_item_def_ids(id.owner_id) {
32-
if matches!(tcx.def_kind(id), DefKind::AssocFn) {
33-
for attr in tcx.get_attrs(id, sym::rustc_abi) {
30+
}
31+
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
32+
// To find associated functions we need to go into the child items here.
33+
for &id in tcx.associated_item_def_ids(id.owner_id) {
34+
for attr in tcx.get_attrs(id, sym::rustc_abi) {
35+
match tcx.def_kind(id) {
36+
DefKind::AssocFn => {
3437
dump_abi_of_fn_item(tcx, id, attr);
3538
}
39+
_ => {
40+
tcx.sess.emit_err(AbiInvalidAttribute { span: tcx.def_span(id) });
41+
}
3642
}
3743
}
3844
}
39-
_ => {}
4045
}
4146
}
4247
}

compiler/rustc_passes/src/errors.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -873,32 +873,32 @@ pub struct DuplicateDiagnosticItemInCrate {
873873
}
874874

875875
#[derive(Diagnostic)]
876-
#[diag(passes_abi)]
877-
pub struct Abi {
876+
#[diag(passes_layout_abi)]
877+
pub struct LayoutAbi {
878878
#[primary_span]
879879
pub span: Span,
880880
pub abi: String,
881881
}
882882

883883
#[derive(Diagnostic)]
884-
#[diag(passes_align)]
885-
pub struct Align {
884+
#[diag(passes_layout_align)]
885+
pub struct LayoutAlign {
886886
#[primary_span]
887887
pub span: Span,
888888
pub align: String,
889889
}
890890

891891
#[derive(Diagnostic)]
892-
#[diag(passes_size)]
893-
pub struct Size {
892+
#[diag(passes_layout_size)]
893+
pub struct LayoutSize {
894894
#[primary_span]
895895
pub span: Span,
896896
pub size: String,
897897
}
898898

899899
#[derive(Diagnostic)]
900-
#[diag(passes_homogeneous_aggregate)]
901-
pub struct HomogeneousAggregate {
900+
#[diag(passes_layout_homogeneous_aggregate)]
901+
pub struct LayoutHomogeneousAggregate {
902902
#[primary_span]
903903
pub span: Span,
904904
pub homogeneous_aggregate: String,
@@ -913,6 +913,13 @@ pub struct LayoutOf {
913913
pub ty_layout: String,
914914
}
915915

916+
#[derive(Diagnostic)]
917+
#[diag(passes_layout_invalid_attribute)]
918+
pub struct LayoutInvalidAttribute {
919+
#[primary_span]
920+
pub span: Span,
921+
}
922+
916923
#[derive(Diagnostic)]
917924
#[diag(passes_abi_of)]
918925
pub struct AbiOf {
@@ -922,6 +929,13 @@ pub struct AbiOf {
922929
pub fn_abi: String,
923930
}
924931

932+
#[derive(Diagnostic)]
933+
#[diag(passes_abi_invalid_attribute)]
934+
pub struct AbiInvalidAttribute {
935+
#[primary_span]
936+
pub span: Span,
937+
}
938+
925939
#[derive(Diagnostic)]
926940
#[diag(passes_unrecognized_field)]
927941
pub struct UnrecognizedField {

compiler/rustc_passes/src/layout_test.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,33 @@ use rustc_span::symbol::sym;
88
use rustc_span::Span;
99
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
1010

11-
use crate::errors::{Abi, Align, HomogeneousAggregate, LayoutOf, Size, UnrecognizedField};
11+
use crate::errors::{
12+
LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
13+
LayoutSize, UnrecognizedField,
14+
};
1215

1316
pub fn test_layout(tcx: TyCtxt<'_>) {
1417
if !tcx.features().rustc_attrs {
1518
// if the `rustc_attrs` feature is not enabled, don't bother testing layout
1619
return;
1720
}
1821
for id in tcx.hir().items() {
19-
if matches!(
20-
tcx.def_kind(id.owner_id),
21-
DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union
22-
) {
23-
for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
24-
dump_layout_of(tcx, id.owner_id.def_id, attr);
22+
for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
23+
match tcx.def_kind(id.owner_id) {
24+
DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union => {
25+
dump_layout_of(tcx, id.owner_id.def_id, attr);
26+
}
27+
_ => {
28+
tcx.sess.emit_err(LayoutInvalidAttribute { span: tcx.def_span(id.owner_id) });
29+
}
30+
}
31+
}
32+
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
33+
// To find associated functions we need to go into the child items here.
34+
for &id in tcx.associated_item_def_ids(id.owner_id) {
35+
for _attr in tcx.get_attrs(id, sym::rustc_layout) {
36+
tcx.sess.emit_err(LayoutInvalidAttribute { span: tcx.def_span(id) });
37+
}
2538
}
2639
}
2740
}
@@ -38,28 +51,28 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
3851
for meta_item in meta_items {
3952
match meta_item.name_or_empty() {
4053
sym::abi => {
41-
tcx.sess.emit_err(Abi {
54+
tcx.sess.emit_err(LayoutAbi {
4255
span: tcx.def_span(item_def_id.to_def_id()),
4356
abi: format!("{:?}", ty_layout.abi),
4457
});
4558
}
4659

4760
sym::align => {
48-
tcx.sess.emit_err(Align {
61+
tcx.sess.emit_err(LayoutAlign {
4962
span: tcx.def_span(item_def_id.to_def_id()),
5063
align: format!("{:?}", ty_layout.align),
5164
});
5265
}
5366

5467
sym::size => {
55-
tcx.sess.emit_err(Size {
68+
tcx.sess.emit_err(LayoutSize {
5669
span: tcx.def_span(item_def_id.to_def_id()),
5770
size: format!("{:?}", ty_layout.size),
5871
});
5972
}
6073

6174
sym::homogeneous_aggregate => {
62-
tcx.sess.emit_err(HomogeneousAggregate {
75+
tcx.sess.emit_err(LayoutHomogeneousAggregate {
6376
span: tcx.def_span(item_def_id.to_def_id()),
6477
homogeneous_aggregate: format!(
6578
"{:?}",

tests/ui/abi/debug.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#![feature(rustc_attrs)]
1010
#![crate_type = "lib"]
1111

12+
struct S(u16);
13+
1214
#[rustc_abi(debug)]
1315
fn test(_x: u8) -> bool { true } //~ ERROR: fn_abi
1416

@@ -18,7 +20,14 @@ type TestFnPtr = fn(bool) -> u8; //~ ERROR: fn_abi
1820
#[rustc_abi(debug)]
1921
fn test_generic<T>(_x: *const T) { } //~ ERROR: fn_abi
2022

21-
struct S(u16);
23+
#[rustc_abi(debug)]
24+
const C: () = (); //~ ERROR: can only be applied to
25+
26+
impl S {
27+
#[rustc_abi(debug)]
28+
const C: () = (); //~ ERROR: can only be applied to
29+
}
30+
2231
impl S {
2332
#[rustc_abi(debug)]
2433
fn assoc_test(&self) { } //~ ERROR: fn_abi

tests/ui/abi/debug.stderr

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ error: fn_abi_of(test) = FnAbi {
8787
conv: Rust,
8888
can_unwind: $SOME_BOOL,
8989
}
90-
--> $DIR/debug.rs:13:1
90+
--> $DIR/debug.rs:15:1
9191
|
9292
LL | fn test(_x: u8) -> bool { true }
9393
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
181181
conv: Rust,
182182
can_unwind: $SOME_BOOL,
183183
}
184-
--> $DIR/debug.rs:16:1
184+
--> $DIR/debug.rs:18:1
185185
|
186186
LL | type TestFnPtr = fn(bool) -> u8;
187187
| ^^^^^^^^^^^^^^
@@ -257,11 +257,23 @@ error: fn_abi_of(test_generic) = FnAbi {
257257
conv: Rust,
258258
can_unwind: $SOME_BOOL,
259259
}
260-
--> $DIR/debug.rs:19:1
260+
--> $DIR/debug.rs:21:1
261261
|
262262
LL | fn test_generic<T>(_x: *const T) { }
263263
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
264264

265+
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
266+
--> $DIR/debug.rs:24:1
267+
|
268+
LL | const C: () = ();
269+
| ^^^^^^^^^^^
270+
271+
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
272+
--> $DIR/debug.rs:28:5
273+
|
274+
LL | const C: () = ();
275+
| ^^^^^^^^^^^
276+
265277
error: fn_abi_of(assoc_test) = FnAbi {
266278
args: [
267279
ArgAbi {
@@ -345,10 +357,10 @@ error: fn_abi_of(assoc_test) = FnAbi {
345357
conv: Rust,
346358
can_unwind: $SOME_BOOL,
347359
}
348-
--> $DIR/debug.rs:24:5
360+
--> $DIR/debug.rs:33:5
349361
|
350362
LL | fn assoc_test(&self) { }
351363
| ^^^^^^^^^^^^^^^^^^^^
352364

353-
error: aborting due to 4 previous errors
365+
error: aborting due to 6 previous errors
354366

tests/ui/layout/debug.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type Test = Result<i32, i32>; //~ ERROR: layout_of
1717

1818
#[rustc_layout(debug)]
1919
type T = impl std::fmt::Debug; //~ ERROR: layout_of
20+
fn f() -> T {
21+
0i32
22+
}
2023

2124
#[rustc_layout(debug)]
2225
pub union V { //~ ERROR: layout_of
@@ -63,6 +66,10 @@ union P5 { zst: [u16; 0], byte: u8 } //~ ERROR: layout_of
6366
#[rustc_layout(debug)]
6467
type X = std::mem::MaybeUninit<u8>; //~ ERROR: layout_of
6568

66-
fn f() -> T {
67-
0i32
69+
#[rustc_layout(debug)]
70+
const C: () = (); //~ ERROR: can only be applied to
71+
72+
impl S {
73+
#[rustc_layout(debug)]
74+
const C: () = (); //~ ERROR: can only be applied to
6875
}

0 commit comments

Comments
 (0)