Skip to content

Commit 607f7ce

Browse files
m-ou-sejdonszelmann
authored andcommitted
Update.
1 parent c728fde commit 607f7ce

File tree

10 files changed

+274
-57
lines changed

10 files changed

+274
-57
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -155,30 +155,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
155155
i: &ItemKind,
156156
) -> Vec<hir::Attribute> {
157157
match i {
158+
ItemKind::Fn(box Fn { eii_impl, .. }) if eii_impl.is_empty() => Vec::new(),
158159
ItemKind::Fn(box Fn { eii_impl, .. }) => {
159-
let mut eii_impls = ThinVec::new();
160-
for EIIImpl {
161-
node_id,
162-
eii_macro_path,
163-
impl_safety,
164-
span,
165-
inner_span,
166-
is_default,
167-
} in eii_impl
168-
{
169-
let did = self.lower_path_simple_eii(*node_id, eii_macro_path);
170-
eii_impls.push(rustc_attr_parsing::EIIImpl {
171-
eii_macro: did,
172-
span: self.lower_span(*span),
173-
inner_span: self.lower_span(*inner_span),
174-
impl_marked_unsafe: self
175-
.lower_safety(*impl_safety, hir::Safety::Safe)
176-
.is_unsafe(),
177-
is_default: *is_default,
178-
})
179-
}
180-
181-
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(eii_impls))]
160+
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(
161+
eii_impl
162+
.iter()
163+
.map(
164+
|EIIImpl {
165+
node_id,
166+
eii_macro_path,
167+
impl_safety,
168+
span,
169+
inner_span,
170+
is_default,
171+
}| {
172+
let did = self.lower_path_simple_eii(*node_id, eii_macro_path);
173+
rustc_attr_parsing::EIIImpl {
174+
eii_macro: did,
175+
span: self.lower_span(*span),
176+
inner_span: self.lower_span(*inner_span),
177+
impl_marked_unsafe: self
178+
.lower_safety(*impl_safety, hir::Safety::Safe)
179+
.is_unsafe(),
180+
is_default: *is_default,
181+
}
182+
},
183+
)
184+
.collect(),
185+
))]
182186
}
183187
ItemKind::MacroDef(MacroDef {
184188
eii_macro_for: Some(EIIMacroFor { extern_item_path, impl_unsafe }),
@@ -551,14 +555,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
551555
def_kind.descr(def_id.to_def_id())
552556
);
553557
};
554-
555-
let ast_macro_def = self.arena.alloc(ast::MacroDef {
558+
let macro_def = self.arena.alloc(ast::MacroDef {
556559
body,
557560
macro_rules: *macro_rules,
558561
eii_macro_for: None,
559562
});
560563

561-
hir::ItemKind::Macro(ident, ast_macro_def, macro_kind)
564+
hir::ItemKind::Macro(ident, macro_def, macro_kind)
562565
}
563566
ItemKind::Delegation(box delegation) => {
564567
debug_assert_ne!(ident.name, kw::Empty);

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
788788
sp: Span,
789789
print_visibility: impl FnOnce(&mut Self),
790790
) {
791+
if let Some(eii_macro_for) = &macro_def.eii_macro_for {
792+
self.word("#[eii_macro_for(");
793+
self.print_path(&eii_macro_for.extern_item_path, false, 0);
794+
if eii_macro_for.impl_unsafe {
795+
self.word(",");
796+
self.space();
797+
self.word("unsafe");
798+
}
799+
self.word(")]");
800+
self.hardbreak();
801+
}
791802
let (kw, has_bang) = if macro_def.macro_rules {
792803
("macro_rules", true)
793804
} else {

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
@@ -124,6 +124,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
124124
global_allocator: global_allocator::expand,
125125
test: test::expand_test,
126126
test_case: test::expand_test_case,
127+
eii: eii::eii,
127128
eii_macro_for: eii::eii_macro_for,
128129
eii_macro: eii::eii_macro,
129130
}

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
@@ -1041,21 +1041,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
10411041
"#[rustc_force_inline] forces a free function to be inlined"
10421042
),
10431043

1044-
gated!(
1045-
eii, Normal, template!(Word),
1046-
ErrorPreceding, EncodeCrossCrate::No,
1047-
eii_internals, "internally used to implement EII"
1048-
),
1049-
gated!(
1050-
eii_impl, Normal, template!(List: "/*opt*/ default"),
1051-
ErrorPreceding, EncodeCrossCrate::No,
1052-
eii_internals, "internally used to implement EII"
1053-
),
1054-
gated!(
1055-
eii_macro_for, Normal, template!(List: "path"),
1056-
ErrorPreceding, EncodeCrossCrate::No,
1057-
eii_internals, "internally used to implement EII"
1058-
),
10591044
// ==========================================================================
10601045
// Internal attributes, Testing:
10611046
// ==========================================================================

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;

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use rustc_trait_selection::traits::{
4040
use tracing::{debug, instrument};
4141
use {rustc_ast as ast, rustc_hir as hir};
4242

43-
use super::compare_eii::{compare_eii_function_types, compare_eii_predicate_entailment};
43+
use super::compare_eii::compare_eii_function_types;
4444
use crate::autoderef::Autoderef;
4545
use crate::collect::CollectItemTypesVisitor;
4646
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};

0 commit comments

Comments
 (0)