Auto merge of #135031 - RalfJung:intrinsics-without-body, r=oli-obk
rustc_intrinsic: support functions without body We synthesize a HIR body `loop {}` but such bodyless intrinsics. Most of the diff is due to turning `ItemKind::Fn` into a brace (named-field) enum variant, because it carries a `bool`-typed field now. This is to remember whether the function has a body. MIR building panics to avoid ever translating the fake `loop {}` body, and the intrinsic logic uses the lack of a body to implicitly mark that intrinsic as must-be-overridden. I first tried actually having no body rather than generating the fake body, but there's a *lot* of code that assumes that all function items have HIR and MIR, so this didn't work very well. Then I noticed that even `rustc_intrinsic_must_be_overridden` intrinsics have MIR generated (they are filled with an `Unreachable` terminator) so I guess I am not the first to discover this. ;) r? `@oli-obk`
This commit is contained in:
commit
fd127a3a84
81 changed files with 272 additions and 175 deletions
|
@ -44,7 +44,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
return None;
|
||||
}
|
||||
match tcx.hir_node_by_def_id(def_id.expect_local()) {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) => {
|
||||
generics.params.is_empty().not().then_some(generics.span)
|
||||
}
|
||||
_ => {
|
||||
|
@ -58,7 +58,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
return None;
|
||||
}
|
||||
match tcx.hir_node_by_def_id(def_id.expect_local()) {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) => {
|
||||
Some(generics.where_clause_span)
|
||||
}
|
||||
_ => {
|
||||
|
@ -79,7 +79,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
return None;
|
||||
}
|
||||
match tcx.hir_node_by_def_id(def_id.expect_local()) {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. }) => {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) => {
|
||||
Some(fn_sig.decl.output.span())
|
||||
}
|
||||
_ => {
|
||||
|
@ -201,7 +201,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|||
match start_t.kind() {
|
||||
ty::FnDef(..) => {
|
||||
if let Node::Item(it) = tcx.hir_node(start_id) {
|
||||
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
|
||||
if let hir::ItemKind::Fn { sig, generics, .. } = &it.kind {
|
||||
let mut error = false;
|
||||
if !generics.params.is_empty() {
|
||||
tcx.dcx().emit_err(errors::StartFunctionParameters { span: generics.span });
|
||||
|
|
|
@ -26,7 +26,7 @@ fn equate_intrinsic_type<'tcx>(
|
|||
sig: ty::PolyFnSig<'tcx>,
|
||||
) {
|
||||
let (generics, span) = match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. })
|
||||
| hir::Node::ForeignItem(hir::ForeignItem {
|
||||
kind: hir::ForeignItemKind::Fn(_, _, generics),
|
||||
..
|
||||
|
|
|
@ -293,7 +293,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
|||
}
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Fn(ref sig, ..) => {
|
||||
hir::ItemKind::Fn { sig, .. } => {
|
||||
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl)
|
||||
}
|
||||
hir::ItemKind::Static(ty, ..) => {
|
||||
|
|
|
@ -795,7 +795,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
}
|
||||
}
|
||||
|
||||
hir::ItemKind::Fn(..) => {
|
||||
hir::ItemKind::Fn { .. } => {
|
||||
tcx.ensure().generics_of(def_id);
|
||||
tcx.ensure().type_of(def_id);
|
||||
tcx.ensure().predicates_of(def_id);
|
||||
|
@ -1325,7 +1325,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
|
|||
generics,
|
||||
..
|
||||
})
|
||||
| Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), .. }) => {
|
||||
| Item(hir::Item { kind: ItemKind::Fn { sig, generics, .. }, .. }) => {
|
||||
lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
|
||||
}
|
||||
|
||||
|
|
|
@ -969,7 +969,7 @@ pub(super) fn const_conditions<'tcx>(
|
|||
{
|
||||
Node::Item(item) => match item.kind {
|
||||
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
|
||||
hir::ItemKind::Fn(_, generics, _) => (generics, None, false),
|
||||
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
|
||||
hir::ItemKind::Trait(_, _, generics, supertraits, _) => {
|
||||
(generics, Some((item.owner_id.def_id, supertraits)), false)
|
||||
}
|
||||
|
|
|
@ -660,7 +660,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
match item.kind {
|
||||
hir::ItemKind::Fn(_, generics, _) => {
|
||||
hir::ItemKind::Fn { generics, .. } => {
|
||||
self.visit_early_late(item.hir_id(), generics, |this| {
|
||||
intravisit::walk_item(this, item);
|
||||
});
|
||||
|
@ -1379,7 +1379,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
} else if let Some(body_id) = outermost_body {
|
||||
let fn_id = self.tcx.hir().body_owner(body_id);
|
||||
match self.tcx.hir_node(fn_id) {
|
||||
Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn(..), .. })
|
||||
Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn { .. }, .. })
|
||||
| Node::TraitItem(hir::TraitItem {
|
||||
owner_id,
|
||||
kind: hir::TraitItemKind::Fn(..),
|
||||
|
|
|
@ -294,7 +294,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
}
|
||||
_ => icx.lower_ty(*self_ty),
|
||||
},
|
||||
ItemKind::Fn(..) => {
|
||||
ItemKind::Fn { .. } => {
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
|
|
|
@ -189,9 +189,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// 2. Functions inside trait blocks
|
||||
// 3. Functions inside impl blocks
|
||||
let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
|
||||
(sig, generics)
|
||||
}
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn { sig, generics, .. }, ..
|
||||
}) => (sig, generics),
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(sig, _),
|
||||
generics,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue