rustc_intrinsic: support functions without body; they are implicitly marked as must-be-overridden
This commit is contained in:
parent
be65012aa3
commit
3cd3649c6c
19 changed files with 118 additions and 68 deletions
|
@ -222,6 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
decl,
|
||||
coroutine_kind,
|
||||
body.as_deref(),
|
||||
attrs,
|
||||
);
|
||||
|
||||
let itctx = ImplTraitContext::Universal;
|
||||
|
@ -233,7 +234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
header: this.lower_fn_header(*header, hir::Safety::Safe),
|
||||
span: this.lower_span(*fn_sig_span),
|
||||
};
|
||||
hir::ItemKind::Fn { sig, generics, body: body_id }
|
||||
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
|
||||
})
|
||||
}
|
||||
ItemKind::Mod(_, mod_kind) => match mod_kind {
|
||||
|
@ -439,6 +440,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
sig: delegation_results.sig,
|
||||
generics: delegation_results.generics,
|
||||
body: delegation_results.body_id,
|
||||
has_body: true,
|
||||
}
|
||||
}
|
||||
ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
|
||||
|
@ -747,7 +749,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);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let attrs = self.lower_attrs(hir_id, &i.attrs);
|
||||
let trait_item_def_id = hir_id.expect_owner();
|
||||
|
||||
let (generics, kind, has_default) = match &i.kind {
|
||||
|
@ -785,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
&sig.decl,
|
||||
sig.header.coroutine_kind,
|
||||
Some(body),
|
||||
attrs,
|
||||
);
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
|
@ -877,7 +880,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);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let attrs = self.lower_attrs(hir_id, &i.attrs);
|
||||
|
||||
let (generics, kind) = match &i.kind {
|
||||
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
|
||||
|
@ -900,6 +903,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
&sig.decl,
|
||||
sig.header.coroutine_kind,
|
||||
body.as_deref(),
|
||||
attrs,
|
||||
);
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
|
@ -1054,20 +1058,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
})
|
||||
}
|
||||
|
||||
fn lower_fn_body_block(
|
||||
&mut self,
|
||||
span: Span,
|
||||
decl: &FnDecl,
|
||||
body: Option<&Block>,
|
||||
) -> hir::BodyId {
|
||||
self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
|
||||
}
|
||||
|
||||
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
|
||||
match block {
|
||||
Some(block) => self.lower_block_expr(block),
|
||||
None => self.expr_err(span, self.dcx().has_errors().unwrap()),
|
||||
}
|
||||
fn lower_fn_body_block(&mut self, decl: &FnDecl, body: &Block) -> hir::BodyId {
|
||||
self.lower_fn_body(decl, |this| this.lower_block_expr(body))
|
||||
}
|
||||
|
||||
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
|
||||
|
@ -1089,9 +1081,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
decl: &FnDecl,
|
||||
coroutine_kind: Option<CoroutineKind>,
|
||||
body: Option<&Block>,
|
||||
attrs: &'hir [hir::Attribute],
|
||||
) -> hir::BodyId {
|
||||
let (Some(coroutine_kind), Some(body)) = (coroutine_kind, body) else {
|
||||
return self.lower_fn_body_block(span, decl, body);
|
||||
let Some(body) = body else {
|
||||
// Functions without a body are an error, except if this is an intrinsic. For those we
|
||||
// create a fake body so that the entire rest of the compiler doesn't have to deal with
|
||||
// this as a special case.
|
||||
return self.lower_fn_body(decl, |this| {
|
||||
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic) {
|
||||
let empty_block = hir::Block {
|
||||
hir_id: this.next_id(),
|
||||
stmts: &[],
|
||||
expr: None,
|
||||
rules: hir::BlockCheckMode::DefaultBlock,
|
||||
span,
|
||||
targeted_by_break: false,
|
||||
};
|
||||
let loop_ = hir::ExprKind::Loop(
|
||||
this.arena.alloc(empty_block),
|
||||
None,
|
||||
hir::LoopSource::Loop,
|
||||
span,
|
||||
);
|
||||
hir::Expr { hir_id: this.next_id(), kind: loop_, span }
|
||||
} else {
|
||||
this.expr_err(span, this.dcx().has_errors().unwrap())
|
||||
}
|
||||
});
|
||||
};
|
||||
let Some(coroutine_kind) = coroutine_kind else {
|
||||
// Typical case: not a coroutine.
|
||||
return self.lower_fn_body_block(decl, body);
|
||||
};
|
||||
self.lower_body(|this| {
|
||||
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue