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
|
@ -3640,7 +3640,7 @@ impl<'hir> Item<'hir> {
|
|||
ItemKind::Const(ty, generics, body), (ty, generics, *body);
|
||||
|
||||
expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
ItemKind::Fn(sig, generics, body), (sig, generics, *body);
|
||||
ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body);
|
||||
|
||||
expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk);
|
||||
|
||||
|
@ -3768,7 +3768,15 @@ pub enum ItemKind<'hir> {
|
|||
/// A `const` item.
|
||||
Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
/// A function declaration.
|
||||
Fn(FnSig<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
Fn {
|
||||
sig: FnSig<'hir>,
|
||||
generics: &'hir Generics<'hir>,
|
||||
body: BodyId,
|
||||
/// Whether this function actually has a body.
|
||||
/// For functions without a body, `body` is synthesized (to avoid ICEs all over the
|
||||
/// compiler), but that code should never be translated.
|
||||
has_body: bool,
|
||||
},
|
||||
/// A MBE macro definition (`macro_rules!` or `macro`).
|
||||
Macro(&'hir ast::MacroDef, MacroKind),
|
||||
/// A module.
|
||||
|
@ -3819,7 +3827,7 @@ pub struct Impl<'hir> {
|
|||
impl ItemKind<'_> {
|
||||
pub fn generics(&self) -> Option<&Generics<'_>> {
|
||||
Some(match *self {
|
||||
ItemKind::Fn(_, ref generics, _)
|
||||
ItemKind::Fn { ref generics, .. }
|
||||
| ItemKind::TyAlias(_, ref generics)
|
||||
| ItemKind::Const(_, ref generics, _)
|
||||
| ItemKind::Enum(_, ref generics)
|
||||
|
@ -3838,7 +3846,7 @@ impl ItemKind<'_> {
|
|||
ItemKind::Use(..) => "`use` import",
|
||||
ItemKind::Static(..) => "static item",
|
||||
ItemKind::Const(..) => "constant item",
|
||||
ItemKind::Fn(..) => "function",
|
||||
ItemKind::Fn { .. } => "function",
|
||||
ItemKind::Macro(..) => "macro",
|
||||
ItemKind::Mod(..) => "module",
|
||||
ItemKind::ForeignMod { .. } => "extern block",
|
||||
|
@ -4004,7 +4012,7 @@ impl<'hir> OwnerNode<'hir> {
|
|||
match self {
|
||||
OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
||||
| OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
||||
| OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. })
|
||||
| OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
|
||||
| OwnerNode::ForeignItem(ForeignItem {
|
||||
kind: ForeignItemKind::Fn(fn_sig, _, _), ..
|
||||
}) => Some(fn_sig),
|
||||
|
@ -4016,7 +4024,7 @@ impl<'hir> OwnerNode<'hir> {
|
|||
match self {
|
||||
OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
||||
| OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
||||
| OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. })
|
||||
| OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
|
||||
| OwnerNode::ForeignItem(ForeignItem {
|
||||
kind: ForeignItemKind::Fn(fn_sig, _, _), ..
|
||||
}) => Some(fn_sig.decl),
|
||||
|
@ -4030,7 +4038,7 @@ impl<'hir> OwnerNode<'hir> {
|
|||
kind:
|
||||
ItemKind::Static(_, _, body)
|
||||
| ItemKind::Const(_, _, body)
|
||||
| ItemKind::Fn(_, _, body),
|
||||
| ItemKind::Fn { body, .. },
|
||||
..
|
||||
})
|
||||
| OwnerNode::TraitItem(TraitItem {
|
||||
|
@ -4206,7 +4214,7 @@ impl<'hir> Node<'hir> {
|
|||
match self {
|
||||
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
|
||||
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
|
||||
Some(fn_sig.decl)
|
||||
}
|
||||
|
@ -4236,7 +4244,7 @@ impl<'hir> Node<'hir> {
|
|||
match self {
|
||||
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
|
||||
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
|
||||
Some(fn_sig)
|
||||
}
|
||||
|
@ -4281,7 +4289,7 @@ impl<'hir> Node<'hir> {
|
|||
Node::Item(Item {
|
||||
owner_id,
|
||||
kind:
|
||||
ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),
|
||||
ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. },
|
||||
..
|
||||
})
|
||||
| Node::TraitItem(TraitItem {
|
||||
|
@ -4338,7 +4346,7 @@ impl<'hir> Node<'hir> {
|
|||
pub fn fn_kind(self) -> Option<FnKind<'hir>> {
|
||||
match self {
|
||||
Node::Item(i) => match i.kind {
|
||||
ItemKind::Fn(ref sig, ref generics, _) => {
|
||||
ItemKind::Fn { sig, generics, .. } => {
|
||||
Some(FnKind::ItemFn(i.ident, generics, sig.header))
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
@ -509,7 +509,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
|
|||
try_visit!(visitor.visit_generics(generics));
|
||||
try_visit!(visitor.visit_nested_body(body));
|
||||
}
|
||||
ItemKind::Fn(ref sig, ref generics, body_id) => {
|
||||
ItemKind::Fn { sig, generics, body: body_id, .. } => {
|
||||
try_visit!(visitor.visit_id(item.hir_id()));
|
||||
try_visit!(visitor.visit_fn(
|
||||
FnKind::ItemFn(item.ident, generics, sig.header),
|
||||
|
|
|
@ -106,7 +106,7 @@ impl Target {
|
|||
ItemKind::Use(..) => Target::Use,
|
||||
ItemKind::Static { .. } => Target::Static,
|
||||
ItemKind::Const(..) => Target::Const,
|
||||
ItemKind::Fn(..) => Target::Fn,
|
||||
ItemKind::Fn { .. } => Target::Fn,
|
||||
ItemKind::Macro(..) => Target::MacroDef,
|
||||
ItemKind::Mod(..) => Target::Mod,
|
||||
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue