[ICE]: broken MIR (`... NoSolution`) when a value with a `for<'a>` HRTB over a GAT is wrapped in a one-element array
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Start from rustc's own UI test tests/ui/closures/closure-capture-hrtb-gat-no-ice-120811.rs (//@ check-pass, the regression test for #120811). Wrap the by-value unary_frontier argument exchange in a one-element array - unary_frontier([exchange]), with unary_frontier taking [P; 1]. The for<'a> HRTB-over-GAT bound is untouched. This causes an ICE:
trait Container { type Item<'a>; }
impl Container for () { type Item<'a> = (); }
struct Exchange<C, F> { _marker: std::marker::PhantomData<(C, F)> }
fn exchange<C, F>(_: F) -> Exchange<C, F>
where
C: Container,
for<'a> F: FnMut(&C::Item<'a>),
{ unimplemented!() }
trait Parallelization<C> {}
impl<C, F> Parallelization<C> for Exchange<C, F> {}
fn unary_frontier<P: Parallelization<()>>(_f: [P; 1]) { let [_p] = _f; }
fn main() {
let exchange = exchange(|_| ());
unary_frontier([exchange]);
}
Reproduces on stable, beta, and nightly; the seed (//@ check-pass) keeps compiling on all three:
| channel | version | seed | rewritten |
|---|---|---|---|
| stable | 1.96.0 (ac68faa20 2026-05-25) | compiles | ICE |
| beta | 1.97.0-beta.5 (c04e321a9 2026-06-26) | compiles | ICE |
| nightly | 1.98.0-nightly (f46ec5218 2026-06-30) | compiles | ICE |
(On nightly the unnormalized projection prints as Alias(No, Alias { kind: Projection { .. }, args: [(), '^1] }) rather than stable/beta's Alias(AliasTy { args: [(), '^1], kind: Projection { .. } }) - a Debug-format difference only.)
Meta
rustc 1.96.0 (ac68faa20 2026-05-25)
binary: rustc
commit-hash: ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96
commit-date: 2026-05-25
host: aarch64-apple-darwin
release: 1.96.0
LLVM version: 22.1.2
Also reproduced on beta 1.97.0-beta.5 and nightly 1.98.0-nightly (f46ec5218 2026-06-30) (see the channel table above).
Error output
note: no errors encountered even though delayed bugs were created
note: those delayed bugs will now be shown as internal compiler errors
error: internal compiler error: broken MIR in DefId(0:25 ~ main[8f81]::main) ([move _5]): Exchange<(), Closure(DefId(0:26 ~ main[8f81]::main::{closure#0}), [i16, Binder { value: extern "RustCall" fn((&'^0 (),)), bound_vars: [Region(BrAnon), Region(BrAnon)] }, ()])> is not a subtype of Exchange<(), Closure(DefId(0:26 ~ main[8f81]::main::{closure#0}), [i16, Binder { value: extern "RustCall" fn((&'^0 Alias(AliasTy { args: [(), '^1], kind: Projection { def_id: DefId(0:4 ~ main[8f81]::Container::Item) }, .. }),)), bound_vars: [Region(BrAnon), Region(BrAnon)] }, ()])>: NoSolution
--> src/main.rs:19:20
|
19 | unary_frontier([exchange]);
| ^^^^^^^^^^
|
note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:2283:17
0: <std::backtrace::Backtrace>::create
1: <rustc_errors::DiagCtxtInner>::emit_diagnostic
2: <rustc_errors::DiagCtxtHandle>::emit_diagnostic
3: <rustc_span::ErrorGuaranteed as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
4: <rustc_errors::DiagCtxtHandle>::span_delayed_bug::<rustc_span::span_encoding::Span, alloc::string::String>
5: <rustc_borrowck::type_check::TypeChecker as rustc_middle::mir::visit::Visitor>::visit_rvalue
6: <rustc_borrowck::type_check::TypeChecker as rustc_middle::mir::visit::Visitor>::visit_statement
7: <rustc_borrowck::type_check::TypeChecker as rustc_middle::mir::visit::Visitor>::visit_body
8: rustc_borrowck::type_check::type_check
9: rustc_borrowck::borrowck_collect_region_constraints
10: <rustc_borrowck::root_cx::BorrowCheckRootCtxt>::do_mir_borrowck
11: rustc_borrowck::mir_borrowck
12: rustc_query_impl::execution::try_execute_query::<rustc_data_structures::vec_cache::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::ErasedData<[u8; 8]>, rustc_middle::dep_graph::graph::DepNodeIndex>, false>
13: rustc_query_impl::query_impl::mir_borrowck::execute_query_non_incr::__rust_end_short_backtrace
14: <rustc_middle::ty::context::TyCtxt>::par_hir_body_owners::<rustc_interface::passes::run_required_analyses::{closure#2}::{closure#0}>::{closure#0}
15: rustc_interface::passes::analysis
16: rustc_query_impl::execution::try_execute_query::<rustc_middle::query::caches::SingleCache<rustc_middle::query::erase::ErasedData<[u8; 0]>>, false>
17: rustc_query_impl::query_impl::analysis::execute_query_non_incr::__rust_end_short_backtrace
18: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>
19: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
20: std::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
21: <std::thread::lifecycle::spawn_unchecked<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
22: <std::sys::thread::unix::Thread>::new::thread_start
23: __pthread_cond_wait
--> src/main.rs:19:20
|
19 | unary_frontier([exchange]);
| ^^^^^^^^^^
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: rustc 1.96.0 (ac68faa20 2026-05-25) running on aarch64-apple-darwin
query stack during panic:
end of query stack
Backtrace
<backtrace>
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with tests/ui/closures/closure-capture-hrtb-gat-no-ice-120811.rs and reproduce the array-wrapped variant from the issue. Read the borrow-checking path at compiler/rustc_borrowck/src/type_check/mod.rs, especially the reported delayed-bug location. Done means the reduced case no longer produces an ICE while the original check-pass test remains passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100