Skip to content

Commit 1f2b090

Browse files
Reject multiple EII implementations on one static
1 parent 59ed245 commit 1f2b090

6 files changed

Lines changed: 56 additions & 4 deletions

File tree

compiler/rustc_builtin_macros/src/eii.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use thin_vec::{ThinVec, thin_vec};
1212
use crate::errors::{
1313
EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe,
1414
EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroInStatementPosition,
15-
EiiSharedMacroTarget, EiiStaticArgumentRequired, EiiStaticDefault, EiiStaticMutable,
15+
EiiSharedMacroTarget, EiiStaticArgumentRequired, EiiStaticDefault,
16+
EiiStaticMultipleImplementations, EiiStaticMutable,
1617
};
1718

1819
/// ```rust
@@ -512,7 +513,14 @@ pub(crate) fn eii_shared_macro(
512513

513514
let eii_impls = match &mut i.kind {
514515
ItemKind::Fn(func) => &mut func.eii_impls,
515-
ItemKind::Static(stat) => &mut stat.eii_impls,
516+
ItemKind::Static(stat) => {
517+
if !stat.eii_impls.is_empty() {
518+
// Reject multiple implementations on one static item
519+
// because it might be unintuitive for libraries defining statics the defined statics may alias
520+
ecx.dcx().emit_err(EiiStaticMultipleImplementations { span });
521+
}
522+
&mut stat.eii_impls
523+
}
516524
_ => {
517525
ecx.dcx()
518526
.emit_err(EiiSharedMacroTarget { span, name: path_to_string(&meta_item.path) });

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,16 @@ pub(crate) struct EiiSharedMacroTarget {
11241124
pub name: String,
11251125
}
11261126

1127+
#[derive(Diagnostic)]
1128+
#[diag("static cannot implement multiple EIIs")]
1129+
#[note(
1130+
"this is not allowed because multiple externally implementable statics that alias may be unintuitive"
1131+
)]
1132+
pub(crate) struct EiiStaticMultipleImplementations {
1133+
#[primary_span]
1134+
pub span: Span,
1135+
}
1136+
11271137
#[derive(Diagnostic)]
11281138
#[diag("`#[{$name}]` cannot be used on statics with a value")]
11291139
pub(crate) struct EiiStaticDefault {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(extern_item_impls)]
2+
3+
const A: () = ();
4+
#[eii(A)]
5+
static A: u64;
6+
//~^ ERROR the name `A` is defined multiple times
7+
8+
#[A]
9+
static A_IMPL: u64 = 5;
10+
11+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0428]: the name `A` is defined multiple times
2+
--> $DIR/multiple_decls.rs:5:1
3+
|
4+
LL | const A: () = ();
5+
| ----------------- previous definition of the value `A` here
6+
LL | #[eii(A)]
7+
LL | static A: u64;
8+
| ^^^^^^^^^^^^^^ `A` redefined here
9+
|
10+
= note: `A` must be defined only once in the value namespace of this module
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0428`.

tests/ui/eii/static/multiple_impls.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//@ run-pass
2-
//@ check-run-results
31
//@ ignore-backends: gcc
42
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
53
//@ ignore-windows
@@ -14,6 +12,7 @@ static B: u64;
1412

1513
#[a]
1614
#[b]
15+
//~^ ERROR static cannot implement multiple EIIs
1716
static IMPL: u64 = 5;
1817

1918
fn main() {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: static cannot implement multiple EIIs
2+
--> $DIR/multiple_impls.rs:14:1
3+
|
4+
LL | #[b]
5+
| ^^^^
6+
|
7+
= note: this is not allowed because multiple externally implementable statics that alias may be unintuitive
8+
9+
error: aborting due to 1 previous error
10+

0 commit comments

Comments
 (0)