about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-07-07 03:26:05 +0200
committerGitHub <noreply@github.com>2025-07-07 03:26:05 +0200
commitd748e70fead45b1c4ee9fdec84eb79ac8f09733e (patch)
tree0986c9bd1f35a73d6d363f623cff4325b94e7921
parenta84ab0ce6c4557a2f01a3a6c3fdb0f92098db78d (diff)
parent8f86c4abec54ecc06b469fff2cccf0a4182db41d (diff)
downloadrust-d748e70fead45b1c4ee9fdec84eb79ac8f09733e.tar.gz
rust-d748e70fead45b1c4ee9fdec84eb79ac8f09733e.zip
Rollup merge of #143206 - Jules-Bertholet:align-attr-fixes, r=workingjubilee
Align attr fixes

- Remove references to the superseded `repr(align)` syntax
- Allow the attribute on fn items in `extern` blocks
- Test attribute in combination with `async fn` and `dyn`

r? workingjubilee

Tracking issue: https://github.com/rust-lang/rust/issues/82232
`@rustbot` label A-attributes F-fn_align T-compiler
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs10
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs7
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--tests/assembly/naked-functions/wasm32.rs10
-rw-r--r--tests/codegen/align-fn.rs23
-rw-r--r--tests/codegen/min-function-alignment.rs1
-rw-r--r--tests/codegen/naked-fn/aligned.rs1
-rw-r--r--tests/codegen/naked-fn/min-function-alignment.rs1
-rw-r--r--tests/ui/attributes/fn-align-dyn.rs16
-rw-r--r--tests/ui/attributes/malformed-fn-align.rs24
-rw-r--r--tests/ui/attributes/malformed-fn-align.stderr60
12 files changed, 144 insertions, 22 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index be63bb8ac59..ff454427871 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -4,7 +4,7 @@ use rustc_abi::{Align, ExternAbi};
 use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
 use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
 use rustc_attr_data_structures::{
-    AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, UsedBy, find_attr,
+    AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, UsedBy, find_attr,
 };
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
@@ -109,14 +109,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
 
         if let hir::Attribute::Parsed(p) = attr {
             match p {
-                AttributeKind::Repr { reprs, first_span: _ } => {
-                    codegen_fn_attrs.alignment = reprs
-                        .iter()
-                        .filter_map(
-                            |(r, _)| if let ReprAttr::ReprAlign(x) = r { Some(*x) } else { None },
-                        )
-                        .max();
-                }
                 AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
                 AttributeKind::ExportName { name, .. } => {
                     codegen_fn_attrs.export_name = Some(*name);
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 5a94d01e088..46c21dcf67b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -13,6 +13,10 @@ passes_abi_ne =
 passes_abi_of =
     fn_abi_of({$fn_name}) = {$fn_abi}
 
+passes_align_attr_application =
+    `#[align(...)]` should be applied to a function item
+    .label = not a function item
+
 passes_align_should_be_repr_align =
     `#[align(...)]` is not supported on {$item} items
     .suggestion = use `#[repr(align(...))]` instead
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 3fa5cdc36bc..b8f1ec7ca93 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1915,7 +1915,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     /// Checks if the `#[align]` attributes on `item` are valid.
     fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
         match target {
-            Target::Fn | Target::Method(_) => {}
+            Target::Fn | Target::Method(_) | Target::ForeignFn => {}
             Target::Struct | Target::Union | Target::Enum => {
                 self.dcx().emit_err(errors::AlignShouldBeReprAlign {
                     span: repr_span,
@@ -1924,10 +1924,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 });
             }
             _ => {
-                self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
-                    hint_span: repr_span,
-                    span,
-                });
+                self.dcx().emit_err(errors::AlignAttrApplication { hint_span: repr_span, span });
             }
         }
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 3ede3c889c8..4ad615a2abf 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1838,3 +1838,12 @@ pub(crate) struct AlignShouldBeReprAlign {
     pub item: &'static str,
     pub align_bytes: u64,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes_align_attr_application)]
+pub(crate) struct AlignAttrApplication {
+    #[primary_span]
+    pub hint_span: Span,
+    #[label]
+    pub span: Span,
+}
diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs
index 5f114246ad5..77547e82041 100644
--- a/tests/assembly/naked-functions/wasm32.rs
+++ b/tests/assembly/naked-functions/wasm32.rs
@@ -27,18 +27,16 @@ extern "C" fn nop() {
     naked_asm!("nop")
 }
 
-// CHECK: .section  .text.weak_aligned_nop,"",@
-// CHECK: .weak weak_aligned_nop
+// CHECK: .section  .text.weak_nop,"",@
+// CHECK: .weak weak_nop
 // CHECK-LABEL: nop:
-// CHECK: .functype weak_aligned_nop () -> ()
+// CHECK: .functype weak_nop () -> ()
 // CHECK-NOT: .size
 // CHECK: end_function
 #[no_mangle]
 #[unsafe(naked)]
 #[linkage = "weak"]
-// wasm functions cannot be aligned, so this has no effect
-#[align(32)]
-extern "C" fn weak_aligned_nop() {
+extern "C" fn weak_nop() {
     naked_asm!("nop")
 }
 
diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs
index 90073ff3081..fd572910c28 100644
--- a/tests/codegen/align-fn.rs
+++ b/tests/codegen/align-fn.rs
@@ -1,4 +1,6 @@
 //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code
+//@ edition: 2024
+//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368)
 
 #![crate_type = "lib"]
 #![feature(fn_align)]
@@ -116,3 +118,24 @@ pub fn align_specified_twice_2() {}
 #[align(32)]
 #[align(256)]
 pub fn align_specified_twice_3() {}
+
+const _: () = {
+    // CHECK-LABEL: align_unmangled
+    // CHECK-SAME: align 256
+    #[unsafe(no_mangle)]
+    #[align(32)]
+    #[align(256)]
+    extern "C" fn align_unmangled() {}
+};
+
+unsafe extern "C" {
+    #[align(256)]
+    fn align_unmangled();
+}
+
+// FIXME also check `gen` et al
+// CHECK-LABEL: async_align
+// CHECK-SAME: align 64
+#[unsafe(no_mangle)]
+#[align(64)]
+pub async fn async_align() {}
diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs
index 78989ec5df2..6a3843b0f4f 100644
--- a/tests/codegen/min-function-alignment.rs
+++ b/tests/codegen/min-function-alignment.rs
@@ -2,6 +2,7 @@
 //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code
 //@ [align16] compile-flags: -Zmin-function-alignment=16
 //@ [align1024] compile-flags: -Zmin-function-alignment=1024
+//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368)
 
 #![crate_type = "lib"]
 #![feature(fn_align)]
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index f9fce8e5a5d..2648b0213ca 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -1,6 +1,7 @@
 //@ compile-flags: -C no-prepopulate-passes -Copt-level=0
 //@ needs-asm-support
 //@ ignore-arm no "ret" mnemonic
+//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368)
 
 #![crate_type = "lib"]
 #![feature(fn_align)]
diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs
index 59554c1cae5..4ebaacd3eff 100644
--- a/tests/codegen/naked-fn/min-function-alignment.rs
+++ b/tests/codegen/naked-fn/min-function-alignment.rs
@@ -1,6 +1,7 @@
 //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16
 //@ needs-asm-support
 //@ ignore-arm no "ret" mnemonic
+//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368)
 
 #![feature(fn_align)]
 #![crate_type = "lib"]
diff --git a/tests/ui/attributes/fn-align-dyn.rs b/tests/ui/attributes/fn-align-dyn.rs
new file mode 100644
index 00000000000..8ba4d5e2897
--- /dev/null
+++ b/tests/ui/attributes/fn-align-dyn.rs
@@ -0,0 +1,16 @@
+//@ run-pass
+//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368)
+#![feature(fn_align)]
+
+trait Test {
+    #[align(4096)]
+    fn foo(&self);
+
+    #[align(4096)]
+    fn foo1(&self);
+}
+
+fn main() {
+    assert_eq!((<dyn Test>::foo as fn(_) as usize & !1) % 4096, 0);
+    assert_eq!((<dyn Test>::foo1 as fn(_) as usize & !1) % 4096, 0);
+}
diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs
index f5ab9555e56..e06e6116842 100644
--- a/tests/ui/attributes/malformed-fn-align.rs
+++ b/tests/ui/attributes/malformed-fn-align.rs
@@ -21,5 +21,29 @@ fn f3() {}
 #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items
 fn f4() {}
 
+#[align(-1)] //~ ERROR expected unsuffixed literal, found `-`
+fn f5() {}
+
+#[align(3)] //~ ERROR invalid alignment value: not a power of two
+fn f6() {}
+
+#[align(4usize)] //~ ERROR invalid alignment value: not an unsuffixed integer [E0589]
+//~^ ERROR suffixed literals are not allowed in attributes
+fn f7() {}
+
+#[align(16)]
+#[align(3)] //~ ERROR invalid alignment value: not a power of two
+#[align(16)]
+fn f8() {}
+
 #[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items
 struct S1;
+
+#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item
+const FOO: i32 = 42;
+
+#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item
+mod test {}
+
+#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item
+use ::std::iter;
diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr
index b769d0b457d..af3625b1f3b 100644
--- a/tests/ui/attributes/malformed-fn-align.stderr
+++ b/tests/ui/attributes/malformed-fn-align.stderr
@@ -1,3 +1,17 @@
+error: expected unsuffixed literal, found `-`
+  --> $DIR/malformed-fn-align.rs:24:9
+   |
+LL | #[align(-1)]
+   |         ^
+
+error: suffixed literals are not allowed in attributes
+  --> $DIR/malformed-fn-align.rs:30:9
+   |
+LL | #[align(4usize)]
+   |         ^^^^^^
+   |
+   = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
 error[E0539]: malformed `align` attribute input
   --> $DIR/malformed-fn-align.rs:5:5
    |
@@ -37,6 +51,24 @@ error[E0589]: invalid alignment value: not a power of two
 LL | #[align(0)]
    |         ^
 
+error[E0589]: invalid alignment value: not a power of two
+  --> $DIR/malformed-fn-align.rs:27:9
+   |
+LL | #[align(3)]
+   |         ^
+
+error[E0589]: invalid alignment value: not an unsuffixed integer
+  --> $DIR/malformed-fn-align.rs:30:9
+   |
+LL | #[align(4usize)]
+   |         ^^^^^^
+
+error[E0589]: invalid alignment value: not a power of two
+  --> $DIR/malformed-fn-align.rs:35:9
+   |
+LL | #[align(3)]
+   |         ^
+
 error: `#[repr(align(...))]` is not supported on function items
   --> $DIR/malformed-fn-align.rs:21:8
    |
@@ -50,7 +82,7 @@ LL | #[repr(align(16))]
    |        ^^^^^^^^^
 
 error: `#[align(...)]` is not supported on struct items
-  --> $DIR/malformed-fn-align.rs:24:1
+  --> $DIR/malformed-fn-align.rs:39:1
    |
 LL | #[align(16)]
    | ^^^^^^^^^^^^
@@ -61,7 +93,31 @@ LL - #[align(16)]
 LL + #[repr(align(16))]
    |
 
-error: aborting due to 7 previous errors
+error: `#[align(...)]` should be applied to a function item
+  --> $DIR/malformed-fn-align.rs:42:1
+   |
+LL | #[align(32)]
+   | ^^^^^^^^^^^^
+LL | const FOO: i32 = 42;
+   | -------------------- not a function item
+
+error: `#[align(...)]` should be applied to a function item
+  --> $DIR/malformed-fn-align.rs:45:1
+   |
+LL | #[align(32)]
+   | ^^^^^^^^^^^^
+LL | mod test {}
+   | ----------- not a function item
+
+error: `#[align(...)]` should be applied to a function item
+  --> $DIR/malformed-fn-align.rs:48:1
+   |
+LL | #[align(32)]
+   | ^^^^^^^^^^^^
+LL | use ::std::iter;
+   | ---------------- not a function item
+
+error: aborting due to 15 previous errors
 
 Some errors have detailed explanations: E0539, E0589, E0805.
 For more information about an error, try `rustc --explain E0539`.