Skip to content
/ rust Public
forked from rust-lang/rust

Commit d24482e

Browse files
authored
Rollup merge of rust-lang#156583 - AsakuraMizu:eii-static-default, r=JonathanBrouwer,mu001999
Support defaults for static EIIs Tracking issue: rust-lang#125418 rust-lang#154193 added EII support for statics, but left default implementations for "a followup PR". This PR implements it. Maybe I should remove `no-prefer-dynamic` if rust-lang#156577 is accepted.
2 parents 45aa924 + cdb6acc commit d24482e

14 files changed

Lines changed: 165 additions & 33 deletions

compiler/rustc_builtin_macros/src/diagnostics.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,8 +1135,9 @@ pub(crate) struct EiiStaticMultipleImplementations {
11351135
}
11361136

11371137
#[derive(Diagnostic)]
1138-
#[diag("`#[{$name}]` cannot be used on statics with a value")]
1139-
pub(crate) struct EiiStaticDefault {
1138+
#[diag("`#[{$name}]` cannot be used on statics with a value on Apple targets")]
1139+
#[note("see issue #157649 <https://github.com/rust-lang/rust/issues/157649> for more information")]
1140+
pub(crate) struct EiiStaticDefaultApple {
11401141
#[primary_span]
11411142
pub span: Span,
11421143
pub name: String,

compiler/rustc_builtin_macros/src/eii.rs

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::diagnostics::{
1313
EiiAttributeNotSupported, EiiExternTargetExpectedList, EiiExternTargetExpectedMacro,
1414
EiiExternTargetExpectedUnsafe, EiiMacroExpectedMaxOneArgument, EiiOnlyOnce,
1515
EiiSharedMacroInStatementPosition, EiiSharedMacroTarget, EiiStaticArgumentRequired,
16-
EiiStaticDefault, EiiStaticMultipleImplementations, EiiStaticMutable,
16+
EiiStaticDefaultApple, EiiStaticMultipleImplementations, EiiStaticMutable,
1717
};
1818

1919
/// ```rust
@@ -86,14 +86,17 @@ fn eii_(
8686
let (item_span, foreign_item_name) = match kind {
8787
ItemKind::Fn(func) => (func.sig.span, func.ident),
8888
ItemKind::Static(stat) => {
89-
// Statics with a default are not supported yet
90-
if let Some(stat_body) = &stat.expr {
91-
ecx.dcx().emit_err(EiiStaticDefault {
92-
span: stat_body.span,
89+
// See https://github.com/rust-lang/rust/issues/157649
90+
if let Some(expr) = &stat.expr
91+
&& ecx.sess.target.is_like_darwin
92+
{
93+
ecx.dcx().emit_err(EiiStaticDefaultApple {
94+
span: expr.span,
9395
name: path_to_string(&meta_item.path),
9496
});
9597
return vec![];
9698
}
99+
97100
// Statics must have an explicit name for the eii
98101
if meta_item.is_word() {
99102
ecx.dcx().emit_err(EiiStaticArgumentRequired {
@@ -139,19 +142,17 @@ fn eii_(
139142

140143
let mut module_items = Vec::new();
141144

142-
if let ItemKind::Fn(func) = kind
143-
&& func.body.is_some()
144-
{
145-
module_items.push(generate_default_func_impl(
146-
ecx,
147-
&func,
148-
impl_unsafe,
149-
macro_name,
150-
eii_attr_span,
151-
item_span,
152-
foreign_item_name,
153-
default_func_attrs,
154-
))
145+
if let Some(default_impl) = generate_default_impl(
146+
ecx,
147+
kind,
148+
impl_unsafe,
149+
macro_name,
150+
eii_attr_span,
151+
item_span,
152+
foreign_item_name,
153+
default_func_attrs,
154+
) {
155+
module_items.push(default_impl);
155156
}
156157

157158
module_items.push(generate_foreign_item(
@@ -266,18 +267,31 @@ fn filter_attrs_for_multiple_eii_attr(
266267
.collect()
267268
}
268269

269-
fn generate_default_func_impl(
270+
fn generate_default_impl(
270271
ecx: &mut ExtCtxt<'_>,
271-
func: &ast::Fn,
272+
item_kind: &ItemKind,
272273
impl_unsafe: bool,
273274
macro_name: Ident,
274275
eii_attr_span: Span,
275276
item_span: Span,
276277
foreign_item_name: Ident,
277278
attrs: ThinVec<Attribute>,
278-
) -> Box<ast::Item> {
279-
let mut default_func = func.clone();
280-
default_func.eii_impls.push(EiiImpl {
279+
) -> Option<Box<ast::Item>> {
280+
match item_kind {
281+
ItemKind::Fn(func) => {
282+
if func.body.is_none() {
283+
return None;
284+
}
285+
}
286+
ItemKind::Static(stat) => {
287+
if stat.expr.is_none() {
288+
return None;
289+
}
290+
}
291+
_ => unreachable!("Target was checked earlier"),
292+
};
293+
294+
let eii_impl = EiiImpl {
281295
node_id: DUMMY_NODE_ID,
282296
inner_span: macro_name.span,
283297
eii_macro_path: ast::Path::from_ident(macro_name),
@@ -297,7 +311,18 @@ fn generate_default_func_impl(
297311
),
298312
impl_unsafe,
299313
}),
300-
});
314+
};
315+
316+
let mut item_kind = item_kind.clone();
317+
match &mut item_kind {
318+
ItemKind::Fn(func) => {
319+
func.eii_impls.push(eii_impl);
320+
}
321+
ItemKind::Static(stat) => {
322+
stat.eii_impls.push(eii_impl);
323+
}
324+
_ => unreachable!("Target was checked earlier"),
325+
};
301326

302327
let anon_mod = |span: Span, stmts: ThinVec<ast::Stmt>| {
303328
let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new()));
@@ -311,15 +336,12 @@ fn generate_default_func_impl(
311336
};
312337

313338
// const _: () = {
314-
// <orig fn>
339+
// <orig item>
315340
// }
316-
anon_mod(
341+
Some(anon_mod(
317342
item_span,
318-
thin_vec![ecx.stmt_item(
319-
item_span,
320-
ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
321-
),],
322-
)
343+
thin_vec![ecx.stmt_item(item_span, ecx.item(item_span, attrs, item_kind))],
344+
))
323345
}
324346

325347
/// Generates a foreign item, like
@@ -405,6 +427,8 @@ fn generate_foreign_static(mut stat: Box<ast::StaticItem>) -> ast::ForeignItemKi
405427
stat.safety = ast::Safety::Safe(stat.ident.span);
406428
}
407429

430+
stat.expr = None;
431+
408432
ast::ForeignItemKind::Static(stat)
409433
}
410434

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@ no-prefer-dynamic
2+
#![crate_type = "rlib"]
3+
#![feature(extern_item_impls)]
4+
5+
#[eii(eii1)]
6+
pub static DECL1: u64 = 5;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ no-prefer-dynamic
2+
//@ aux-build: decl_with_default.rs
3+
#![crate_type = "rlib"]
4+
#![feature(extern_item_impls)]
5+
6+
extern crate decl_with_default as decl;
7+
8+
#[decl::eii1]
9+
pub static EII1_IMPL: u64 = 10;

tests/ui/eii/static/default.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ run-pass
2+
//@ check-run-results
3+
//@ ignore-backends: gcc
4+
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
5+
//@ ignore-windows
6+
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
7+
//@ ignore-apple
8+
// Tests static EIIs with default implementations.
9+
10+
#![feature(extern_item_impls)]
11+
12+
#[eii(eii1)]
13+
pub static DECL1: u64 = 5;
14+
15+
fn main() {
16+
println!("{DECL1}");
17+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ only-apple
2+
//@ ignore-backends: gcc
3+
4+
#![feature(extern_item_impls)]
5+
#![crate_type = "lib"]
6+
#[eii(eii1)]
7+
pub static DECL1: u64 = 5;
8+
//~^ ERROR `#[eii]` cannot be used on statics with a value on Apple targets
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: `#[eii]` cannot be used on statics with a value on Apple targets
2+
--> $DIR/default_apple.rs:7:25
3+
|
4+
LL | pub static DECL1: u64 = 5;
5+
| ^
6+
|
7+
= note: see issue #157649 <https://github.com/rust-lang/rust/issues/157649> for more information
8+
9+
error: aborting due to 1 previous error
10+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ aux-build: decl_with_default.rs
2+
//@ run-pass
3+
//@ check-run-results
4+
//@ ignore-backends: gcc
5+
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
6+
//@ ignore-windows
7+
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
8+
//@ ignore-apple
9+
// Tests that a static EII default can be used from another crate.
10+
11+
extern crate decl_with_default;
12+
13+
fn main() {
14+
println!("{}", decl_with_default::DECL1);
15+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5

0 commit comments

Comments
 (0)