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:
@@ -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, ..) => {
|
||||
|
||||
Reference in New Issue
Block a user