Skip to content

Commit 123ca16

Browse files
committed
EII ast changes
1 parent 23eec42 commit 123ca16

File tree

14 files changed

+111
-13
lines changed

14 files changed

+111
-13
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,19 @@ pub struct MacroDef {
20662066
pub body: Box<DelimArgs>,
20672067
/// `true` if macro was defined with `macro_rules`.
20682068
pub macro_rules: bool,
2069+
2070+
/// If this is a macro used for externally implementable items,
2071+
/// it refers to an extern item which is its "target". This requires
2072+
/// name resolution so can't just be an attribute, so we store it in this field.
2073+
pub eii_extern_target: Option<EiiExternTarget>,
2074+
}
2075+
2076+
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2077+
pub struct EiiExternTarget {
2078+
/// path to the extern item we're targetting
2079+
pub extern_item_path: Path,
2080+
pub impl_unsafe: bool,
2081+
pub span: Span,
20692082
}
20702083

20712084
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
@@ -3691,6 +3704,21 @@ pub struct Fn {
36913704
pub contract: Option<Box<FnContract>>,
36923705
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
36933706
pub body: Option<Box<Block>>,
3707+
3708+
/// This function is an implementation of an externally implementable item (EII).
3709+
/// This means, there was an EII declared somewhere and this function is the
3710+
/// implementation that should be run when the declaration is called.
3711+
pub eii_impls: ThinVec<EiiImpl>,
3712+
}
3713+
3714+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3715+
pub struct EiiImpl {
3716+
pub node_id: NodeId,
3717+
pub eii_macro_path: Path,
3718+
pub impl_safety: Safety,
3719+
pub span: Span,
3720+
pub inner_span: Span,
3721+
pub is_default: bool,
36943722
}
36953723

36963724
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
@@ -4038,7 +4066,7 @@ mod size_asserts {
40384066
static_assert_size!(Block, 32);
40394067
static_assert_size!(Expr, 72);
40404068
static_assert_size!(ExprKind, 40);
4041-
static_assert_size!(Fn, 184);
4069+
static_assert_size!(Fn, 192);
40424070
static_assert_size!(ForeignItem, 80);
40434071
static_assert_size!(ForeignItemKind, 16);
40444072
static_assert_size!(GenericArg, 24);

compiler/rustc_ast/src/visit.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ macro_rules! common_visitor_and_walkers {
392392
ThinVec<Box<Pat>>,
393393
ThinVec<Box<Ty>>,
394394
ThinVec<Box<TyPat>>,
395+
ThinVec<EiiImpl>,
395396
);
396397

397398
// This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable`
@@ -485,6 +486,8 @@ macro_rules! common_visitor_and_walkers {
485486
WhereEqPredicate,
486487
WhereRegionPredicate,
487488
YieldKind,
489+
EiiExternTarget,
490+
EiiImpl,
488491
);
489492

490493
/// Each method of this trait is a hook to be potentially
@@ -914,13 +917,13 @@ macro_rules! common_visitor_and_walkers {
914917
_ctxt,
915918
// Visibility is visited as a part of the item.
916919
_vis,
917-
Fn { defaultness, ident, sig, generics, contract, body, define_opaque },
920+
Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impls },
918921
) => {
919922
let FnSig { header, decl, span } = sig;
920923
visit_visitable!($($mut)? vis,
921924
defaultness, ident, header, generics, decl,
922-
contract, body, span, define_opaque
923-
)
925+
contract, body, span, define_opaque, eii_impls
926+
);
924927
}
925928
FnKind::Closure(binder, coroutine_kind, decl, body) =>
926929
visit_visitable!($($mut)? vis, binder, coroutine_kind, decl, body),

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
431431
);
432432
hir::ItemKind::TraitAlias(ident, generics, bounds)
433433
}
434-
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
434+
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => {
435435
let ident = self.lower_ident(*ident);
436436
let body = Box::new(self.lower_delim_args(body));
437437
let def_id = self.local_def_id(id);
@@ -442,7 +442,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
442442
def_kind.descr(def_id.to_def_id())
443443
);
444444
};
445-
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
445+
let macro_def = self.arena.alloc(ast::MacroDef {
446+
body,
447+
macro_rules: *macro_rules,
448+
eii_extern_target: None,
449+
});
446450
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
447451
}
448452
ItemKind::Delegation(box delegation) => {

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,13 +1053,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10531053
contract: _,
10541054
body,
10551055
define_opaque: _,
1056+
eii_impls,
10561057
},
10571058
) => {
10581059
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
10591060
self.check_defaultness(item.span, *defaultness);
10601061

1062+
for EiiImpl { eii_macro_path, .. } in eii_impls {
1063+
self.visit_path(eii_macro_path);
1064+
}
1065+
10611066
let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
1062-
if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
1067+
if body.is_none() && !is_intrinsic {
10631068
self.dcx().emit_err(errors::FnWithoutBody {
10641069
span: item.span,
10651070
replace_span: self.ending_semi_or_hi(item.span),

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
852852
sp: Span,
853853
print_visibility: impl FnOnce(&mut Self),
854854
) {
855+
if let Some(eii_extern_target) = &macro_def.eii_extern_target {
856+
self.word("#[eii_extern_target(");
857+
self.print_path(&eii_extern_target.extern_item_path, false, 0);
858+
if eii_extern_target.impl_unsafe {
859+
self.word(",");
860+
self.space();
861+
self.word("unsafe");
862+
}
863+
self.word(")]");
864+
self.hardbreak();
865+
}
855866
let (kw, has_bang) = if macro_def.macro_rules {
856867
("macro_rules", true)
857868
} else {
@@ -2141,6 +2152,15 @@ impl<'a> State<'a> {
21412152

21422153
fn print_meta_item(&mut self, item: &ast::MetaItem) {
21432154
let ib = self.ibox(INDENT_UNIT);
2155+
2156+
match item.unsafety {
2157+
ast::Safety::Unsafe(_) => {
2158+
self.word("unsafe");
2159+
self.popen();
2160+
}
2161+
ast::Safety::Default | ast::Safety::Safe(_) => {}
2162+
}
2163+
21442164
match &item.kind {
21452165
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0),
21462166
ast::MetaItemKind::NameValue(value) => {
@@ -2156,6 +2176,12 @@ impl<'a> State<'a> {
21562176
self.pclose();
21572177
}
21582178
}
2179+
2180+
match item.unsafety {
2181+
ast::Safety::Unsafe(_) => self.pclose(),
2182+
ast::Safety::Default | ast::Safety::Safe(_) => {}
2183+
}
2184+
21592185
self.end(ib);
21602186
}
21612187

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use ast::StaticItem;
22
use itertools::{Itertools, Position};
3-
use rustc_ast as ast;
4-
use rustc_ast::ModKind;
3+
use rustc_ast::{self as ast, EiiImpl, ModKind, Safety};
54
use rustc_span::Ident;
65

76
use crate::pp::BoxMarker;
@@ -675,10 +674,25 @@ impl<'a> State<'a> {
675674
}
676675

677676
fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
678-
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func;
677+
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impls } =
678+
func;
679679

680680
self.print_define_opaques(define_opaque.as_deref());
681681

682+
for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls {
683+
self.word("#[");
684+
if let Safety::Unsafe(..) = impl_safety {
685+
self.word("unsafe");
686+
self.popen();
687+
}
688+
self.print_path(eii_macro_path, false, 0);
689+
if let Safety::Unsafe(..) = impl_safety {
690+
self.pclose();
691+
}
692+
self.word("]");
693+
self.hardbreak();
694+
}
695+
682696
let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
683697

684698
self.print_visibility(vis);

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
8989
contract: None,
9090
body,
9191
define_opaque: None,
92+
eii_impls: ThinVec::new(),
9293
}));
9394

9495
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];

compiler/rustc_builtin_macros/src/autodiff.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ mod llvm_enzyme {
345345
contract: None,
346346
body: Some(d_body),
347347
define_opaque: None,
348+
eii_impls: ThinVec::new(),
348349
});
349350
let mut rustc_ad_attr =
350351
Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,7 @@ impl<'a> MethodDef<'a> {
10861086
contract: None,
10871087
body: Some(body_block),
10881088
define_opaque: None,
1089+
eii_impls: ThinVec::new(),
10891090
})),
10901091
tokens: None,
10911092
})

compiler/rustc_builtin_macros/src/global_allocator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl AllocFnFactory<'_, '_> {
8484
contract: None,
8585
body,
8686
define_opaque: None,
87+
eii_impls: ThinVec::new(),
8788
}));
8889
let item = self.cx.item(self.span, self.attrs(), kind);
8990
self.cx.stmt_item(self.ty_span, item)

0 commit comments

Comments
 (0)