From b65574d78220ab70da315964224bb73c21de1b46 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Fri, 10 Apr 2026 00:21:53 +0200 Subject: [PATCH 1/5] Add (failing) ui test for denying global_allocator + thread_local --- tests/ui/allocator/no-thread-local.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/ui/allocator/no-thread-local.rs diff --git a/tests/ui/allocator/no-thread-local.rs b/tests/ui/allocator/no-thread-local.rs new file mode 100644 index 000000000000..33c433d5c988 --- /dev/null +++ b/tests/ui/allocator/no-thread-local.rs @@ -0,0 +1,10 @@ +#![feature(thread_local)] + +use std::alloc::System; + +#[global_allocator] +#[thread_local] +//~^ ERROR: allocators cannot be `#[thread_local]` +static A: System = System; + +fn main() {} From 95c1a3793e8d348205cab69962da709c6c63d8a4 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Fri, 10 Apr 2026 00:33:27 +0200 Subject: [PATCH 2/5] Deny global_allocator + thread_local --- compiler/rustc_builtin_macros/src/errors.rs | 7 +++++++ compiler/rustc_builtin_macros/src/global_allocator.rs | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 87f1ff960a82..72fe9e7843bb 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -158,6 +158,13 @@ pub(crate) struct AllocMustStatics { pub(crate) span: Span, } +#[derive(Diagnostic)] +#[diag("allocators cannot be `#[thread_local]`")] +pub(crate) struct AllocCannotThreadLocal { + #[primary_span] + pub(crate) span: Span, +} + pub(crate) use autodiff::*; mod autodiff { diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 85ad8a63a54f..f8a1607778e8 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -38,6 +38,12 @@ pub(crate) fn expand( return vec![orig_item]; }; + // Forbid `#[thread_local]` attributes on the item + if let Some(_) = item.attrs.iter().find(|x| { x.has_name(sym::thread_local) }) { + ecx.dcx().emit_err(errors::AllocCannotThreadLocal { span: item.span_with_attributes() }); + return vec![orig_item]; + } + // Generate a bunch of new items using the AllocFnFactory let span = ecx.with_def_site_ctxt(item.span); let f = AllocFnFactory { span, ty_span, global: ident, cx: ecx }; From 9614f285a70be5b310029a30b38b6fb9adfac80c Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Fri, 10 Apr 2026 00:33:44 +0200 Subject: [PATCH 3/5] Update ui test for deny global_allocator + thread_local --- tests/ui/allocator/no-thread-local.stderr | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/ui/allocator/no-thread-local.stderr diff --git a/tests/ui/allocator/no-thread-local.stderr b/tests/ui/allocator/no-thread-local.stderr new file mode 100644 index 000000000000..27aa8fd4a7fa --- /dev/null +++ b/tests/ui/allocator/no-thread-local.stderr @@ -0,0 +1,10 @@ +error: allocators cannot be `#[thread_local]` + --> $DIR/no-thread-local.rs:6:1 + | +LL | / #[thread_local] +LL | | +LL | | static A: System = System; + | |__________________________^ + +error: aborting due to 1 previous error + From dbe7a4e13ad2c2e0cdaddde1348f8777d1de71ee Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Fri, 10 Apr 2026 00:45:37 +0200 Subject: [PATCH 4/5] Improve diagnostic for global_allocator + thread_local --- compiler/rustc_builtin_macros/src/errors.rs | 3 +++ .../rustc_builtin_macros/src/global_allocator.rs | 7 +++++-- tests/ui/allocator/no-thread-local.rs | 2 +- tests/ui/allocator/no-thread-local.stderr | 13 ++++++++----- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 72fe9e7843bb..b5ac84337465 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -163,6 +163,9 @@ pub(crate) struct AllocMustStatics { pub(crate) struct AllocCannotThreadLocal { #[primary_span] pub(crate) span: Span, + #[label("marked `#[thread_local]` here")] + #[suggestion("remove this attribute", code = "", applicability = "maybe-incorrect")] + pub(crate) attr: Span, } pub(crate) use autodiff::*; diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index f8a1607778e8..f6e28bd78004 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -39,8 +39,11 @@ pub(crate) fn expand( }; // Forbid `#[thread_local]` attributes on the item - if let Some(_) = item.attrs.iter().find(|x| { x.has_name(sym::thread_local) }) { - ecx.dcx().emit_err(errors::AllocCannotThreadLocal { span: item.span_with_attributes() }); + if let Some(attr) = item.attrs.iter().find(|x| { x.has_name(sym::thread_local) }) { + ecx.dcx().emit_err(errors::AllocCannotThreadLocal { + span: item.span, + attr: attr.span + }); return vec![orig_item]; } diff --git a/tests/ui/allocator/no-thread-local.rs b/tests/ui/allocator/no-thread-local.rs index 33c433d5c988..4548b00816fd 100644 --- a/tests/ui/allocator/no-thread-local.rs +++ b/tests/ui/allocator/no-thread-local.rs @@ -4,7 +4,7 @@ #[global_allocator] #[thread_local] -//~^ ERROR: allocators cannot be `#[thread_local]` static A: System = System; +//~^ ERROR: allocators cannot be `#[thread_local]` fn main() {} diff --git a/tests/ui/allocator/no-thread-local.stderr b/tests/ui/allocator/no-thread-local.stderr index 27aa8fd4a7fa..b045dae09c8e 100644 --- a/tests/ui/allocator/no-thread-local.stderr +++ b/tests/ui/allocator/no-thread-local.stderr @@ -1,10 +1,13 @@ error: allocators cannot be `#[thread_local]` - --> $DIR/no-thread-local.rs:6:1 + --> $DIR/no-thread-local.rs:7:1 | -LL | / #[thread_local] -LL | | -LL | | static A: System = System; - | |__________________________^ +LL | #[thread_local] + | --------------- + | | + | marked `#[thread_local]` here + | help: remove this attribute +LL | static A: System = System; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error From b537c45ec84373293329b2b7d59054f058c5f2b1 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Fri, 10 Apr 2026 00:49:17 +0200 Subject: [PATCH 5/5] Apply suggestions from fmt output --- compiler/rustc_builtin_macros/src/global_allocator.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index f6e28bd78004..208562b8d0bc 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -39,11 +39,8 @@ pub(crate) fn expand( }; // Forbid `#[thread_local]` attributes on the item - if let Some(attr) = item.attrs.iter().find(|x| { x.has_name(sym::thread_local) }) { - ecx.dcx().emit_err(errors::AllocCannotThreadLocal { - span: item.span, - attr: attr.span - }); + if let Some(attr) = item.attrs.iter().find(|x| x.has_name(sym::thread_local)) { + ecx.dcx().emit_err(errors::AllocCannotThreadLocal { span: item.span, attr: attr.span }); return vec![orig_item]; }