rust-lang / rust-lang/rust

ICE from inductive cycle in specialization

Open
#147,507 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-coinduction A-specialization C-bug I-ICE P-medium regression-from-stable-to-stable T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
#![feature(specialization)]
#![allow(incomplete_features)]

trait Helper {}

struct Wrap<T>(T);
impl<T> Helper for Wrap<T> where Wrap<T>: Helper {}

trait Trait {
    fn method();
}
impl<T> Trait for T {
    default fn method() {}
}
impl<T: Helper> Trait for T {
    fn method() {}
}

fn call_method<T>() {
    T::method();
}

fn main() {
    call_method::<Wrap<i32>>();
}

My guess is that, after monomorphization, the trait solver tries to choose which trait impl of Trait to use. It finds the impl that goes through Helper. Then, the trait solver overflows while trying to figure out if the type implements Helper.

Using the next-solver does not fix this issue.

Meta

Reproducible on the playground with version 1.92.0-nightly (2025-10-08 b6f0945e4681bc4d2faa)

Error output
error: internal compiler error: compiler/rustc_middle/src/ty/instance.rs:579:21: failed to resolve instance for <Wrap<i32> as Trait>::method
  --> src/main.rs:20:5
   |
20 |     T::method();
   |     ^^^^^^^^^^^


thread 'rustc' (100) panicked at compiler/rustc_middle/src/ty/instance.rs:579:21:
Box<dyn Any>
Backtrace

stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
   2: <rustc_errors::DiagCtxtHandle>::span_bug::<rustc_span::span_encoding::Span, alloc::string::String>
   3: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>::{closure#0}
   4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}
   5: rustc_middle::ty::context::tls::with_context_opt::<rustc_middle::ty::context::tls::with_opt<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
   6: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
   7: <rustc_middle::ty::instance::Instance>::expect_resolve
   8: rustc_monomorphize::collector::items_of_instance
      [... omitted 1 frame ...]
   9: rustc_monomorphize::collector::collect_items_rec::{closure#0}
  10: rustc_monomorphize::collector::collect_items_rec
  11: rustc_monomorphize::collector::collect_items_rec
  12: rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure#0}
  13: rustc_monomorphize::partitioning::collect_and_partition_mono_items
      [... omitted 2 frames ...]
  14: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  15: <rustc_interface::queries::Linker>::codegen_and_build_linker
  16: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  17: <rustc_interface::passes::create_and_enter_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2} as core::ops::function::FnOnce<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy>, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once::{shim:vtable#0}
  18: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

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: please make sure that you have updated to the latest nightly

note: please attach the file at `/playground/rustc-ice-2025-10-09T04_33_22-98.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [items_of_instance] collecting items used by `call_method::<Wrap<i32>>`
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: could not compile `playground` (bin "playground")

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the ICE with the minimized specialization example, then inspect compiler/rustc_middle/src/ty/instance.rs at expect_resolve and the rustc_monomorphize collector's items_of_instance query. Trace how the Trait implementation is selected for Wrap and how the Helper cycle is handled; done means this case no longer reaches the internal compiler error.

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
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.