Skip to content

Commit 2c37b3e

Browse files
Rollup merge of rust-lang#160211 - jieyouxu:froot-loops, r=mati865
Rename `#[unroll]` => `#[rustc_unroll]` to mitigate nameres ambiguity ## Summary Mitigate rust-lang#159429 by renaming `#[unroll]` => `#[rustc_unroll]`. Did not bother with a regression test, because a regression test would be hedging against an unknown attribute if `#[unroll]` later proceeds to get a different name. Tracking issue for `#![feature(loop_hints)]`: rust-lang#156874. ## Rationale Even while the crater-observed fallout seems to be relatively small, we'd like such nameres ambiguity breakages to be *deliberate* (read: T-lang FCP'd) rather than accidental (discovered through beta crater runs). See discussions around [last week's compiler triage meeting](https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202026-07-23/near/612371735). ## Background context The recurring problem is that built-in attributes are treated differently compared to ordinary prelude attributes, built-in attributes, even while unstable, can name-collide with stable macro re-exports of the same name (and proc-macro helper attributes of the same name), which can break stable code. See rust-lang#134964. See also: - rust-lang#133708 - rust-lang#53913 (comment) - https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Name.20Res.3A.20questions.20on.20intended.20behavior/near/562001319 - rust-lang#143834 (comment) ## Prior Art - For `#[align]`, breakage was more wide-spread, so we posted this same mitigation here: rust-lang#144080. - For `#[sanitize]`, T-lang explicitly FCP'd the breakage stemming from renaming `#[no_sanitize]` (old name) to `#[sanitize]` (new name) that regressed a couple of crates: rust-lang#142681 (comment). ## Alternatives to this PR Generally: - We let it slide. - T-lang FCP on `#[unroll]` breakage (in which case this PR should be closed). - FCP another name (and associated breakages). - (Hard) Fix the built-in attribute name resolution behavior. I have no particular preference on the approaches myself, any of this PR and the alternatives seem fine so as long as the breakage is *deliberate* not accidental.
2 parents c3c9170 + d1265b7 commit 2c37b3e

14 files changed

Lines changed: 73 additions & 58 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/unroll.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use super::prelude::*;
66

77
pub(crate) struct UnrollParser;
88
impl SingleAttributeParser for UnrollParser {
9-
const PATH: &[Symbol] = &[sym::unroll];
9+
// FIXME(#159429): temporarily renamed to mitigate `#[unroll]` nameres ambiguity.
10+
const PATH: &[Symbol] = &[sym::rustc_unroll];
1011
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
1112
Allow(Target::Loop),
1213
Allow(Target::ForLoop),

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,12 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[
217217
// - https://github.com/rust-lang/rust/issues/153629
218218
sym::rustc_splat,
219219

220-
// The `#[unroll]` attribute.
220+
// The `#[rustc_unroll]` attribute.
221221
//
222222
// - https://github.com/rust-lang/rust/pull/156816
223-
sym::unroll,
223+
//
224+
// FIXME(#159429): temporarily renamed to mitigate `#[unroll]` nameres ambiguity
225+
sym::rustc_unroll,
224226

225227
// `#[instrument_fn = "on|off"]` to insert or inhibit instrumentation function
226228
// calls inside a function, usually around the prologue.

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,8 @@ pub enum AttributeKind {
17061706
limit: Limit,
17071707
},
17081708

1709-
/// Represents `#[unroll]`
1709+
/// Represents `#[rustc_unroll]`
1710+
// FIXME(#159429): temporarily renamed from `#[unroll]` to mitigate nameres ambiguity
17101711
Unroll(UnrollAttr),
17111712

17121713
/// Represents `#[unstable_feature_bound]`.

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,8 @@ symbols! {
18721872
rustc_test_marker,
18731873
rustc_then_this_would_need,
18741874
rustc_trivial_field_reads,
1875+
// FIXME(#159429): temporary rename to avoid `#[unroll]` nameres ambiguity
1876+
rustc_unroll,
18751877
rustdoc,
18761878
rustdoc_internals,
18771879
rustdoc_missing_doc_code_examples,
@@ -2254,7 +2256,6 @@ symbols! {
22542256
unreachable_display,
22552257
unreachable_macro,
22562258
unrestricted_attribute_tokens,
2257-
unroll,
22582259
unsafe_attributes,
22592260
unsafe_binders,
22602261
unsafe_block_in_unsafe_fn,

src/doc/unstable-book/src/language-features/loop-hints.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ The tracking issue for this feature is: [#156874]
66

77
------
88

9+
<!--
10+
FIXME(#159429): temporarily renamed `#[unroll]` to mitigate a nameres ambiguity
11+
-->
12+
913
Loop unrolling can be a powerful optimization but like inlining, it is sometimes useful to
1014
manually provide hints to optimizations.
1115

12-
`#[unroll]` will encourage unrolling of a loop.
16+
`#[rustc_unroll]` will encourage unrolling of a loop.
1317

14-
`#[unroll(full)]` is a stronger hint and can cause optimizations to completely ignore the code
18+
`#[rustc_unroll(full)]` is a stronger hint and can cause optimizations to completely ignore the code
1519
side growth from repeating a loop body.
1620

17-
`#[unroll(never)]` is a strong hint to not unroll the loop at all. Note that other loop
21+
`#[rustc_unroll(never)]` is a strong hint to not unroll the loop at all. Note that other loop
1822
optimizations may still be applied.
1923

20-
`#[unroll(N)]` is a hint to unroll `N` iterations of the loop.
24+
`#[rustc_unroll(N)]` is a hint to unroll `N` iterations of the loop.
2125

2226
In all cases these are just hints and may be ignored. But unlike function inlining hints,
2327
loops tend to be heavily modified during compilation, which can make obeying hints challenging.

tests/codegen-llvm/loop-attrs/unroll-for-metadata.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ unsafe extern "C" {
1515
pub fn unroll_hint() {
1616
// CHECK-LABEL: @unroll_hint
1717
// CHECK: !llvm.loop ![[HINT:[0-9]+]]
18-
#[unroll]
18+
#[rustc_unroll]
1919
for _ in 0..10 {
2020
unsafe { maybe_has_side_effect() }
2121
}
@@ -25,7 +25,7 @@ pub fn unroll_hint() {
2525
pub fn unroll_full() {
2626
// CHECK-LABEL: @unroll_full
2727
// CHECK: !llvm.loop ![[FULL:[0-9]+]]
28-
#[unroll(full)]
28+
#[rustc_unroll(full)]
2929
for _ in 0..10 {
3030
unsafe { maybe_has_side_effect() }
3131
}
@@ -35,7 +35,7 @@ pub fn unroll_full() {
3535
pub fn unroll_never() {
3636
// CHECK-LABEL: @unroll_never
3737
// CHECK: !llvm.loop ![[DISABLE:[0-9]+]]
38-
#[unroll(never)]
38+
#[rustc_unroll(never)]
3939
for _ in 0..10 {
4040
unsafe { maybe_has_side_effect() }
4141
}
@@ -45,7 +45,7 @@ pub fn unroll_never() {
4545
pub fn unroll_count() {
4646
// CHECK-LABEL: @unroll_count
4747
// CHECK: !llvm.loop ![[COUNT:[0-9]+]]
48-
#[unroll(5)]
48+
#[rustc_unroll(5)]
4949
for _ in 0..10 {
5050
unsafe { maybe_has_side_effect() }
5151
}

tests/codegen-llvm/loop-attrs/unroll-for-works.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ unsafe extern "C" {
1111
pub fn unroll_full() {
1212
// CHECK-LABEL: @unroll_full
1313
// CHECK-COUNT-512: tail call void @maybe_has_side_effect()
14-
#[unroll(full)]
14+
#[rustc_unroll(full)]
1515
for _ in 0..512 {
1616
unsafe { maybe_has_side_effect() }
1717
}
@@ -22,7 +22,7 @@ pub fn unroll_never() {
2222
// CHECK-LABEL: @unroll_never
2323
// CHECK: tail call void @maybe_has_side_effect()
2424
// CHECK-NOT: tail call void @maybe_has_side_effect()
25-
#[unroll(never)]
25+
#[rustc_unroll(never)]
2626
for _ in 0..3 {
2727
unsafe { maybe_has_side_effect() }
2828
}
@@ -32,7 +32,7 @@ pub fn unroll_never() {
3232
pub fn unroll_count() {
3333
// CHECK-LABEL: @unroll_count
3434
// CHECK-COUNT-5: tail call void @maybe_has_side_effect()
35-
#[unroll(5)]
35+
#[rustc_unroll(5)]
3636
for _ in 0..10 {
3737
unsafe { maybe_has_side_effect() }
3838
}

tests/codegen-llvm/loop-attrs/unroll-loop-metadata.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn unroll_hint() {
1717
// CHECK-LABEL: @unroll_hint
1818
// CHECK: !llvm.loop ![[HINT:[0-9]+]]
1919
let mut i = 0;
20-
#[unroll]
20+
#[rustc_unroll]
2121
loop {
2222
unsafe { maybe_has_side_effect() }
2323
i += 1;
@@ -35,7 +35,7 @@ pub fn unroll_full() {
3535
// CHECK-LABEL: @unroll_full
3636
// CHECK: !llvm.loop ![[FULL:[0-9]+]]
3737
let mut i = 0;
38-
let _return = (#[unroll(full)]
38+
let _return = (#[rustc_unroll(full)]
3939
loop {
4040
unsafe { maybe_has_side_effect() }
4141
i += 1;
@@ -50,7 +50,7 @@ pub fn unroll_never() {
5050
// CHECK-LABEL: @unroll_never
5151
// CHECK: !llvm.loop ![[DISABLE:[0-9]+]]
5252
let mut i = 0;
53-
let _return = (1 + #[unroll(never)]
53+
let _return = (1 + #[rustc_unroll(never)]
5454
loop {
5555
unsafe { maybe_has_side_effect() }
5656
i += 1;
@@ -65,7 +65,7 @@ pub fn unroll_count() {
6565
// CHECK-LABEL: @unroll_count
6666
// CHECK: !llvm.loop ![[COUNT:[0-9]+]]
6767
let mut i = 0;
68-
#[unroll(5)]
68+
#[rustc_unroll(5)]
6969
loop {
7070
unsafe { maybe_has_side_effect() }
7171
i += 1;

tests/codegen-llvm/loop-attrs/unroll-while-metadata.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn unroll_hint() {
1616
// CHECK-LABEL: @unroll_hint
1717
// CHECK: !llvm.loop ![[HINT:[0-9]+]]
1818
let mut i = 0;
19-
#[unroll]
19+
#[rustc_unroll]
2020
while i < 10 {
2121
unsafe { maybe_has_side_effect() }
2222
i += 1;
@@ -28,7 +28,7 @@ pub fn unroll_full() {
2828
// CHECK-LABEL: @unroll_full
2929
// CHECK: !llvm.loop ![[FULL:[0-9]+]]
3030
let mut i = 0;
31-
#[unroll(full)]
31+
#[rustc_unroll(full)]
3232
while i < 10 {
3333
unsafe { maybe_has_side_effect() }
3434
i += 1;
@@ -40,7 +40,7 @@ pub fn unroll_never() {
4040
// CHECK-LABEL: @unroll_never
4141
// CHECK: !llvm.loop ![[DISABLE:[0-9]+]]
4242
let mut i = 0;
43-
#[unroll(never)]
43+
#[rustc_unroll(never)]
4444
while i < 10 {
4545
unsafe { maybe_has_side_effect() }
4646
i += 1;
@@ -52,7 +52,7 @@ pub fn unroll_count() {
5252
// CHECK-LABEL: @unroll_count
5353
// CHECK: !llvm.loop ![[COUNT:[0-9]+]]
5454
let mut i = 0;
55-
#[unroll(5)]
55+
#[rustc_unroll(5)]
5656
while i < 10 {
5757
unsafe { maybe_has_side_effect() }
5858
i += 1;

tests/ui/attributes/unroll/invalid-unroll.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
#![crate_type = "lib"]
33

44
pub fn main() {
5-
#[unroll(please)] //~ ERROR malformed `unroll` attribute input
5+
#[rustc_unroll(please)] //~ ERROR malformed `rustc_unroll` attribute input
66
for _ in 0..10 {}
77

8-
#[unroll("never")] //~ ERROR malformed `unroll` attribute input
8+
#[rustc_unroll("never")] //~ ERROR malformed `rustc_unroll` attribute input
99
for _ in 0..10 {}
1010

11-
#[unroll()] //~ ERROR malformed `unroll` attribute input
11+
#[rustc_unroll()] //~ ERROR malformed `rustc_unroll` attribute input
1212
for _ in 0..10 {}
1313

14-
#[unroll(-1)] //~ ERROR expected a literal
14+
#[rustc_unroll(-1)] //~ ERROR expected a literal
1515
for _ in 0..10 {}
1616

17-
#[unroll(1.5)] //~ ERROR malformed `unroll` attribute input
17+
#[rustc_unroll(1.5)] //~ ERROR malformed `rustc_unroll` attribute input
1818
for _ in 0..10 {}
1919
}

0 commit comments

Comments
 (0)