EII ast changes
This commit is contained in:
parent
615acd8b4d
commit
2de02ac86e
14 changed files with 110 additions and 11 deletions
|
|
@ -2109,6 +2109,19 @@ pub struct MacroDef {
|
|||
pub body: Box<DelimArgs>,
|
||||
/// `true` if macro was defined with `macro_rules`.
|
||||
pub macro_rules: bool,
|
||||
|
||||
/// If this is a macro used for externally implementable items,
|
||||
/// it refers to an extern item which is its "target". This requires
|
||||
/// name resolution so can't just be an attribute, so we store it in this field.
|
||||
pub eii_extern_target: Option<EiiExternTarget>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
|
||||
pub struct EiiExternTarget {
|
||||
/// path to the extern item we're targetting
|
||||
pub extern_item_path: Path,
|
||||
pub impl_unsafe: bool,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
|
||||
|
|
@ -3748,6 +3761,21 @@ pub struct Fn {
|
|||
pub contract: Option<Box<FnContract>>,
|
||||
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
|
||||
pub body: Option<Box<Block>>,
|
||||
|
||||
/// This function is an implementation of an externally implementable item (EII).
|
||||
/// This means, there was an EII declared somewhere and this function is the
|
||||
/// implementation that should be run when the declaration is called.
|
||||
pub eii_impls: ThinVec<EiiImpl>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct EiiImpl {
|
||||
pub node_id: NodeId,
|
||||
pub eii_macro_path: Path,
|
||||
pub impl_safety: Safety,
|
||||
pub span: Span,
|
||||
pub inner_span: Span,
|
||||
pub is_default: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
|
|
@ -4114,7 +4142,7 @@ mod size_asserts {
|
|||
static_assert_size!(Block, 32);
|
||||
static_assert_size!(Expr, 72);
|
||||
static_assert_size!(ExprKind, 40);
|
||||
static_assert_size!(Fn, 184);
|
||||
static_assert_size!(Fn, 192);
|
||||
static_assert_size!(ForeignItem, 80);
|
||||
static_assert_size!(ForeignItemKind, 16);
|
||||
static_assert_size!(GenericArg, 24);
|
||||
|
|
|
|||
|
|
@ -393,6 +393,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
ThinVec<Pat>,
|
||||
ThinVec<Box<Ty>>,
|
||||
ThinVec<TyPat>,
|
||||
ThinVec<EiiImpl>,
|
||||
);
|
||||
|
||||
// This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable`
|
||||
|
|
@ -485,6 +486,8 @@ macro_rules! common_visitor_and_walkers {
|
|||
WhereEqPredicate,
|
||||
WhereRegionPredicate,
|
||||
YieldKind,
|
||||
EiiExternTarget,
|
||||
EiiImpl,
|
||||
);
|
||||
|
||||
/// Each method of this trait is a hook to be potentially
|
||||
|
|
@ -919,13 +922,13 @@ macro_rules! common_visitor_and_walkers {
|
|||
_ctxt,
|
||||
// Visibility is visited as a part of the item.
|
||||
_vis,
|
||||
Fn { defaultness, ident, sig, generics, contract, body, define_opaque },
|
||||
Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impls },
|
||||
) => {
|
||||
let FnSig { header, decl, span } = sig;
|
||||
visit_visitable!($($mut)? vis,
|
||||
defaultness, ident, header, generics, decl,
|
||||
contract, body, span, define_opaque
|
||||
)
|
||||
contract, body, span, define_opaque, eii_impls
|
||||
);
|
||||
}
|
||||
FnKind::Closure(binder, coroutine_kind, decl, body) =>
|
||||
visit_visitable!($($mut)? vis, binder, coroutine_kind, decl, body),
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
hir::ItemKind::TraitAlias(constness, ident, generics, bounds)
|
||||
}
|
||||
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
|
||||
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => {
|
||||
let ident = self.lower_ident(*ident);
|
||||
let body = Box::new(self.lower_delim_args(body));
|
||||
let def_id = self.local_def_id(id);
|
||||
|
|
@ -446,7 +446,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
def_kind.descr(def_id.to_def_id())
|
||||
);
|
||||
};
|
||||
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
|
||||
let macro_def = self.arena.alloc(ast::MacroDef {
|
||||
body,
|
||||
macro_rules: *macro_rules,
|
||||
eii_extern_target: None,
|
||||
});
|
||||
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
|
||||
}
|
||||
ItemKind::Delegation(box delegation) => {
|
||||
|
|
|
|||
|
|
@ -1179,11 +1179,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
contract: _,
|
||||
body,
|
||||
define_opaque: _,
|
||||
eii_impls,
|
||||
},
|
||||
) => {
|
||||
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
|
||||
for EiiImpl { eii_macro_path, .. } in eii_impls {
|
||||
self.visit_path(eii_macro_path);
|
||||
}
|
||||
|
||||
let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
|
||||
if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
|
||||
self.dcx().emit_err(errors::FnWithoutBody {
|
||||
|
|
|
|||
|
|
@ -865,6 +865,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||
sp: Span,
|
||||
print_visibility: impl FnOnce(&mut Self),
|
||||
) {
|
||||
if let Some(eii_extern_target) = ¯o_def.eii_extern_target {
|
||||
self.word("#[eii_extern_target(");
|
||||
self.print_path(&eii_extern_target.extern_item_path, false, 0);
|
||||
if eii_extern_target.impl_unsafe {
|
||||
self.word(",");
|
||||
self.space();
|
||||
self.word("unsafe");
|
||||
}
|
||||
self.word(")]");
|
||||
self.hardbreak();
|
||||
}
|
||||
let (kw, has_bang) = if macro_def.macro_rules {
|
||||
("macro_rules", true)
|
||||
} else {
|
||||
|
|
@ -2162,6 +2173,15 @@ impl<'a> State<'a> {
|
|||
|
||||
fn print_meta_item(&mut self, item: &ast::MetaItem) {
|
||||
let ib = self.ibox(INDENT_UNIT);
|
||||
|
||||
match item.unsafety {
|
||||
ast::Safety::Unsafe(_) => {
|
||||
self.word("unsafe");
|
||||
self.popen();
|
||||
}
|
||||
ast::Safety::Default | ast::Safety::Safe(_) => {}
|
||||
}
|
||||
|
||||
match &item.kind {
|
||||
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0),
|
||||
ast::MetaItemKind::NameValue(value) => {
|
||||
|
|
@ -2177,6 +2197,12 @@ impl<'a> State<'a> {
|
|||
self.pclose();
|
||||
}
|
||||
}
|
||||
|
||||
match item.unsafety {
|
||||
ast::Safety::Unsafe(_) => self.pclose(),
|
||||
ast::Safety::Default | ast::Safety::Safe(_) => {}
|
||||
}
|
||||
|
||||
self.end(ib);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use ast::StaticItem;
|
||||
use itertools::{Itertools, Position};
|
||||
use rustc_ast::{self as ast, ModKind, TraitAlias};
|
||||
use rustc_ast::{self as ast, EiiImpl, ModKind, Safety, TraitAlias};
|
||||
use rustc_span::Ident;
|
||||
|
||||
use crate::pp::BoxMarker;
|
||||
|
|
@ -671,10 +671,25 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
|
||||
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func;
|
||||
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impls } =
|
||||
func;
|
||||
|
||||
self.print_define_opaques(define_opaque.as_deref());
|
||||
|
||||
for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls {
|
||||
self.word("#[");
|
||||
if let Safety::Unsafe(..) = impl_safety {
|
||||
self.word("unsafe");
|
||||
self.popen();
|
||||
}
|
||||
self.print_path(eii_macro_path, false, 0);
|
||||
if let Safety::Unsafe(..) = impl_safety {
|
||||
self.pclose();
|
||||
}
|
||||
self.word("]");
|
||||
self.hardbreak();
|
||||
}
|
||||
|
||||
let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
|
||||
|
||||
self.print_visibility(vis);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
|
|||
contract: None,
|
||||
body,
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
}));
|
||||
|
||||
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
|
||||
|
|
|
|||
|
|
@ -346,6 +346,7 @@ mod llvm_enzyme {
|
|||
contract: None,
|
||||
body: Some(d_body),
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
});
|
||||
let mut rustc_ad_attr =
|
||||
Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
|
||||
|
|
|
|||
|
|
@ -1092,6 +1092,7 @@ impl<'a> MethodDef<'a> {
|
|||
contract: None,
|
||||
body: Some(body_block),
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
})),
|
||||
tokens: None,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ impl AllocFnFactory<'_, '_> {
|
|||
contract: None,
|
||||
body,
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
}));
|
||||
let item = self.cx.item(self.span, self.attrs(method), kind);
|
||||
self.cx.stmt_item(self.ty_span, item)
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
|
|||
contract: None,
|
||||
body: Some(main_body),
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
}));
|
||||
|
||||
let main = Box::new(ast::Item {
|
||||
|
|
|
|||
|
|
@ -1530,7 +1530,7 @@ impl<'a> CrateMetadataRef<'a> {
|
|||
.get((self, tcx), id)
|
||||
.unwrap()
|
||||
.decode((self, tcx));
|
||||
ast::MacroDef { macro_rules, body: Box::new(body) }
|
||||
ast::MacroDef { macro_rules, body: Box::new(body), eii_extern_target: None }
|
||||
}
|
||||
_ => bug!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ impl<'a> Parser<'a> {
|
|||
contract,
|
||||
body,
|
||||
define_opaque: None,
|
||||
eii_impls: ThinVec::new(),
|
||||
}))
|
||||
} else if self.eat_keyword_case(exp!(Extern), case) {
|
||||
if self.eat_keyword_case(exp!(Crate), case) {
|
||||
|
|
@ -2200,7 +2201,10 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
|
||||
Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
|
||||
Ok(ItemKind::MacroDef(
|
||||
ident,
|
||||
ast::MacroDef { body, macro_rules: false, eii_extern_target: None },
|
||||
))
|
||||
}
|
||||
|
||||
/// Is this a possibly malformed start of a `macro_rules! foo` item definition?
|
||||
|
|
@ -2247,7 +2251,10 @@ impl<'a> Parser<'a> {
|
|||
self.eat_semi_for_macro_if_needed(&body);
|
||||
self.complain_if_pub_macro(vis, true);
|
||||
|
||||
Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
|
||||
Ok(ItemKind::MacroDef(
|
||||
ident,
|
||||
ast::MacroDef { body, macro_rules: true, eii_extern_target: None },
|
||||
))
|
||||
}
|
||||
|
||||
/// Item macro invocations or `macro_rules!` definitions need inherited visibility.
|
||||
|
|
|
|||
|
|
@ -382,6 +382,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
contract: lc,
|
||||
body: lb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
Fn(box ast::Fn {
|
||||
defaultness: rd,
|
||||
|
|
@ -391,6 +392,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
contract: rc,
|
||||
body: rb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
) => {
|
||||
eq_defaultness(*ld, *rd)
|
||||
|
|
@ -554,6 +556,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
|||
contract: lc,
|
||||
body: lb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
Fn(box ast::Fn {
|
||||
defaultness: rd,
|
||||
|
|
@ -563,6 +566,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
|||
contract: rc,
|
||||
body: rb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
) => {
|
||||
eq_defaultness(*ld, *rd)
|
||||
|
|
@ -638,6 +642,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
|||
contract: lc,
|
||||
body: lb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
Fn(box ast::Fn {
|
||||
defaultness: rd,
|
||||
|
|
@ -647,6 +652,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
|||
contract: rc,
|
||||
body: rb,
|
||||
define_opaque: _,
|
||||
eii_impls: _,
|
||||
}),
|
||||
) => {
|
||||
eq_defaultness(*ld, *rd)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue