From 59ed2459457eb7c95b2baa9dccdb74f63b9c0a80 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 10 Apr 2026 15:05:07 +0200 Subject: [PATCH] Reject mutable externally implementable statics --- compiler/rustc_builtin_macros/src/eii.rs | 14 ++++++++++++-- compiler/rustc_builtin_macros/src/errors.rs | 8 ++++++++ tests/ui/eii/static/mismatch_mut.rs | 1 + tests/ui/eii/static/mismatch_mut.stderr | 10 ++++++++-- tests/ui/eii/static/mismatch_mut2.rs | 21 +++++++++++++++++++++ tests/ui/eii/static/mismatch_mut2.stderr | 8 ++++++++ tests/ui/eii/static/mismatch_safety.rs | 2 +- tests/ui/eii/static/mismatch_safety2.rs | 21 +++++++++++++++++++++ tests/ui/eii/static/mismatch_safety2.stderr | 8 ++++++++ tests/ui/eii/static/mut.rs | 3 +-- tests/ui/eii/static/mut.stderr | 8 ++++++++ 11 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 tests/ui/eii/static/mismatch_mut2.rs create mode 100644 tests/ui/eii/static/mismatch_mut2.stderr create mode 100644 tests/ui/eii/static/mismatch_safety2.rs create mode 100644 tests/ui/eii/static/mismatch_safety2.stderr create mode 100644 tests/ui/eii/static/mut.stderr diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 9dab90b72a02..0cf9adfd4bcc 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -1,7 +1,8 @@ use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{ - Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, StmtKind, Visibility, ast, + Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Mutability, Path, StmtKind, + Visibility, ast, }; use rustc_ast_pretty::pprust::path_to_string; use rustc_expand::base::{Annotatable, ExtCtxt}; @@ -11,7 +12,7 @@ use crate::errors::{ EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe, EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroInStatementPosition, - EiiSharedMacroTarget, EiiStaticArgumentRequired, EiiStaticDefault, + EiiSharedMacroTarget, EiiStaticArgumentRequired, EiiStaticDefault, EiiStaticMutable, }; /// ```rust @@ -100,6 +101,15 @@ fn eii_( }); return vec![]; } + + // Mut statics are currently not supported + if stat.mutability == Mutability::Mut { + ecx.dcx().emit_err(EiiStaticMutable { + span: eii_attr_span, + name: path_to_string(&meta_item.path), + }); + } + (item.span, stat.ident) } _ => { diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 4b572c2f34ac..b210f93338d3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1140,6 +1140,14 @@ pub(crate) struct EiiStaticArgumentRequired { pub name: String, } +#[derive(Diagnostic)] +#[diag("`#[{$name}]` cannot be used on mutable statics")] +pub(crate) struct EiiStaticMutable { + #[primary_span] + pub span: Span, + pub name: String, +} + #[derive(Diagnostic)] #[diag("`#[{$name}]` can only be used on functions inside a module")] pub(crate) struct EiiSharedMacroInStatementPosition { diff --git a/tests/ui/eii/static/mismatch_mut.rs b/tests/ui/eii/static/mismatch_mut.rs index e99c948d0dcc..87c2c4128aa5 100644 --- a/tests/ui/eii/static/mismatch_mut.rs +++ b/tests/ui/eii/static/mismatch_mut.rs @@ -5,6 +5,7 @@ #![feature(extern_item_impls)] #[eii(hello)] +//~^ ERROR `#[eii]` cannot be used on mutable statics static mut HELLO: u64; #[hello] diff --git a/tests/ui/eii/static/mismatch_mut.stderr b/tests/ui/eii/static/mismatch_mut.stderr index a8438789c404..537ac0de3c3a 100644 --- a/tests/ui/eii/static/mismatch_mut.stderr +++ b/tests/ui/eii/static/mismatch_mut.stderr @@ -1,8 +1,14 @@ +error: `#[eii]` cannot be used on mutable statics + --> $DIR/mismatch_mut.rs:7:1 + | +LL | #[eii(hello)] + | ^^^^^^^^^^^^^ + error: mutability does not match with the definition of`#[hello]` - --> $DIR/mismatch_mut.rs:10:1 + --> $DIR/mismatch_mut.rs:11:1 | LL | #[hello] | ^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/eii/static/mismatch_mut2.rs b/tests/ui/eii/static/mismatch_mut2.rs new file mode 100644 index 000000000000..ab525e418ade --- /dev/null +++ b/tests/ui/eii/static/mismatch_mut2.rs @@ -0,0 +1,21 @@ +//@ ignore-backends: gcc +// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether EIIs work on statics +#![feature(extern_item_impls)] + +#[eii(hello)] +static HELLO: u64; + +#[hello] +//~^ ERROR mutability does not match with the definition of`#[hello]` +static mut HELLO_IMPL: u64 = 5; + +// what you would write: +fn main() { + // directly + println!("{}", unsafe { HELLO_IMPL }); + + // through the alias + println!("{HELLO}"); +} diff --git a/tests/ui/eii/static/mismatch_mut2.stderr b/tests/ui/eii/static/mismatch_mut2.stderr new file mode 100644 index 000000000000..6ac3df57697d --- /dev/null +++ b/tests/ui/eii/static/mismatch_mut2.stderr @@ -0,0 +1,8 @@ +error: mutability does not match with the definition of`#[hello]` + --> $DIR/mismatch_mut2.rs:10:1 + | +LL | #[hello] + | ^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/static/mismatch_safety.rs b/tests/ui/eii/static/mismatch_safety.rs index 9579cd68cb84..f30326b0755c 100644 --- a/tests/ui/eii/static/mismatch_safety.rs +++ b/tests/ui/eii/static/mismatch_safety.rs @@ -5,7 +5,7 @@ #![feature(extern_item_impls)] #[eii(hello)] -unsafe static mut HELLO: u64; +unsafe static HELLO: u64; #[hello] //~^ ERROR safety does not match with the definition of`#[hello]` diff --git a/tests/ui/eii/static/mismatch_safety2.rs b/tests/ui/eii/static/mismatch_safety2.rs new file mode 100644 index 000000000000..dea45c26292d --- /dev/null +++ b/tests/ui/eii/static/mismatch_safety2.rs @@ -0,0 +1,21 @@ +//@ ignore-backends: gcc +// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether EIIs work on statics +#![feature(extern_item_impls)] + +#[eii(hello)] +static HELLO: u64; + +#[hello] +unsafe static HELLO_IMPL: u64 = 5; +//~^ ERROR static items cannot be declared with `unsafe` safety qualifier outside of `extern` block + +// what you would write: +fn main() { + // directly + println!("{HELLO_IMPL}"); + + // through the alias + println!("{}", unsafe { HELLO }); +} diff --git a/tests/ui/eii/static/mismatch_safety2.stderr b/tests/ui/eii/static/mismatch_safety2.stderr new file mode 100644 index 000000000000..6957a6202b61 --- /dev/null +++ b/tests/ui/eii/static/mismatch_safety2.stderr @@ -0,0 +1,8 @@ +error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block + --> $DIR/mismatch_safety2.rs:11:1 + | +LL | unsafe static HELLO_IMPL: u64 = 5; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/static/mut.rs b/tests/ui/eii/static/mut.rs index 49c36f72ab86..803ffc229799 100644 --- a/tests/ui/eii/static/mut.rs +++ b/tests/ui/eii/static/mut.rs @@ -1,5 +1,3 @@ -//@ run-pass -//@ check-run-results //@ ignore-backends: gcc // FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 //@ ignore-windows @@ -7,6 +5,7 @@ #![feature(extern_item_impls)] #[eii(hello)] +//~^ ERROR `#[eii]` cannot be used on mutable statics static mut HELLO: u64; #[hello] diff --git a/tests/ui/eii/static/mut.stderr b/tests/ui/eii/static/mut.stderr new file mode 100644 index 000000000000..cd3a0ca23c7f --- /dev/null +++ b/tests/ui/eii/static/mut.stderr @@ -0,0 +1,8 @@ +error: `#[eii]` cannot be used on mutable statics + --> $DIR/mut.rs:7:1 + | +LL | #[eii(hello)] + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +