Skip to content

Commit 1adfb50

Browse files
m-ou-sejdonszelmann
authored andcommitted
Update.
1 parent b8bcc6d commit 1adfb50

File tree

11 files changed

+272
-76
lines changed

11 files changed

+272
-76
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -161,30 +161,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
161161
i: &ItemKind,
162162
) -> Vec<hir::Attribute> {
163163
match i {
164+
ItemKind::Fn(box Fn { eii_impl, .. }) if eii_impl.is_empty() => Vec::new(),
164165
ItemKind::Fn(box Fn { eii_impl, .. }) => {
165-
let mut eii_impls = ThinVec::new();
166-
for EIIImpl {
167-
node_id,
168-
eii_macro_path,
169-
impl_safety,
170-
span,
171-
inner_span,
172-
is_default,
173-
} in eii_impl
174-
{
175-
let did = self.lower_path_simple_eii(*node_id, eii_macro_path);
176-
eii_impls.push(rustc_attr_parsing::EIIImpl {
177-
eii_macro: did,
178-
span: self.lower_span(*span),
179-
inner_span: self.lower_span(*inner_span),
180-
impl_marked_unsafe: self
181-
.lower_safety(*impl_safety, hir::Safety::Safe)
182-
.is_unsafe(),
183-
is_default: *is_default,
184-
})
185-
}
186-
187-
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(eii_impls))]
166+
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(
167+
eii_impl
168+
.iter()
169+
.map(
170+
|EIIImpl {
171+
node_id,
172+
eii_macro_path,
173+
impl_safety,
174+
span,
175+
inner_span,
176+
is_default,
177+
}| {
178+
let did = self.lower_path_simple_eii(*node_id, eii_macro_path);
179+
rustc_attr_parsing::EIIImpl {
180+
eii_macro: did,
181+
span: self.lower_span(*span),
182+
inner_span: self.lower_span(*inner_span),
183+
impl_marked_unsafe: self
184+
.lower_safety(*impl_safety, hir::Safety::Safe)
185+
.is_unsafe(),
186+
is_default: *is_default,
187+
}
188+
},
189+
)
190+
.collect(),
191+
))]
188192
}
189193
ItemKind::MacroDef(MacroDef {
190194
eii_macro_for: Some(EIIMacroFor { extern_item_path, impl_unsafe }),
@@ -508,7 +512,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
508512
def_kind.descr(def_id.to_def_id())
509513
);
510514
};
511-
512515
let macro_def = self.arena.alloc(ast::MacroDef {
513516
body,
514517
macro_rules: *macro_rules,

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
781781
sp: Span,
782782
print_visibility: impl FnOnce(&mut Self),
783783
) {
784+
if let Some(eii_macro_for) = &macro_def.eii_macro_for {
785+
self.word("#[eii_macro_for(");
786+
self.print_path(&eii_macro_for.extern_item_path, false, 0);
787+
if eii_macro_for.impl_unsafe {
788+
self.word(",");
789+
self.space();
790+
self.word("unsafe");
791+
}
792+
self.word(")]");
793+
self.hardbreak();
794+
}
784795
let (kw, has_bang) = if macro_def.macro_rules {
785796
("macro_rules", true)
786797
} else {

compiler/rustc_attr_parsing/src/attributes/eii.rs

Lines changed: 0 additions & 21 deletions
This file was deleted.

compiler/rustc_builtin_macros/src/eii.rs

Lines changed: 204 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,209 @@
1-
use rustc_ast::{
2-
DUMMY_NODE_ID, DUMMY_NODE_ID, EIIImpl, EIIImpl, EIIMacroFor, EiiMacroFor, ItemKind, ItemKind,
3-
ast, ast,
4-
};
1+
use rustc_ast::ptr::P;
2+
use rustc_ast::token::{Delimiter, TokenKind};
3+
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
4+
use rustc_ast::{DUMMY_NODE_ID, EIIImpl, EIIMacroFor, ItemKind, ast, token, tokenstream};
55
use rustc_ast_pretty::pprust::path_to_string;
66
use rustc_expand::base::{Annotatable, ExtCtxt};
7-
use rustc_span::{Span, Span, kw, kw};
7+
use rustc_span::{Ident, Span, kw, sym};
8+
9+
/* ```rust
10+
11+
#[eii]
12+
fn panic_handler();
13+
14+
#[eii(panic_handler)]
15+
fn panic_handler();
16+
17+
#[eii(panic_handler, unsafe)]
18+
fn panic_handler();
19+
20+
// expansion:
21+
22+
extern "Rust" {
23+
fn panic_handler();
24+
}
25+
26+
#[rustc_builtin_macro(eii_macro)] // eii_macro_for: panic_handler
27+
macro panic_handler() {}
28+
29+
``` */
30+
pub(crate) fn eii(
31+
ecx: &mut ExtCtxt<'_>,
32+
span: Span,
33+
meta_item: &ast::MetaItem,
34+
item: Annotatable,
35+
) -> Vec<Annotatable> {
36+
let span = ecx.with_def_site_ctxt(span);
37+
38+
let Annotatable::Item(item) = item else {
39+
ecx.dcx()
40+
.emit_err(EIIMacroExpectedFunction { span, name: path_to_string(&meta_item.path) });
41+
return vec![item];
42+
};
43+
44+
let macro_name = if meta_item.is_word() {
45+
item.ident
46+
} else if let Some([first]) = meta_item.meta_item_list()
47+
&& let Some(m) = first.meta_item()
48+
&& m.path.segments.len() == 1
49+
{
50+
m.path.segments[0].ident
51+
} else {
52+
ecx.dcx().emit_err(EIIMacroExpectedMaxOneArgument {
53+
span: meta_item.span,
54+
name: path_to_string(&meta_item.path),
55+
});
56+
return vec![Annotatable::Item(item)];
57+
};
58+
59+
let item = item.into_inner();
60+
61+
let ast::Item {
62+
attrs,
63+
id: _,
64+
span: item_span,
65+
vis,
66+
ident: item_name,
67+
kind: ItemKind::Fn(mut func),
68+
tokens: _,
69+
} = item
70+
else {
71+
ecx.dcx()
72+
.emit_err(EIIMacroExpectedFunction { span, name: path_to_string(&meta_item.path) });
73+
return vec![Annotatable::Item(P(item))];
74+
};
75+
76+
let impl_unsafe = false; // TODO
77+
78+
let abi = match func.sig.header.ext {
79+
// extern "X" fn => extern "X" {}
80+
ast::Extern::Explicit(lit, _) => Some(lit),
81+
// extern fn => extern {}
82+
ast::Extern::Implicit(_) => None,
83+
// fn => extern "Rust" {}
84+
ast::Extern::None => Some(ast::StrLit {
85+
symbol: sym::Rust,
86+
suffix: None,
87+
symbol_unescaped: sym::Rust,
88+
style: ast::StrStyle::Cooked,
89+
span,
90+
}),
91+
};
92+
93+
// ABI has been moved to the extern {} block, so we remove it from the fn item.
94+
func.sig.header.ext = ast::Extern::None;
95+
96+
// And mark safe functions explicitly as `safe fn`.
97+
if func.sig.header.safety == ast::Safety::Default {
98+
func.sig.header.safety = ast::Safety::Safe(func.sig.span);
99+
}
100+
101+
// extern "…" { safe fn item(); }
102+
let extern_block = Annotatable::Item(P(ast::Item {
103+
attrs: ast::AttrVec::default(),
104+
id: ast::DUMMY_NODE_ID,
105+
span,
106+
vis: ast::Visibility { span, kind: ast::VisibilityKind::Inherited, tokens: None },
107+
ident: Ident::dummy(),
108+
kind: ast::ItemKind::ForeignMod(ast::ForeignMod {
109+
extern_span: span,
110+
safety: ast::Safety::Unsafe(span),
111+
abi,
112+
items: From::from([P(ast::ForeignItem {
113+
attrs,
114+
id: ast::DUMMY_NODE_ID,
115+
span: item_span,
116+
vis,
117+
ident: item_name,
118+
kind: ast::ForeignItemKind::Fn(func),
119+
tokens: None,
120+
})]),
121+
}),
122+
tokens: None,
123+
}));
124+
125+
let macro_def = Annotatable::Item(P(ast::Item {
126+
attrs: ast::AttrVec::from_iter([
127+
// #[eii_macro_for(item_name)]
128+
ast::Attribute {
129+
kind: ast::AttrKind::Normal(P(ast::NormalAttr {
130+
item: ast::AttrItem {
131+
unsafety: ast::Safety::Default,
132+
path: ast::Path::from_ident(Ident::new(sym::eii_macro_for, span)),
133+
args: ast::AttrArgs::Delimited(ast::DelimArgs {
134+
dspan: DelimSpan::from_single(span),
135+
delim: Delimiter::Parenthesis,
136+
tokens: TokenStream::new(vec![tokenstream::TokenTree::Token(
137+
token::Token::from_ast_ident(item_name),
138+
Spacing::Alone,
139+
)]),
140+
}),
141+
tokens: None,
142+
},
143+
tokens: None,
144+
})),
145+
id: ecx.sess.psess.attr_id_generator.mk_attr_id(),
146+
style: ast::AttrStyle::Outer,
147+
span,
148+
},
149+
// #[builtin_macro(eii_macro)]
150+
ast::Attribute {
151+
kind: ast::AttrKind::Normal(P(ast::NormalAttr {
152+
item: ast::AttrItem {
153+
unsafety: ast::Safety::Default,
154+
path: ast::Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)),
155+
args: ast::AttrArgs::Delimited(ast::DelimArgs {
156+
dspan: DelimSpan::from_single(span),
157+
delim: Delimiter::Parenthesis,
158+
tokens: TokenStream::new(vec![tokenstream::TokenTree::token_alone(
159+
token::TokenKind::Ident(sym::eii_macro, token::IdentIsRaw::No),
160+
span,
161+
)]),
162+
}),
163+
tokens: None,
164+
},
165+
tokens: None,
166+
})),
167+
id: ecx.sess.psess.attr_id_generator.mk_attr_id(),
168+
style: ast::AttrStyle::Outer,
169+
span,
170+
},
171+
]),
172+
id: ast::DUMMY_NODE_ID,
173+
span,
174+
// pub
175+
vis: ast::Visibility { span, kind: ast::VisibilityKind::Public, tokens: None },
176+
// macro macro_name
177+
ident: macro_name,
178+
kind: ast::ItemKind::MacroDef(ast::MacroDef {
179+
// { () => {} }
180+
body: P(ast::DelimArgs {
181+
dspan: DelimSpan::from_single(span),
182+
delim: Delimiter::Brace,
183+
tokens: TokenStream::from_iter([
184+
TokenTree::Delimited(
185+
DelimSpan::from_single(span),
186+
DelimSpacing::new(Spacing::Alone, Spacing::Alone),
187+
Delimiter::Parenthesis,
188+
TokenStream::default(),
189+
),
190+
TokenTree::token_alone(TokenKind::FatArrow, span),
191+
TokenTree::Delimited(
192+
DelimSpan::from_single(span),
193+
DelimSpacing::new(Spacing::Alone, Spacing::Alone),
194+
Delimiter::Brace,
195+
TokenStream::default(),
196+
),
197+
]),
198+
}),
199+
macro_rules: false,
200+
eii_macro_for: None,
201+
}),
202+
tokens: None,
203+
}));
204+
205+
vec![extern_block, macro_def]
206+
}
8207

9208
use crate::errors::{
10209
EIIMacroExpectedFunction, EIIMacroExpectedMaxOneArgument, EIIMacroForExpectedList,

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
123123
global_allocator: global_allocator::expand,
124124
test: test::expand_test,
125125
test_case: test::expand_test_case,
126+
eii: eii::eii,
126127
eii_macro_for: eii::eii_macro_for,
127128
eii_macro: eii::eii_macro,
128129
}

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
111111

112112
if let hir::Attribute::Parsed(p) = attr {
113113
match p {
114+
/*
115+
AttributeKind::EiiImpl(eii_macro) => {
116+
let Some(eii_extern_item) = find_attr!(
117+
tcx.get_all_attrs(eii_macro),
118+
AttributeKind::EiiMacroFor { eii_extern_item, .. } => *eii_extern_item
119+
) else {
120+
tcx.dcx().span_delayed_bug(attr.span(), "missing attr on EII macro");
121+
continue;
122+
};
123+
let _ = eii_extern_item; // XXX mangle as this item or something.
124+
}*/
114125
AttributeKind::Repr(reprs) => {
115126
codegen_fn_attrs.alignment = reprs
116127
.iter()
117128
.find_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None });
118129
}
119-
120130
_ => {}
121131
}
122132
}

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,21 +1021,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
10211021
"#[rustc_force_inline] forces a free function to be inlined"
10221022
),
10231023

1024-
gated!(
1025-
eii, Normal, template!(Word),
1026-
ErrorPreceding, EncodeCrossCrate::No,
1027-
eii_internals, "internally used to implement EII"
1028-
),
1029-
gated!(
1030-
eii_impl, Normal, template!(List: "/*opt*/ default"),
1031-
ErrorPreceding, EncodeCrossCrate::No,
1032-
eii_internals, "internally used to implement EII"
1033-
),
1034-
gated!(
1035-
eii_macro_for, Normal, template!(List: "path"),
1036-
ErrorPreceding, EncodeCrossCrate::No,
1037-
eii_internals, "internally used to implement EII"
1038-
),
10391024
// ==========================================================================
10401025
// Internal attributes, Testing:
10411026
// ==========================================================================

compiler/rustc_hir_analysis/src/check/compare_eii.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ use std::borrow::Cow;
22
use std::iter;
33

44
use rustc_data_structures::fx::FxIndexSet;
5-
use rustc_errors::{
6-
Applicability, E0050, E0053, E0053, E0053, struct_span_code_err, struct_span_code_err,
7-
struct_span_code_err,
8-
};
5+
use rustc_errors::{Applicability, E0050, E0053, struct_span_code_err};
96
use rustc_hir::def_id::{DefId, LocalDefId};
10-
use rustc_hir::{
11-
self as hir, self as hir, self as hir, FnSig, HirId, HirId, HirId, ItemKind, ItemKind, ItemKind,
12-
};
7+
use rustc_hir::{self as hir, FnSig, HirId, ItemKind};
138
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
149
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
1510
use rustc_middle::ty;
1611
use rustc_middle::ty::TyCtxt;
17-
use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeError, TypeError};
18-
use rustc_span::{ErrorGuaranteed, Ident, Span};
12+
use rustc_middle::ty::error::{ExpectedFound, TypeError};
13+
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
1914
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2015
use rustc_trait_selection::regions::InferCtxtRegionExt;
2116
use rustc_trait_selection::traits::ObligationCtxt;

0 commit comments

Comments
 (0)