Encode MIR for 'unreachable' non-generic fns

This commit is contained in:
Michael Goulet 2022-06-03 15:21:57 -07:00
parent e40d5e83dc
commit 15cccb97d6
3 changed files with 58 additions and 25 deletions

View File

@ -148,32 +148,15 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_))
| hir::TraitItemKind::Type(..) => false,
},
Some(Node::ImplItem(impl_item)) => {
match impl_item.kind {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Fn(..) => {
let attrs = self.tcx.codegen_fn_attrs(def_id);
let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) || attrs.requests_inline() {
true
} else {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let impl_did = self.tcx.hir().get_parent_item(hir_id);
// Check the impl. If the generics on the self
// type of the impl require inlining, this method
// does too.
match self.tcx.hir().expect_item(impl_did).kind {
hir::ItemKind::Impl { .. } => {
let generics = self.tcx.generics_of(impl_did);
generics.requires_monomorphization(self.tcx)
}
_ => false,
}
}
}
hir::ImplItemKind::TyAlias(_) => false,
Some(Node::ImplItem(impl_item)) => match impl_item.kind {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Fn(..) => {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let impl_did = self.tcx.hir().get_parent_item(hir_id);
method_might_be_inlined(self.tcx, impl_item, impl_did)
}
}
hir::ImplItemKind::TyAlias(_) => false,
},
Some(_) => false,
None => false, // This will happen for default methods.
}

View File

@ -0,0 +1,41 @@
use std::{ptr::NonNull, task::Poll};
struct TaskRef;
struct Header {
vtable: &'static Vtable,
}
struct Vtable {
poll: unsafe fn(TaskRef) -> Poll<()>,
deallocate: unsafe fn(NonNull<Header>),
}
// in the "Header" type, which is a private type in maitake
impl Header {
pub(crate) const fn new_stub() -> Self {
unsafe fn nop(_ptr: TaskRef) -> Poll<()> {
Poll::Pending
}
unsafe fn nop_deallocate(ptr: NonNull<Header>) {
unreachable!("stub task ({ptr:p}) should never be deallocated!");
}
Self { vtable: &Vtable { poll: nop, deallocate: nop_deallocate } }
}
}
// This is a public type in `maitake`
#[repr(transparent)]
#[cfg_attr(loom, allow(dead_code))]
pub struct TaskStub {
hdr: Header,
}
impl TaskStub {
/// Create a new unique stub [`Task`].
pub const fn new() -> Self {
Self { hdr: Header::new_stub() }
}
}

View File

@ -0,0 +1,9 @@
// build-pass
// aux-build:issue-97708-aux.rs
extern crate issue_97708_aux;
use issue_97708_aux::TaskStub;
static TASK_STUB: TaskStub = TaskStub::new();
fn main() {}