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
|
@ -634,7 +634,7 @@ impl<'hir> Map<'hir> {
|
|||
for (hir_id, node) in self.parent_iter(hir_id) {
|
||||
if let Node::Item(Item {
|
||||
kind:
|
||||
ItemKind::Fn(..)
|
||||
ItemKind::Fn { .. }
|
||||
| ItemKind::Const(..)
|
||||
| ItemKind::Static(..)
|
||||
| ItemKind::Mod(..)
|
||||
|
@ -823,7 +823,7 @@ impl<'hir> Map<'hir> {
|
|||
|
||||
let span = match self.tcx.hir_node(hir_id) {
|
||||
// Function-like.
|
||||
Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
|
||||
Node::Item(Item { kind: ItemKind::Fn { sig, .. }, span: outer_span, .. })
|
||||
| Node::TraitItem(TraitItem {
|
||||
kind: TraitItemKind::Fn(sig, ..),
|
||||
span: outer_span,
|
||||
|
@ -1149,7 +1149,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
|||
ItemKind::Use(..) => "use",
|
||||
ItemKind::Static(..) => "static",
|
||||
ItemKind::Const(..) => "const",
|
||||
ItemKind::Fn(..) => "fn",
|
||||
ItemKind::Fn { .. } => "fn",
|
||||
ItemKind::Macro(..) => "macro",
|
||||
ItemKind::Mod(..) => "mod",
|
||||
ItemKind::ForeignMod { .. } => "foreign mod",
|
||||
|
|
|
@ -1778,9 +1778,16 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
|
|||
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
||||
|| tcx.has_attr(def_id, sym::rustc_intrinsic))
|
||||
{
|
||||
let must_be_overridden = tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden)
|
||||
|| match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => {
|
||||
!has_body
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
Some(ty::IntrinsicDef {
|
||||
name: tcx.item_name(def_id.into()),
|
||||
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
|
||||
must_be_overridden,
|
||||
const_stable: tcx.has_attr(def_id, sym::rustc_intrinsic_const_stable_indirect),
|
||||
})
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue