Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Github: Repro: Reproduces in: Stable Linux - rustc 1.61.0 ( 2022-05-18) Nightly Linux - rustc 1.63.0-nightly ( 2022-06-02) <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
I'll see if I can make a smaller repro case
So, the minimal repro case is MUCH smaller: in : In : Which points to these code chunks: This seems to work in the tests for , so it seems like the ICE only triggers when used from an external trait. Additionally, this ICE does NOT trigger in .
CC
Yeah, this seems to occur specifically when trying to compile an external crate that calls this function. Lib tests inside the crate that call the function don't ICE, but adding an integration test (outside of the crate's compilation unit) does trigger the ICE:
If the function is made , the ICE no longer occurs. For example, this commit does not ICE:
prioritize
, if the functions are made but placed in a private module, they get culled again, triggering the ICE:
It also appears that if you move the functions out of the , AND mark them as , the ICE is also abated. See this PR for addressing:
For folks joining now/as a TL;DR, the offending code is basically this: The function produces a value, that gets created in a static: Which gets loaded into a static in user code: It LOOKS like somehow the two original functions (declared inside a private, const fn; inside a private type), are getting culled, which means that when the static (in another compilation unit) goes to be created, the MIR for those functions are missing.
This is likely a disagreement between . Though I don't know much about codegen.
Anyways I think I have a fix, though I am not certain it's the right one. In any case, I at least have a minimized UI test for rustc devs who know codegen better than me. PR incoming.

Discussion:
hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) | hir::TraitItemKind::Type(..) => false, }, <del> 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, </del> <ins> 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) </ins> } <del> } </del> <ins> hir::ImplItemKind::TyAlias(_) => false, }, </ins> Some(_) => false, None => false, // This will happen for default methods. }

<ins> 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() } } } </ins>

<ins> // 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() {} </ins>