diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 87f1ff960a82..b5ac84337465 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -158,6 +158,16 @@ 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, + #[label("marked `#[thread_local]` here")] + #[suggestion("remove this attribute", code = "", applicability = "maybe-incorrect")] + pub(crate) attr: 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..208562b8d0bc 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(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]; + } + // 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 }; diff --git a/tests/ui/allocator/no-thread-local.rs b/tests/ui/allocator/no-thread-local.rs new file mode 100644 index 000000000000..4548b00816fd --- /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] +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 new file mode 100644 index 000000000000..b045dae09c8e --- /dev/null +++ b/tests/ui/allocator/no-thread-local.stderr @@ -0,0 +1,13 @@ +error: allocators cannot be `#[thread_local]` + --> $DIR/no-thread-local.rs:7:1 + | +LL | #[thread_local] + | --------------- + | | + | marked `#[thread_local]` here + | help: remove this attribute +LL | static A: System = System; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +