Skip to content

Commit 2de02ac

Browse files
committed
EII ast changes
1 parent 615acd8 commit 2de02ac

File tree

14 files changed

+110
-11
lines changed

14 files changed

+110
-11
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,19 @@ pub struct MacroDef {
21092109
pub body: Box<DelimArgs>,
21102110
/// `true` if macro was defined with `macro_rules`.
21112111
pub macro_rules: bool,
2112+
2113+
/// If this is a macro used for externally implementable items,
2114+
/// it refers to an extern item which is its "target". This requires
2115+
/// name resolution so can't just be an attribute, so we store it in this field.
2116+
pub eii_extern_target: Option<EiiExternTarget>,
2117+
}
2118+
2119+
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2120+
pub struct EiiExternTarget {
2121+
/// path to the extern item we're targetting
2122+
pub extern_item_path: Path,
2123+
pub impl_unsafe: bool,
2124+
pub span: Span,
21122125
}
21132126

21142127
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
@@ -3748,6 +3761,21 @@ pub struct Fn {
37483761
pub contract: Option<Box<FnContract>>,
37493762
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
37503763
pub body: Option<Box<Block>>,
3764+
3765+
/// This function is an implementation of an externally implementable item (EII).
3766+
/// This means, there was an EII declared somewhere and this function is the
3767+
/// implementation that should be run when the declaration is called.
3768+
pub eii_impls: ThinVec<EiiImpl>,
3769+
}
3770+
3771+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3772+
pub struct EiiImpl {
3773+
pub node_id: NodeId,
3774+
pub eii_macro_path: Path,
3775+
pub impl_safety: Safety,
3776+
pub span: Span,
3777+
pub inner_span: Span,
3778+
pub is_default: bool,
37513779
}
37523780

37533781
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
@@ -4114,7 +4142,7 @@ mod size_asserts {
41144142
static_assert_size!(Block, 32);
41154143
static_assert_size!(Expr, 72);
41164144
static_assert_size!(ExprKind, 40);
4117-
static_assert_size!(Fn, 184);
4145+
static_assert_size!(Fn, 192);
41184146
static_assert_size!(ForeignItem, 80);
41194147
static_assert_size!(ForeignItemKind, 16);
41204148
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
@@ -393,6 +393,7 @@ macro_rules! common_visitor_and_walkers {
393393
ThinVec<Pat>,
394394
ThinVec<Box<Ty>>,
395395
ThinVec<TyPat>,
396+
ThinVec<EiiImpl>,
396397
);
397398

398399
// 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
@@ -919,13 +922,13 @@ macro_rules! common_visitor_and_walkers {
919922
_ctxt,
920923
// Visibility is visited as a part of the item.
921924
_vis,
922-
Fn { defaultness, ident, sig, generics, contract, body, define_opaque },
925+
Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impls },
923926
) => {
924927
let FnSig { header, decl, span } = sig;
925928
visit_visitable!($($mut)? vis,
926929
defaultness, ident, header, generics, decl,
927-
contract, body, span, define_opaque
928-
)
930+
contract, body, span, define_opaque, eii_impls
931+
);
929932
}
930933
FnKind::Closure(binder, coroutine_kind, decl, body) =>
931934
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
@@ -435,7 +435,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
435435
);
436436
hir::ItemKind::TraitAlias(constness, ident, generics, bounds)
437437
}
438-
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
438+
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => {
439439
let ident = self.lower_ident(*ident);
440440
let body = Box::new(self.lower_delim_args(body));
441441
let def_id = self.local_def_id(id);
@@ -446,7 +446,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
446446
def_kind.descr(def_id.to_def_id())
447447
);
448448
};
449-
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
449+
let macro_def = self.arena.alloc(ast::MacroDef {
450+
body,
451+
macro_rules: *macro_rules,
452+
eii_extern_target: None,
453+
});
450454
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
451455
}
452456
ItemKind::Delegation(box delegation) => {

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,11 +1179,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11791179
contract: _,
11801180
body,
11811181
define_opaque: _,
1182+
eii_impls,
11821183
},
11831184
) => {
11841185
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
11851186
self.check_defaultness(item.span, *defaultness);
11861187

1188+
for EiiImpl { eii_macro_path, .. } in eii_impls {
1189+
self.visit_path(eii_macro_path);
1190+
}
1191+
11871192
let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
11881193
if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
11891194
self.dcx().emit_err(errors::FnWithoutBody {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
865865
sp: Span,
866866
print_visibility: impl FnOnce(&mut Self),
867867
) {
868+
if let Some(eii_extern_target) = &macro_def.eii_extern_target {
869+
self.word("#[eii_extern_target(");
870+
self.print_path(&eii_extern_target.extern_item_path, false, 0);
871+
if eii_extern_target.impl_unsafe {
872+
self.word(",");
873+
self.space();
874+
self.word("unsafe");
875+
}
876+
self.word(")]");
877+
self.hardbreak();
878+
}
868879
let (kw, has_bang) = if macro_def.macro_rules {
869880
("macro_rules", true)
870881
} else {
@@ -2162,6 +2173,15 @@ impl<'a> State<'a> {
21622173

21632174
fn print_meta_item(&mut self, item: &ast::MetaItem) {
21642175
let ib = self.ibox(INDENT_UNIT);
2176+
2177+
match item.unsafety {
2178+
ast::Safety::Unsafe(_) => {
2179+
self.word("unsafe");
2180+
self.popen();
2181+
}
2182+
ast::Safety::Default | ast::Safety::Safe(_) => {}
2183+
}
2184+
21652185
match &item.kind {
21662186
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0),
21672187
ast::MetaItemKind::NameValue(value) => {
@@ -2177,6 +2197,12 @@ impl<'a> State<'a> {
21772197
self.pclose();
21782198
}
21792199
}
2200+
2201+
match item.unsafety {
2202+
ast::Safety::Unsafe(_) => self.pclose(),
2203+
ast::Safety::Default | ast::Safety::Safe(_) => {}
2204+
}
2205+
21802206
self.end(ib);
21812207
}
21822208

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

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

66
use crate::pp::BoxMarker;
@@ -671,10 +671,25 @@ impl<'a> State<'a> {
671671
}
672672

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

676677
self.print_define_opaques(define_opaque.as_deref());
677678

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

680695
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
@@ -90,6 +90,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
9090
contract: None,
9191
body,
9292
define_opaque: None,
93+
eii_impls: ThinVec::new(),
9394
}));
9495

9596
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
@@ -346,6 +346,7 @@ mod llvm_enzyme {
346346
contract: None,
347347
body: Some(d_body),
348348
define_opaque: None,
349+
eii_impls: ThinVec::new(),
349350
});
350351
let mut rustc_ad_attr =
351352
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
@@ -1092,6 +1092,7 @@ impl<'a> MethodDef<'a> {
10921092
contract: None,
10931093
body: Some(body_block),
10941094
define_opaque: None,
1095+
eii_impls: ThinVec::new(),
10951096
})),
10961097
tokens: None,
10971098
})

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(method), kind);
8990
self.cx.stmt_item(self.ty_span, item)

0 commit comments

Comments
 (0)