Mitigate #[align] name resolution ambiguity regression with a rename

From `#[align]` -> `#[rustc_align]`. Attributes starting with `rustc`
are always perma-unstable and feature-gated by `feature(rustc_attrs)`.

See regression RUST-143834.

For the underlying problem where even introducing new feature-gated
unstable built-in attributes can break user code such as

```rs
macro_rules! align {
    () => {
        /* .. */
    };
}

pub(crate) use align; // `use` here becomes ambiguous
```

refer to RUST-134963.

Since the `#[align]` attribute is still feature-gated by
`feature(fn_align)`, we can rename it as a mitigation. Note that
`#[rustc_align]` will obviously mean that current unstable user code
using `feature(fn_aling)` will need additionally `feature(rustc_attrs)`,
but this is a short-term mitigation to buy time, and is expected to be
changed to a better name with less collision potential.

See
<https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202025-07-17/near/529290371>
where mitigation options were considered.

(cherry picked from commit 69b71e4410)
This commit is contained in:
Jieyou Xu
2025-07-18 00:10:46 +08:00
committed by Josh Stone
parent 43056c1614
commit 2e832047c6
21 changed files with 126 additions and 116 deletions
@@ -184,6 +184,7 @@ pub fn is_since_rustc_version(&self) -> bool {
pub enum AttributeKind {
// tidy-alphabetical-start
/// Represents `#[align(N)]`.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
Align { align: Align, span: Span },
/// Represents `#[rustc_allow_const_fn_unstable]`.
@@ -273,7 +273,7 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
pub(crate) struct AlignParser(Option<(Align, Span)>);
impl AlignParser {
const PATH: &'static [Symbol] = &[sym::align];
const PATH: &'static [Symbol] = &[sym::rustc_align];
const TEMPLATE: AttributeTemplate = template!(List: "<alignment in bytes>");
fn parse<'c, S: Stage>(
+2 -1
View File
@@ -495,7 +495,8 @@ pub struct BuiltinAttribute {
),
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
gated!(rustc_align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
@@ -48,6 +48,7 @@ pub struct CodegenFnAttrs {
/// switching between multiple instruction sets.
pub instruction_set: Option<InstructionSetAttr>,
/// The `#[align(...)]` attribute. Determines the alignment of the function body.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
pub alignment: Option<Align>,
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
/// the function entry.
+2 -1
View File
@@ -289,7 +289,8 @@ fn emit_malformed_attribute(
| sym::rustc_force_inline
| sym::rustc_confusables
| sym::repr
| sym::align
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
| sym::rustc_align
| sym::deprecated
| sym::optimize
| sym::cold
+2 -2
View File
@@ -14,7 +14,7 @@ passes_abi_of =
fn_abi_of({$fn_name}) = {$fn_abi}
passes_align_should_be_repr_align =
`#[align(...)]` is not supported on {$item} items
`#[rustc_align(...)]` is not supported on {$item} items
.suggestion = use `#[repr(align(...))]` instead
passes_allow_incoherent_impl =
@@ -589,7 +589,7 @@ passes_repr_align_greater_than_target_max =
passes_repr_align_should_be_align =
`#[repr(align(...))]` is not supported on {$item} items
.help = use `#[align(...)]` instead
.help = use `#[rustc_align(...)]` instead
passes_repr_conflicting =
conflicting representation hints
+3 -1
View File
@@ -662,7 +662,8 @@ fn check_naked(
sym::naked,
sym::instruction_set,
sym::repr,
sym::align,
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
sym::rustc_align,
sym::rustc_std_internal_symbol,
// documentation
sym::doc,
@@ -1996,6 +1997,7 @@ fn check_no_mangle(&self, hir_id: HirId, attr_span: Span, span: Span, target: Ta
}
/// Checks if the `#[align]` attributes on `item` are valid.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
match target {
Target::Fn | Target::Method(_) => {}
+2
View File
@@ -1806,6 +1806,8 @@
rust_out,
rustc,
rustc_abi,
// FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
rustc_align,
rustc_allocator,
rustc_allocator_zeroed,
rustc_allow_const_fn_unstable,
+7 -3
View File
@@ -1,15 +1,19 @@
//@compile-flags: -Zmin-function-alignment=8
// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]`
// nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
// When a function uses `align(N)`, the function address should be a multiple of `N`.
#[align(256)]
#[rustc_align(256)]
fn foo() {}
#[align(16)]
#[rustc_align(16)]
fn bar() {}
#[align(4)]
#[rustc_align(4)]
fn baz() {}
fn main() {
+14 -12
View File
@@ -1,11 +1,13 @@
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
#![crate_type = "lib"]
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
// CHECK: align 16
#[no_mangle]
#[align(16)]
#[rustc_align(16)]
pub fn fn_align() {}
pub struct A;
@@ -13,12 +15,12 @@ pub fn fn_align() {}
impl A {
// CHECK: align 16
#[no_mangle]
#[align(16)]
#[rustc_align(16)]
pub fn method_align(self) {}
// CHECK: align 16
#[no_mangle]
#[align(16)]
#[rustc_align(16)]
pub fn associated_fn() {}
}
@@ -26,19 +28,19 @@ trait T: Sized {
fn trait_fn() {}
// CHECK: align 32
#[align(32)]
#[rustc_align(32)]
fn trait_method(self) {}
}
impl T for A {
// CHECK: align 16
#[no_mangle]
#[align(16)]
#[rustc_align(16)]
fn trait_fn() {}
// CHECK: align 16
#[no_mangle]
#[align(16)]
#[rustc_align(16)]
fn trait_method(self) {}
}
@@ -51,20 +53,20 @@ pub fn foo() {
// CHECK-LABEL: align_specified_twice_1
// CHECK-SAME: align 64
#[no_mangle]
#[align(32)]
#[align(64)]
#[rustc_align(32)]
#[rustc_align(64)]
pub fn align_specified_twice_1() {}
// CHECK-LABEL: align_specified_twice_2
// CHECK-SAME: align 128
#[no_mangle]
#[align(128)]
#[align(32)]
#[rustc_align(128)]
#[rustc_align(32)]
pub fn align_specified_twice_2() {}
// CHECK-LABEL: align_specified_twice_3
// CHECK-SAME: align 256
#[no_mangle]
#[align(32)]
#[align(256)]
#[rustc_align(32)]
#[rustc_align(256)]
pub fn align_specified_twice_3() {}
+4 -2
View File
@@ -4,6 +4,8 @@
//@ [align1024] compile-flags: -Zmin-function-alignment=1024
#![crate_type = "lib"]
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
// functions without explicit alignment use the global minimum
@@ -18,7 +20,7 @@ pub fn no_explicit_align() {}
// align16: align 16
// align1024: align 1024
#[no_mangle]
#[align(8)]
#[rustc_align(8)]
pub fn lower_align() {}
// the higher value of min-function-alignment and the align attribute wins out
@@ -27,7 +29,7 @@ pub fn lower_align() {}
// align16: align 32
// align1024: align 1024
#[no_mangle]
#[align(32)]
#[rustc_align(32)]
pub fn higher_align() {}
// cold functions follow the same rules as other functions
+4 -1
View File
@@ -3,12 +3,15 @@
//@ ignore-arm no "ret" mnemonic
#![crate_type = "lib"]
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
use std::arch::naked_asm;
// CHECK: .balign 16
// CHECK-LABEL: naked_empty:
#[align(16)]
#[rustc_align(16)]
#[no_mangle]
#[unsafe(naked)]
pub extern "C" fn naked_empty() {
@@ -2,6 +2,8 @@
//@ needs-asm-support
//@ ignore-arm no "ret" mnemonic
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
#![crate_type = "lib"]
@@ -16,7 +18,7 @@ pub extern "C" fn naked_no_explicit_align() {
// CHECK: .balign 16
#[no_mangle]
#[align(8)]
#[rustc_align(8)]
#[unsafe(naked)]
pub extern "C" fn naked_lower_align() {
core::arch::naked_asm!("ret")
@@ -24,7 +26,7 @@ pub extern "C" fn naked_lower_align() {
// CHECK: .balign 32
#[no_mangle]
#[align(32)]
#[rustc_align(32)]
#[unsafe(naked)]
pub extern "C" fn naked_higher_align() {
core::arch::naked_asm!("ret")
+5 -1
View File
@@ -1,5 +1,9 @@
//@ needs-asm-support
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
#![crate_type = "lib"]
use std::arch::naked_asm;
@@ -21,7 +25,7 @@ extern "C" fn example2() {
#[repr(C)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
#[align(16)]
#[rustc_align(16)]
#[unsafe(naked)]
extern "C" fn example3() {
//~^ NOTE not a struct, enum, or union
@@ -1,5 +1,5 @@
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:6:8
--> $DIR/naked-with-invalid-repr-attr.rs:10:8
|
LL | #[repr(C)]
| ^
@@ -11,7 +11,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:14:8
--> $DIR/naked-with-invalid-repr-attr.rs:18:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:22:8
--> $DIR/naked-with-invalid-repr-attr.rs:26:8
|
LL | #[repr(C)]
| ^
@@ -35,7 +35,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:32:8
--> $DIR/naked-with-invalid-repr-attr.rs:36:8
|
LL | #[repr(C, packed)]
| ^
@@ -48,7 +48,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct or union
--> $DIR/naked-with-invalid-repr-attr.rs:32:11
--> $DIR/naked-with-invalid-repr-attr.rs:36:11
|
LL | #[repr(C, packed)]
| ^^^^^^
@@ -61,7 +61,7 @@ LL | | }
| |_- not a struct or union
error[E0517]: attribute should be applied to an enum
--> $DIR/naked-with-invalid-repr-attr.rs:42:8
--> $DIR/naked-with-invalid-repr-attr.rs:46:8
|
LL | #[repr(u8)]
| ^^
@@ -1,21 +1,19 @@
//~ NOTE `align` could refer to a built-in attribute
// Anti-regression test to demonstrate that at least we mitigated breakage from adding a new
// `#[align]` built-in attribute.
//
// See https://github.com/rust-lang/rust/issues/143834.
//@ check-pass
// Needs edition >= 2018 macro use behavior.
//@ edition: 2018
macro_rules! align {
//~^ NOTE `align` could also refer to the macro defined here
() => {
/* .. */
};
}
pub(crate) use align;
//~^ ERROR `align` is ambiguous
//~| NOTE ambiguous name
//~| NOTE ambiguous because of a name conflict with a builtin attribute
fn main() {}
@@ -1,22 +0,0 @@
error[E0659]: `align` is ambiguous
--> $DIR/fn-align-nameres-ambiguity-143834.rs:16:16
|
LL | pub(crate) use align;
| ^^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a builtin attribute
= note: `align` could refer to a built-in attribute
note: `align` could also refer to the macro defined here
--> $DIR/fn-align-nameres-ambiguity-143834.rs:9:1
|
LL | / macro_rules! align {
LL | |
LL | | () => {
LL | | /* .. */
LL | | };
LL | | }
| |_^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0659`.
+11 -6
View File
@@ -1,25 +1,30 @@
// ignore-tidy-linelength
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#![feature(rustc_attrs)]
#![feature(fn_align)]
#![crate_type = "lib"]
trait MyTrait {
#[align] //~ ERROR malformed `align` attribute input
#[rustc_align] //~ ERROR malformed `rustc_align` attribute input
fn myfun1();
#[align(1, 2)] //~ ERROR malformed `align` attribute input
#[rustc_align(1, 2)] //~ ERROR malformed `rustc_align` attribute input
fn myfun2();
}
#[align = 16] //~ ERROR malformed `align` attribute input
#[rustc_align = 16] //~ ERROR malformed `rustc_align` attribute input
fn f1() {}
#[align("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer
#[rustc_align("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer
fn f2() {}
#[align(0)] //~ ERROR invalid alignment value: not a power of two
#[rustc_align(0)] //~ ERROR invalid alignment value: not a power of two
fn f3() {}
#[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items
fn f4() {}
#[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items
#[rustc_align(16)] //~ ERROR `#[rustc_align(...)]` is not supported on struct items
struct S1;
+31 -31
View File
@@ -1,63 +1,63 @@
error[E0539]: malformed `align` attribute input
--> $DIR/malformed-fn-align.rs:5:5
error[E0539]: malformed `rustc_align` attribute input
--> $DIR/malformed-fn-align.rs:10:5
|
LL | #[align]
| ^^^^^^^^
LL | #[rustc_align]
| ^^^^^^^^^^^^^^
| |
| expected this to be a list
| help: must be of the form: `#[align(<alignment in bytes>)]`
| help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
error[E0805]: malformed `align` attribute input
--> $DIR/malformed-fn-align.rs:8:5
error[E0805]: malformed `rustc_align` attribute input
--> $DIR/malformed-fn-align.rs:13:5
|
LL | #[align(1, 2)]
| ^^^^^^^------^
| | |
| | expected a single argument here
| help: must be of the form: `#[align(<alignment in bytes>)]`
LL | #[rustc_align(1, 2)]
| ^^^^^^^^^^^^^------^
| | |
| | expected a single argument here
| help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
error[E0539]: malformed `align` attribute input
--> $DIR/malformed-fn-align.rs:12:1
error[E0539]: malformed `rustc_align` attribute input
--> $DIR/malformed-fn-align.rs:17:1
|
LL | #[align = 16]
| ^^^^^^^^^^^^^
LL | #[rustc_align = 16]
| ^^^^^^^^^^^^^^^^^^^
| |
| expected this to be a list
| help: must be of the form: `#[align(<alignment in bytes>)]`
| help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
error[E0589]: invalid alignment value: not an unsuffixed integer
--> $DIR/malformed-fn-align.rs:15:9
--> $DIR/malformed-fn-align.rs:20:15
|
LL | #[align("hello")]
| ^^^^^^^
LL | #[rustc_align("hello")]
| ^^^^^^^
error[E0589]: invalid alignment value: not a power of two
--> $DIR/malformed-fn-align.rs:18:9
--> $DIR/malformed-fn-align.rs:23:15
|
LL | #[align(0)]
| ^
LL | #[rustc_align(0)]
| ^
error: `#[repr(align(...))]` is not supported on function items
--> $DIR/malformed-fn-align.rs:21:8
--> $DIR/malformed-fn-align.rs:26:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
|
help: use `#[align(...)]` instead
--> $DIR/malformed-fn-align.rs:21:8
help: use `#[rustc_align(...)]` instead
--> $DIR/malformed-fn-align.rs:26:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
error: `#[align(...)]` is not supported on struct items
--> $DIR/malformed-fn-align.rs:24:1
error: `#[rustc_align(...)]` is not supported on struct items
--> $DIR/malformed-fn-align.rs:29:1
|
LL | #[align(16)]
| ^^^^^^^^^^^^
LL | #[rustc_align(16)]
| ^^^^^^^^^^^^^^^^^^
|
help: use `#[repr(align(...))]` instead
|
LL - #[align(16)]
LL - #[rustc_align(16)]
LL + #[repr(align(16))]
|
@@ -1,12 +1,16 @@
#![crate_type = "lib"]
#[align(16)]
//~^ ERROR the `#[align]` attribute is an experimental feature
// ignore-tidy-linelength
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
#[rustc_align(16)]
//~^ ERROR the `#[rustc_align]` attribute is an experimental feature
fn requires_alignment() {}
trait MyTrait {
#[align]
//~^ ERROR the `#[align]` attribute is an experimental feature
//~| ERROR malformed `align` attribute input
#[rustc_align]
//~^ ERROR the `#[rustc_align]` attribute is an experimental feature
//~| ERROR malformed `rustc_align` attribute input
fn myfun();
}
@@ -1,31 +1,31 @@
error[E0658]: the `#[align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:3:1
error[E0658]: the `#[rustc_align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:7:1
|
LL | #[align(16)]
| ^^^^^^^^^^^^
LL | #[rustc_align(16)]
| ^^^^^^^^^^^^^^^^^^
|
= note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
= help: add `#![feature(fn_align)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:8:5
error[E0658]: the `#[rustc_align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:12:5
|
LL | #[align]
| ^^^^^^^^
LL | #[rustc_align]
| ^^^^^^^^^^^^^^
|
= note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
= help: add `#![feature(fn_align)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0539]: malformed `align` attribute input
--> $DIR/feature-gate-fn_align.rs:8:5
error[E0539]: malformed `rustc_align` attribute input
--> $DIR/feature-gate-fn_align.rs:12:5
|
LL | #[align]
| ^^^^^^^^
LL | #[rustc_align]
| ^^^^^^^^^^^^^^
| |
| expected this to be a list
| help: must be of the form: `#[align(<alignment in bytes>)]`
| help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
error: aborting due to 3 previous errors