rust-lang / rust-lang/rust

Conflicting supertrait associated type in dyn causes unsoundness and ICE

Open
#154,662 9 comments 0 reactions 1 assignee View on GitHub

@theemathas is already working on this.

Since Jun 9, 2026.

A-associated-items A-dyn-trait A-trait-system C-bug I-ICE I-unsound P-high T-compiler T-types WG-trait-system-refactor
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.