rust-lang/rust · critical

`Tuple` does not have an associated type: {:?}

Error message

`Tuple` does not have an associated type: {:?}

What it means

consider_builtin_tuple_candidate (normalizes_to.rs:694) panics unconditionally. The Tuple auto-trait (the built-in impl that lets tuple types satisfy the Fn call machinery) declares no associated types, so a NormalizesTo (projection) goal such as `<? as Tuple>::SomeAssoc` is semantically impossible. The dispatch in assembly/mod.rs routes trait goals to a real implementation in trait_goals.rs; if a projection goal for the Tuple trait ever reaches this normalizes_to.rs stub, it is an invariant violation in the solver's goal construction.

Source

Thrown at compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs:694

            ecx.cx(),
            goal_kind,
            tupled_inputs_ty.expect_ty(),
            tupled_upvars_ty.expect_ty(),
            coroutine_captures_by_ref_ty.expect_ty(),
            borrow_region.expect_region(),
        );

        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
            ecx.instantiate_normalizes_to_term(goal, upvars_ty.into())?;
            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
        })
    }

    fn consider_builtin_tuple_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        panic!("`Tuple` does not have an associated type: {:?}", goal);
    }

    fn consider_builtin_pointee_candidate(
        ecx: &mut EvalCtxt<'_, D>,
        goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        let cx = ecx.cx();
        let metadata_def_id = cx.require_projection_lang_item(SolverProjectionLangItem::Metadata);
        assert_eq!(
            ty::AliasTermKind::ProjectionTy { def_id: metadata_def_id },
            goal.predicate.alias.kind
        );
        let metadata_ty = match goal.predicate.self_ty().kind() {
            ty::Bool
            | ty::Char
            | ty::Int(..)
            | ty::Uint(..)
            | ty::Float(..)

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Update to the latest nightly; this path is unreachable from valid input, so a hit implies a compiler bug that gets fixed quickly.
  2. Disable -Znext-solver (remove the flag or use -Znext-solver=no) to fall back to the legacy solver.
  3. Capture the full ICE backtrace and the goal printed in the panic, then file it at https://github.com/rust-lang/rust/issues.
  4. Bisect nightly toolchains (rustup toolchain install nightly-YYYY-MM-DD) to find the commit that introduced the regression and include it in the report.
Defensive patterns

Strategy: type-guard

Validate before calling

// `Tuple` is an auto/marker trait with NO associated types.
// Anywhere you wrote `<X as Tuple>::Foo` -> remove it; this is always a bug.
// Valid: only use `Tuple` as a bound, never as a projection target.
fn accept_tuple<T: Tuple>() {} // OK

Type guard

// Reject at review-time: grep for `as Tuple>::` / `Tuple>::`.
// Type-level guard that the projection is never written:
const _: () = { fn _no_tuple_assoc<T: Tuple>() { /* do not reference <T as Tuple>::X */ } };

Prevention

When it happens

Trigger: A NormalizesTo goal whose trait_ref resolves to the Tuple lang item is passed to the next solver's builtin-candidate assembly, routing here instead of short-circuiting. This requires the solver to have built a projection goal against a trait that has no associated items — something well-formed user code cannot express directly.

Common situations: A nightly rustc regression in the next solver that misclassifies a goal kind; fuzzing or stress-testing the solver with adversarial projections; none of these arises from ordinary stable Rust code.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/d673d1279cc98475.json. Report an issue: GitHub.