Skip to content

[DONT MERGE] externally implementable items #140010

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 41 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
94aff96
add map for eii ids in resolver
jdonszelmann Mar 10, 2025
305268a
eii_macro_for
jdonszelmann Mar 10, 2025
76a8f1d
some things work
jdonszelmann Mar 12, 2025
6679336
add some files
jdonszelmann Mar 12, 2025
eef8939
lowering doesn't error
jdonszelmann Mar 12, 2025
3d61264
lowering works
jdonszelmann Mar 12, 2025
2193301
tidy up things
jdonszelmann Mar 12, 2025
fa839c8
typecheck EII
jdonszelmann Mar 13, 2025
60b645d
rename compare fn
jdonszelmann Mar 14, 2025
9397189
unsafe impl
jdonszelmann Mar 14, 2025
163d12b
add tests
jdonszelmann Mar 14, 2025
1544eab
remove namespace check in nameres
jdonszelmann Mar 14, 2025
5be94ba
type checking works (with some tests) for EII
jdonszelmann Mar 14, 2025
7ee830f
test attr misuse
jdonszelmann Mar 14, 2025
14fb00b
propagate default
jdonszelmann Mar 14, 2025
c1df98d
Update.
m-ou-se Mar 17, 2025
e72ed5a
Move eii macros to prelude.
m-ou-se Mar 17, 2025
204a589
Add #[unsafe_eii].
m-ou-se Mar 17, 2025
52c31bb
Add eii macros to std preludes.
m-ou-se Mar 17, 2025
c423195
Update tests.
m-ou-se Mar 17, 2025
3cc5076
Allow builtin macros to be used more than once.
m-ou-se Mar 17, 2025
ff42eed
better error messages on cross-crate eiis
jdonszelmann Mar 17, 2025
4b8c94b
allow eii marked items to have a body which becomes a default
jdonszelmann Mar 31, 2025
cb3c389
codegen eii
jdonszelmann Mar 31, 2025
c5e9f12
test codegen of eii
jdonszelmann Mar 31, 2025
06da48a
tidy
jdonszelmann Mar 31, 2025
d988d70
broken tests after rebase?
jdonszelmann Apr 2, 2025
1e8100b
fix bug with resolving EIIs in hir lowering
jdonszelmann Apr 18, 2025
b3016cb
forward attributes on EII implementation functions
jdonszelmann Apr 18, 2025
b45f96a
remove again defkind EIIShim
jdonszelmann Apr 18, 2025
f41c8da
fix various bugs in EII (todo: absorb)
jdonszelmann Apr 18, 2025
7f09bd9
fix tests
jdonszelmann Apr 18, 2025
6da9baa
remove panic handler from compiler
jdonszelmann Apr 18, 2025
fefe20d
add feature gates for eii(-internals)
jdonszelmann Apr 18, 2025
08ca134
make linkage be external more often
jdonszelmann Apr 18, 2025
c747e71
include EIIs in used crates check
jdonszelmann Apr 18, 2025
1c7af70
fix clippy
jdonszelmann Apr 18, 2025
7db4f70
error codes
jdonszelmann May 9, 2025
774c09a
fix some nameres bugs
jdonszelmann May 9, 2025
3ab4ab3
fix error messages
jdonszelmann May 9, 2025
7c70314
fix fixmes
jdonszelmann May 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1951,6 +1951,15 @@ pub struct MacroDef {
pub body: P<DelimArgs>,
/// `true` if macro was defined with `macro_rules`.
pub macro_rules: bool,

pub eii_macro_for: Option<EIIMacroFor>,
}

#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct EIIMacroFor {
pub extern_item_path: Path,
pub impl_unsafe: bool,
pub span: Span,
}

#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
Expand Down Expand Up @@ -3578,6 +3587,19 @@ pub struct Fn {
pub contract: Option<P<FnContract>>,
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
pub body: Option<P<Block>>,

/// This fn implements some EII, pointed to by the `path`
pub eii_impl: ThinVec<EIIImpl>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
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)]
Expand Down Expand Up @@ -3927,7 +3949,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);
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,10 @@ fn walk_mac<T: MutVisitor>(vis: &mut T, mac: &mut MacCall) {
}

fn walk_macro_def<T: MutVisitor>(vis: &mut T, macro_def: &mut MacroDef) {
let MacroDef { body, macro_rules: _ } = macro_def;
let MacroDef { body, macro_rules: _, eii_macro_for } = macro_def;
if let Some(EIIMacroFor { extern_item_path, impl_unsafe: _, span: _ }) = eii_macro_for {
vis.visit_path(extern_item_path);
}
visit_delim_args(vis, body);
}

Expand Down Expand Up @@ -836,11 +839,17 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
body,
sig: FnSig { header, decl, span },
define_opaque,
eii_impl,
},
) => {
// Visibility is visited as a part of the item.
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);

for EIIImpl { node_id, eii_macro_path, .. } in eii_impl {
vis.visit_id(node_id);
vis.visit_path(eii_macro_path);
}
vis.visit_fn_header(header);
vis.visit_generics(generics);
vis.visit_fn_decl(decl);
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ pub enum BoundKind {
/// Trait bounds in trait object type.
/// E.g., `dyn Bound1 + Bound2 + Bound3`.
TraitObject,

/// Super traits of a trait.
/// E.g., `trait A: B`
SuperTraits,
Expand Down Expand Up @@ -479,7 +478,12 @@ impl WalkItemKind for ItemKind {
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ident, ts) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mac_def(ts, id))
try_visit!(visitor.visit_mac_def(ts, id));
if let Some(EIIMacroFor { extern_item_path, impl_unsafe: _, span: _ }) =
&ts.eii_macro_for
{
try_visit!(visitor.visit_path(extern_item_path, id));
}
}
ItemKind::Delegation(box Delegation {
id,
Expand Down Expand Up @@ -953,10 +957,16 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
contract,
body,
define_opaque,
eii_impl,
},
) => {
// Visibility is visited as a part of the item.
try_visit!(visitor.visit_ident(ident));

for EIIImpl { node_id, eii_macro_path, .. } in eii_impl {
try_visit!(visitor.visit_path(eii_macro_path, *node_id));
}

try_visit!(visitor.visit_fn_header(header));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_decl(decl));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
let span = self.lower_span(l.span);
let source = hir::LocalSource::Normal;
self.lower_attrs(hir_id, &l.attrs, l.span);
self.lower_attrs(hir_id, &l.attrs, l.span, &[]);
self.arena.alloc(hir::LetStmt { hir_id, super_, ty, pat, init, els, span, source })
}

Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

let expr_hir_id = self.lower_node_id(e.id);
self.lower_attrs(expr_hir_id, &e.attrs, e.span);
self.lower_attrs(expr_hir_id, &e.attrs, e.span, &[]);

let kind = match &e.kind {
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
Expand Down Expand Up @@ -679,7 +679,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond));
let hir_id = self.next_id();
let span = self.lower_span(arm.span);
self.lower_attrs(hir_id, &arm.attrs, arm.span);
self.lower_attrs(hir_id, &arm.attrs, arm.span, &[]);
let is_never_pattern = pat.is_never_pattern();
// We need to lower the body even if it's unneeded for never pattern in match,
// ensure that we can get HirId for DefId if need (issue #137708).
Expand Down Expand Up @@ -852,6 +852,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: unstable_span,
}],
span,
&[],
);
}
}
Expand Down Expand Up @@ -1690,7 +1691,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs, f.span);
self.lower_attrs(hir_id, &f.attrs, f.span, &[]);
hir::ExprField {
hir_id,
ident: self.lower_ident(f.ident),
Expand Down Expand Up @@ -1946,7 +1947,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
//
// Also, add the attributes to the outer returned expr node.
let expr = self.expr_drop_temps_mut(for_span, match_expr);
self.lower_attrs(expr.hir_id, &e.attrs, e.span);
self.lower_attrs(expr.hir_id, &e.attrs, e.span, &[]);
expr
}

Expand Down Expand Up @@ -2003,7 +2004,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let val_ident = Ident::with_dummy_span(sym::val);
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
self.lower_attrs(val_expr.hir_id, &attrs, span);
self.lower_attrs(val_expr.hir_id, &attrs, span, &[]);
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
};
Expand Down Expand Up @@ -2034,7 +2035,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ret_expr = self.checked_return(Some(from_residual_expr));
self.arena.alloc(self.expr(try_span, ret_expr))
};
self.lower_attrs(ret_expr.hir_id, &attrs, ret_expr.span);
self.lower_attrs(ret_expr.hir_id, &attrs, ret_expr.span, &[]);

let break_pat = self.pat_cf_break(try_span, residual_local);
self.arm(break_pat, ret_expr)
Expand Down
117 changes: 105 additions & 12 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use rustc_abi::ExternAbi;
use rustc_ast::ptr::P;
use rustc_ast::visit::AssocCtxt;
use rustc_ast::*;
use rustc_attr_parsing::{AttributeKind, EIIDecl};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
Expand Down Expand Up @@ -92,7 +93,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
self.with_lctx(CRATE_NODE_ID, |lctx| {
let module = lctx.lower_mod(&c.items, &c.spans);
// FIXME(jdonszelman): is dummy span ever a problem here?
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, &[]);
hir::OwnerNode::Crate(module)
})
}
Expand Down Expand Up @@ -146,11 +147,88 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn generate_extra_attrs_for_item_kind(
&mut self,
id: NodeId,
i: &ItemKind,
) -> Vec<hir::Attribute> {
match i {
ItemKind::Fn(box Fn { eii_impl, .. }) if eii_impl.is_empty() => Vec::new(),
ItemKind::Fn(box Fn { eii_impl, .. }) => {
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(
eii_impl
.iter()
.flat_map(
|EIIImpl {
node_id,
eii_macro_path,
impl_safety,
span,
inner_span,
is_default,
}| {
self.lower_path_simple_eii(*node_id, eii_macro_path).map(|did| {
rustc_attr_parsing::EIIImpl {
eii_macro: did,
span: self.lower_span(*span),
inner_span: self.lower_span(*inner_span),
impl_marked_unsafe: self
.lower_safety(*impl_safety, hir::Safety::Safe)
.is_unsafe(),
is_default: *is_default,
}
})
},
)
.collect(),
))]
}
ItemKind::MacroDef(
_,
MacroDef {
eii_macro_for: Some(EIIMacroFor { extern_item_path, impl_unsafe, span }),
..
},
) => self
.lower_path_simple_eii(id, extern_item_path)
.map(|did| {
vec![hir::Attribute::Parsed(AttributeKind::EiiMacroFor(EIIDecl {
eii_extern_item: did,
impl_unsafe: *impl_unsafe,
span: self.lower_span(*span),
}))]
})
.unwrap_or_default(),
ItemKind::ExternCrate(..)
| ItemKind::Use(..)
| ItemKind::Static(..)
| ItemKind::Const(..)
| ItemKind::Mod(..)
| ItemKind::ForeignMod(..)
| ItemKind::GlobalAsm(..)
| ItemKind::TyAlias(..)
| ItemKind::Enum(..)
| ItemKind::Struct(..)
| ItemKind::Union(..)
| ItemKind::Trait(..)
| ItemKind::TraitAlias(..)
| ItemKind::Impl(..)
| ItemKind::MacCall(..)
| ItemKind::MacroDef(..)
| ItemKind::Delegation(..)
| ItemKind::DelegationMac(..) => Vec::new(),
}
}

fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
let vis_span = self.lower_span(i.vis.span);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);

let extra_hir_attributes = self.generate_extra_attrs_for_item_kind(i.id, &i.kind);

let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, &extra_hir_attributes);
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);

let item = hir::Item {
owner_id: hir_id.expect_owner(),
kind,
Expand Down Expand Up @@ -462,7 +540,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
hir::ItemKind::TraitAlias(ident, generics, bounds)
}
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_macro_for: _ }) => {
let ident = self.lower_ident(*ident);
let body = P(self.lower_delim_args(body));
let def_id = self.local_def_id(id);
Expand All @@ -473,7 +551,12 @@ 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_macro_for: None,
});

hir::ItemKind::Macro(ident, macro_def, macro_kind)
}
ItemKind::Delegation(box delegation) => {
Expand All @@ -492,6 +575,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn lower_path_simple_eii(&mut self, id: NodeId, path: &Path) -> Option<DefId> {
let res = self.resolver.get_partial_res(id)?;
let Some(did) = res.expect_full_res().opt_def_id() else {
self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
return None;
};

Some(did)
}

fn lower_const_item(
&mut self,
ty: &Ty,
Expand Down Expand Up @@ -635,7 +728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let owner_id = hir_id.expect_owner();
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, &[]);
let (ident, kind) = match &i.kind {
ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
let fdec = &sig.decl;
Expand Down Expand Up @@ -709,7 +802,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let hir_id = self.lower_node_id(v.id);
self.lower_attrs(hir_id, &v.attrs, v.span);
self.lower_attrs(hir_id, &v.attrs, v.span, &[]);
hir::Variant {
hir_id,
def_id: self.local_def_id(v.id),
Expand Down Expand Up @@ -771,7 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::FieldDef<'hir> {
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs, f.span);
self.lower_attrs(hir_id, &f.attrs, f.span, &[]);
hir::FieldDef {
span: self.lower_span(f.span),
hir_id,
Expand All @@ -790,7 +883,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, &[]);
let trait_item_def_id = hir_id.expect_owner();

let (ident, generics, kind, has_default) = match &i.kind {
Expand Down Expand Up @@ -983,7 +1076,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, &[]);

let (ident, (generics, kind)) = match &i.kind {
AssocItemKind::Const(box ConstItem {
Expand Down Expand Up @@ -1176,7 +1269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs, param.span);
self.lower_attrs(hir_id, &param.attrs, param.span, &[]);
hir::Param {
hir_id,
pat: self.lower_pat(&param.pat),
Expand Down Expand Up @@ -1885,7 +1978,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
let hir_id = self.lower_node_id(pred.id);
let span = self.lower_span(pred.span);
self.lower_attrs(hir_id, &pred.attrs, span);
self.lower_attrs(hir_id, &pred.attrs, span, &[]);
let kind = self.arena.alloc(match &pred.kind {
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bound_generic_params,
Expand Down
Loading
Loading