Code
Edit: See the comment below for an unsoundness in both the old and new solvers.
The following code compiles in the old solver, but ICEs with -Znext-solver. I suspect that the code is unsound in the old solver, but I haven't yet figured out how.
Note that dyn Sub<DummyStruct> implements Super<i16, Assoc = i32> and Super<i16, Assoc = i64> due to the supertraits of Sub. This means that a single type has two different types for its associated type. This should be rejected somewhere.
cc @lcnr @ShoyuVanilla
trait Dummy {
type DummyAssoc1;
type DummyAssoc2;
}
struct DummyStruct;
impl Dummy for DummyStruct {
type DummyAssoc1 = i16;
type DummyAssoc2 = i16;
}
trait Super<T> {
type Assoc;
}
trait Sub<D: Dummy>: Super<D::DummyAssoc1, Assoc = i32> + Super<D::DummyAssoc2, Assoc = i64> {}
fn require_trait<D: Dummy, U: Super<D::DummyAssoc1> + ?Sized>() {}
fn use_dyn<D: Dummy>() {
require_trait::<D, dyn Sub<D>>();
}
pub fn weird() {
use_dyn::<DummyStruct>();
}
Meta
Reproducible on Godbolt with compiler version:
rustc 1.96.0-nightly (a25435bcf 2026-03-29)
binary: rustc
commit-hash: a25435bcf7cfc9b953d356eda3a51db8da9e3386
commit-date: 2026-03-29
host: x86_64-unknown-linux-gnu
release: 1.96.0-nightly
LLVM version: 22.1.2
Internal compiler ID: nightly
Error output
thread 'rustc' (3) panicked at /rustc-dev/a25435bcf7cfc9b953d356eda3a51db8da9e3386/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs:981:13:
could not replace AliasTerm { args: [dyn [Binder { value: Trait(Sub<!0>), bound_vars: [] }, Binder { value: Projection(ExistentialProjection { def_id: DefId(0:13 ~ example[2e03]::Super::Assoc), args: [Alias(Projection, AliasTy { args: [!0], def_id: DefId(0:5 ~ example[2e03]::Dummy::DummyAssoc2), .. })], term: Term::Ty(i64), .. }), bound_vars: [] }, Binder { value: Projection(ExistentialProjection { def_id: DefId(0:13 ~ example[2e03]::Super::Assoc), args: [Alias(Projection, AliasTy { args: [!0], def_id: DefId(0:4 ~ example[2e03]::Dummy::DummyAssoc1), .. })], term: Term::Ty(i32), .. }), bound_vars: [] }] + '?0, Alias(Projection, AliasTy { args: [!0], def_id: DefId(0:4 ~ example[2e03]::Dummy::DummyAssoc1), .. })], def_id: DefId(0:13 ~ example[2e03]::Super::Assoc), .. } with term from from dyn [Binder { value: Trait(Sub<!0>), bound_vars: [] }, Binder { value: Projection(ExistentialProjection { def_id: DefId(0:13 ~ example[2e03]::Super::Assoc), args: [Alias(Projection, AliasTy { args: [!0], def_id: DefId(0:5 ~ example[2e03]::Dummy::DummyAssoc2), .. })], term: Term::Ty(i64), .. }), bound_vars: [] }, Binder { value: Projection(ExistentialProjection { def_id: DefId(0:13 ~ example[2e03]::Super::Assoc), args: [Alias(Projection, AliasTy { args: [!0], def_id: DefId(0:4 ~ example[2e03]::Dummy::DummyAssoc1), .. })], term: Term::Ty(i32), .. }), bound_vars: [] }] + '?0
Backtrace
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: <rustc_next_trait_solver::solve::assembly::structural_traits::ReplaceProjectionWith<rustc_middle::ty::context::TyCtxt, rustc_trait_selection::solve::delegate::SolverDelegate> as rustc_type_ir::fold::FallibleTypeFolder<rustc_middle::ty::context::TyCtxt>>::try_fold_ty.cold
3: <&rustc_middle::ty::list::RawList<(), rustc_middle::ty::generic_args::GenericArg> as rustc_type_ir::fold::TypeFoldable<rustc_middle::ty::context::TyCtxt>>::try_fold_with::<rustc_next_trait_solver::solve::assembly::structural_traits::ReplaceProjectionWith<rustc_middle::ty::context::TyCtxt, rustc_trait_selection::solve::delegate::SolverDelegate>>
4: rustc_next_trait_solver::solve::assembly::structural_traits::predicates_for_object_candidate::<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>
5: <rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt> as rustc_next_trait_solver::solve::assembly::GoalKind<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::match_assumption::<<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt> as rustc_next_trait_solver::solve::assembly::GoalKind<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::probe_and_consider_object_bound_candidate::{closure#0}>
6: <rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt> as rustc_next_trait_solver::solve::assembly::GoalKind<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::probe_and_consider_object_bound_candidate
7: <rustc_next_trait_solver::solve::eval_ctxt::EvalCtxt<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::assemble_and_evaluate_candidates::<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt>>
8: <rustc_next_trait_solver::solve::eval_ctxt::EvalCtxt<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::compute_trait_goal
9: <rustc_next_trait_solver::solve::search_graph::SearchGraphDelegate<rustc_trait_selection::solve::delegate::SolverDelegate> as rustc_type_ir::search_graph::Delegate>::compute_goal::{closure#0}
10: <rustc_type_ir::search_graph::SearchGraph<rustc_next_trait_solver::solve::search_graph::SearchGraphDelegate<rustc_trait_selection::solve::delegate::SolverDelegate>, rustc_middle::ty::context::TyCtxt>>::evaluate_goal::{closure#0}::{closure#2}
11: <rustc_next_trait_solver::solve::eval_ctxt::EvalCtxt<rustc_trait_selection::solve::delegate::SolverDelegate, rustc_middle::ty::context::TyCtxt>>::evaluate_goal_raw
12: <rustc_trait_selection::solve::fulfill::FulfillmentCtxt<rustc_trait_selection::traits::FulfillmentError> as rustc_infer::traits::engine::TraitEngine<rustc_trait_selection::traits::FulfillmentError>>::try_evaluate_obligations
13: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_call
14: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
15: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_block
16: <rustc_hir_typeck::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
17: rustc_hir_typeck::check::check_fn
18: rustc_hir_typeck::typeck_with_inspect::{closure#0}
[... omitted 1 frame ...]
19: <rustc_middle::ty::context::TyCtxt>::par_hir_body_owners::<rustc_hir_analysis::check_crate::{closure#1}>::{closure#0}
20: rustc_hir_analysis::check_crate
21: rustc_interface::passes::analysis
22: rustc_query_impl::execution::try_execute_query::<rustc_middle::query::caches::SingleCache<rustc_middle::query::erase::ErasedData<[u8; 0]>>, false>
23: 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.
error: the compiler unexpectedly panicked. This is a bug
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 `/app/rustc-ice-2026-04-01T04_15_50-1.txt` to your bug report
note: rustc 1.96.0-nightly (a25435bcf 2026-03-29) running on x86_64-unknown-linux-gnu
note: compiler flags: -C debuginfo=2 -C llvm-args=--x86-asm-syntax=intel --crate-type rlib -Z next-solver
query stack during panic:
#0 [typeck_root] type-checking `use_dyn`
#1 [analysis] running analysis passes on crate `example`
end of query stack
Code
Edit: See the comment below for an unsoundness in both the old and new solvers.
The following code compiles in the old solver, but ICEs with
-Znext-solver. I suspect that the code is unsound in the old solver, but I haven't yet figured out how.Note that
dyn Sub<DummyStruct>implementsSuper<i16, Assoc = i32>andSuper<i16, Assoc = i64>due to the supertraits ofSub. This means that a single type has two different types for its associated type. This should be rejected somewhere.cc @lcnr @ShoyuVanilla
Meta
Reproducible on Godbolt with compiler version:
Error output
Backtrace