about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-09-02 14:03:25 +0200
committerRalf Jung <post@ralfj.de>2023-09-06 11:11:06 +0200
commite66913f8fefd54a37c0a8b86b27b7b5117360be0 (patch)
tree85e1d9b882440f2077a11559ea108e0b09dfd88f
parent9570cac0199c4da6d4c493a4946d6b715eb437d9 (diff)
downloadrust-e66913f8fefd54a37c0a8b86b27b7b5117360be0.tar.gz
rust-e66913f8fefd54a37c0a8b86b27b7b5117360be0.zip
rustc_layout/abi: error when attribute is applied to the wrong thing
-rw-r--r--compiler/rustc_passes/messages.ftl25
-rw-r--r--compiler/rustc_passes/src/abi_test.rs31
-rw-r--r--compiler/rustc_passes/src/errors.rs30
-rw-r--r--compiler/rustc_passes/src/layout_test.rs35
-rw-r--r--tests/ui/abi/debug.rs11
-rw-r--r--tests/ui/abi/debug.stderr22
-rw-r--r--tests/ui/layout/debug.rs11
-rw-r--r--tests/ui/layout/debug.stderr32
8 files changed, 134 insertions, 63 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index aa7db3348d0..602d614295c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -4,15 +4,11 @@
 -passes_see_issue =
     see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
 
-passes_abi =
-    abi: {$abi}
-
+passes_abi_invalid_attribute =
+    `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
 passes_abi_of =
     fn_abi_of({$fn_name}) = {$fn_abi}
 
-passes_align =
-    align: {$align}
-
 passes_allow_incoherent_impl =
     `rustc_allow_incoherent_impl` attribute should be applied to impl items.
     .label = the only currently supported targets are inherent methods
@@ -318,9 +314,6 @@ passes_has_incoherent_inherent_impl =
     `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
     .label = only adts, extern types and traits are supported
 
-passes_homogeneous_aggregate =
-    homogeneous_aggregate: {$homogeneous_aggregate}
-
 passes_ignored_attr =
     `#[{$sym}]` is ignored on struct fields and match arms
     .warn = {-passes_previously_accepted}
@@ -404,9 +397,18 @@ passes_lang_item_on_incorrect_target =
 
 passes_layout =
     layout error: {$layout_error}
-
+passes_layout_abi =
+    abi: {$abi}
+passes_layout_align =
+    align: {$align}
+passes_layout_homogeneous_aggregate =
+    homogeneous_aggregate: {$homogeneous_aggregate}
+passes_layout_invalid_attribute =
+    `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
 passes_layout_of =
     layout_of({$normalized_ty}) = {$ty_layout}
+passes_layout_size =
+    size: {$size}
 
 passes_link =
     attribute should be applied to an `extern` block with non-Rust ABI
@@ -662,9 +664,6 @@ passes_should_be_applied_to_trait =
     attribute should be applied to a trait
     .label = not a trait
 
-passes_size =
-    size: {$size}
-
 passes_skipping_const_checks = skipping const checks
 
 passes_stability_promotable =
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index aeaa264216d..4653a9c2b39 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -7,7 +7,7 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
 use rustc_target::abi::call::FnAbi;
 
-use crate::errors::{AbiOf, UnrecognizedField};
+use crate::errors::{AbiInvalidAttribute, AbiOf, UnrecognizedField};
 
 pub fn test_abi(tcx: TyCtxt<'_>) {
     if !tcx.features().rustc_attrs {
@@ -15,28 +15,33 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
         return;
     }
     for id in tcx.hir().items() {
-        match tcx.def_kind(id.owner_id) {
-            DefKind::Fn => {
-                for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
+        for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
+            match tcx.def_kind(id.owner_id) {
+                DefKind::Fn => {
                     dump_abi_of_fn_item(tcx, id.owner_id.def_id.into(), attr);
                 }
-            }
-            DefKind::TyAlias { .. } => {
-                for attr in tcx.get_attrs(id.owner_id, sym::rustc_abi) {
+                DefKind::TyAlias { .. } => {
                     dump_abi_of_fn_type(tcx, id.owner_id.def_id.into(), attr);
                 }
+                _ => {
+                    tcx.sess.emit_err(AbiInvalidAttribute { span: tcx.def_span(id.owner_id) });
+                }
             }
-            DefKind::Impl { .. } => {
-                // To find associated functions we need to go into the child items here.
-                for &id in tcx.associated_item_def_ids(id.owner_id) {
-                    if matches!(tcx.def_kind(id), DefKind::AssocFn) {
-                        for attr in tcx.get_attrs(id, sym::rustc_abi) {
+        }
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
+            // To find associated functions we need to go into the child items here.
+            for &id in tcx.associated_item_def_ids(id.owner_id) {
+                for attr in tcx.get_attrs(id, sym::rustc_abi) {
+                    match tcx.def_kind(id) {
+                        DefKind::AssocFn => {
                             dump_abi_of_fn_item(tcx, id, attr);
                         }
+                        _ => {
+                            tcx.sess.emit_err(AbiInvalidAttribute { span: tcx.def_span(id) });
+                        }
                     }
                 }
             }
-            _ => {}
         }
     }
 }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 32dd02a4aa9..de55b5ec2cb 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -873,32 +873,32 @@ pub struct DuplicateDiagnosticItemInCrate {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_abi)]
-pub struct Abi {
+#[diag(passes_layout_abi)]
+pub struct LayoutAbi {
     #[primary_span]
     pub span: Span,
     pub abi: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_align)]
-pub struct Align {
+#[diag(passes_layout_align)]
+pub struct LayoutAlign {
     #[primary_span]
     pub span: Span,
     pub align: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_size)]
-pub struct Size {
+#[diag(passes_layout_size)]
+pub struct LayoutSize {
     #[primary_span]
     pub span: Span,
     pub size: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_homogeneous_aggregate)]
-pub struct HomogeneousAggregate {
+#[diag(passes_layout_homogeneous_aggregate)]
+pub struct LayoutHomogeneousAggregate {
     #[primary_span]
     pub span: Span,
     pub homogeneous_aggregate: String,
@@ -914,6 +914,13 @@ pub struct LayoutOf {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_layout_invalid_attribute)]
+pub struct LayoutInvalidAttribute {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_abi_of)]
 pub struct AbiOf {
     #[primary_span]
@@ -923,6 +930,13 @@ pub struct AbiOf {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_abi_invalid_attribute)]
+pub struct AbiInvalidAttribute {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_unrecognized_field)]
 pub struct UnrecognizedField {
     #[primary_span]
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index d839fee07a6..f3c12e0746d 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -8,7 +8,10 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_target::abi::{HasDataLayout, TargetDataLayout};
 
-use crate::errors::{Abi, Align, HomogeneousAggregate, LayoutOf, Size, UnrecognizedField};
+use crate::errors::{
+    LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
+    LayoutSize, UnrecognizedField,
+};
 
 pub fn test_layout(tcx: TyCtxt<'_>) {
     if !tcx.features().rustc_attrs {
@@ -16,12 +19,22 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
         return;
     }
     for id in tcx.hir().items() {
-        if matches!(
-            tcx.def_kind(id.owner_id),
-            DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union
-        ) {
-            for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
-                dump_layout_of(tcx, id.owner_id.def_id, attr);
+        for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
+            match tcx.def_kind(id.owner_id) {
+                DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union => {
+                    dump_layout_of(tcx, id.owner_id.def_id, attr);
+                }
+                _ => {
+                    tcx.sess.emit_err(LayoutInvalidAttribute { span: tcx.def_span(id.owner_id) });
+                }
+            }
+        }
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
+            // To find associated functions we need to go into the child items here.
+            for &id in tcx.associated_item_def_ids(id.owner_id) {
+                for _attr in tcx.get_attrs(id, sym::rustc_layout) {
+                    tcx.sess.emit_err(LayoutInvalidAttribute { span: tcx.def_span(id) });
+                }
             }
         }
     }
@@ -38,28 +51,28 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
             for meta_item in meta_items {
                 match meta_item.name_or_empty() {
                     sym::abi => {
-                        tcx.sess.emit_err(Abi {
+                        tcx.sess.emit_err(LayoutAbi {
                             span: tcx.def_span(item_def_id.to_def_id()),
                             abi: format!("{:?}", ty_layout.abi),
                         });
                     }
 
                     sym::align => {
-                        tcx.sess.emit_err(Align {
+                        tcx.sess.emit_err(LayoutAlign {
                             span: tcx.def_span(item_def_id.to_def_id()),
                             align: format!("{:?}", ty_layout.align),
                         });
                     }
 
                     sym::size => {
-                        tcx.sess.emit_err(Size {
+                        tcx.sess.emit_err(LayoutSize {
                             span: tcx.def_span(item_def_id.to_def_id()),
                             size: format!("{:?}", ty_layout.size),
                         });
                     }
 
                     sym::homogeneous_aggregate => {
-                        tcx.sess.emit_err(HomogeneousAggregate {
+                        tcx.sess.emit_err(LayoutHomogeneousAggregate {
                             span: tcx.def_span(item_def_id.to_def_id()),
                             homogeneous_aggregate: format!(
                                 "{:?}",
diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs
index 84d08ead08d..8575021494d 100644
--- a/tests/ui/abi/debug.rs
+++ b/tests/ui/abi/debug.rs
@@ -9,6 +9,8 @@
 #![feature(rustc_attrs)]
 #![crate_type = "lib"]
 
+struct S(u16);
+
 #[rustc_abi(debug)]
 fn test(_x: u8) -> bool { true } //~ ERROR: fn_abi
 
@@ -18,7 +20,14 @@ type TestFnPtr = fn(bool) -> u8; //~ ERROR: fn_abi
 #[rustc_abi(debug)]
 fn test_generic<T>(_x: *const T) { } //~ ERROR: fn_abi
 
-struct S(u16);
+#[rustc_abi(debug)]
+const C: () = (); //~ ERROR: can only be applied to
+
+impl S {
+    #[rustc_abi(debug)]
+    const C: () = (); //~ ERROR: can only be applied to
+}
+
 impl S {
     #[rustc_abi(debug)]
     fn assoc_test(&self) { } //~ ERROR: fn_abi
diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr
index dd0cfea351f..2315288c3c7 100644
--- a/tests/ui/abi/debug.stderr
+++ b/tests/ui/abi/debug.stderr
@@ -87,7 +87,7 @@ error: fn_abi_of(test) = FnAbi {
            conv: Rust,
            can_unwind: $SOME_BOOL,
        }
-  --> $DIR/debug.rs:13:1
+  --> $DIR/debug.rs:15:1
    |
 LL | fn test(_x: u8) -> bool { true }
    | ^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
            conv: Rust,
            can_unwind: $SOME_BOOL,
        }
-  --> $DIR/debug.rs:16:1
+  --> $DIR/debug.rs:18:1
    |
 LL | type TestFnPtr = fn(bool) -> u8;
    | ^^^^^^^^^^^^^^
@@ -257,11 +257,23 @@ error: fn_abi_of(test_generic) = FnAbi {
            conv: Rust,
            can_unwind: $SOME_BOOL,
        }
-  --> $DIR/debug.rs:19:1
+  --> $DIR/debug.rs:21:1
    |
 LL | fn test_generic<T>(_x: *const T) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
+  --> $DIR/debug.rs:24:1
+   |
+LL | const C: () = ();
+   | ^^^^^^^^^^^
+
+error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
+  --> $DIR/debug.rs:28:5
+   |
+LL |     const C: () = ();
+   |     ^^^^^^^^^^^
+
 error: fn_abi_of(assoc_test) = FnAbi {
            args: [
                ArgAbi {
@@ -345,10 +357,10 @@ error: fn_abi_of(assoc_test) = FnAbi {
            conv: Rust,
            can_unwind: $SOME_BOOL,
        }
-  --> $DIR/debug.rs:24:5
+  --> $DIR/debug.rs:33:5
    |
 LL |     fn assoc_test(&self) { }
    |     ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs
index b74a8d3b917..97dc73d3aa7 100644
--- a/tests/ui/layout/debug.rs
+++ b/tests/ui/layout/debug.rs
@@ -17,6 +17,9 @@ type Test = Result<i32, i32>; //~ ERROR: layout_of
 
 #[rustc_layout(debug)]
 type T = impl std::fmt::Debug; //~ ERROR: layout_of
+fn f() -> T {
+    0i32
+}
 
 #[rustc_layout(debug)]
 pub union V { //~ ERROR: layout_of
@@ -63,6 +66,10 @@ union P5 { zst: [u16; 0], byte: u8 } //~ ERROR: layout_of
 #[rustc_layout(debug)]
 type X = std::mem::MaybeUninit<u8>; //~ ERROR: layout_of
 
-fn f() -> T {
-    0i32
+#[rustc_layout(debug)]
+const C: () = (); //~ ERROR: can only be applied to
+
+impl S {
+    #[rustc_layout(debug)]
+    const C: () = (); //~ ERROR: can only be applied to
 }
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index c20a0198ccb..0973043c678 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -344,7 +344,7 @@ error: layout_of(V) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
        }
-  --> $DIR/debug.rs:22:1
+  --> $DIR/debug.rs:25:1
    |
 LL | pub union V {
    | ^^^^^^^^^^^
@@ -368,7 +368,7 @@ error: layout_of(W) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
        }
-  --> $DIR/debug.rs:28:1
+  --> $DIR/debug.rs:31:1
    |
 LL | pub union W {
    | ^^^^^^^^^^^
@@ -392,7 +392,7 @@ error: layout_of(Y) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(2 bytes),
        }
-  --> $DIR/debug.rs:34:1
+  --> $DIR/debug.rs:37:1
    |
 LL | pub union Y {
    | ^^^^^^^^^^^
@@ -416,7 +416,7 @@ error: layout_of(P1) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:41:1
+  --> $DIR/debug.rs:44:1
    |
 LL | union P1 { x: u32 }
    | ^^^^^^^^
@@ -440,7 +440,7 @@ error: layout_of(P2) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:45:1
+  --> $DIR/debug.rs:48:1
    |
 LL | union P2 { x: (u32, u32) }
    | ^^^^^^^^
@@ -464,7 +464,7 @@ error: layout_of(P3) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:53:1
+  --> $DIR/debug.rs:56:1
    |
 LL | union P3 { x: F32x4 }
    | ^^^^^^^^
@@ -488,7 +488,7 @@ error: layout_of(P4) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:57:1
+  --> $DIR/debug.rs:60:1
    |
 LL | union P4 { x: E }
    | ^^^^^^^^
@@ -517,7 +517,7 @@ error: layout_of(P5) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:61:1
+  --> $DIR/debug.rs:64:1
    |
 LL | union P5 { zst: [u16; 0], byte: u8 }
    | ^^^^^^^^
@@ -546,10 +546,22 @@ error: layout_of(std::mem::MaybeUninit<u8>) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(1 bytes),
        }
-  --> $DIR/debug.rs:64:1
+  --> $DIR/debug.rs:67:1
    |
 LL | type X = std::mem::MaybeUninit<u8>;
    | ^^^^^^
 
-error: aborting due to 14 previous errors
+error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
+  --> $DIR/debug.rs:70:1
+   |
+LL | const C: () = ();
+   | ^^^^^^^^^^^
+
+error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
+  --> $DIR/debug.rs:74:5
+   |
+LL |     const C: () = ();
+   |     ^^^^^^^^^^^
+
+error: aborting due to 16 previous errors