rust-lang/rust · critical

trait aliases do not have associated types: {:?}

Error message

trait aliases do not have associated types: {:?}

What it means

A `panic!` in `consider_trait_alias_candidate`. Trait aliases (`trait Foo = Bar<Baz>;`) are pure sugar that expands to a set of where-clauses; they cannot declare or project associated types. If a `NormalizesTo` goal (`<T as Foo>::Item`) is dispatched against a trait alias, the solver has no associated item to project, so it panics — this indicates dispatch routed a projection goal to the alias assembly by mistake.

Source

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

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

    fn consider_auto_trait_candidate(
        ecx: &mut EvalCtxt<'_, D>,
        _goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        ecx.cx().delay_bug("associated types not allowed on auto traits");
        Err(NoSolution.into())
    }

    fn consider_trait_alias_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        panic!("trait aliases do not have associated types: {:?}", goal);
    }

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

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

    fn consider_builtin_fn_ptr_trait_candidate(

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Rewrite the projection to use the concrete trait the alias expands to: replace `<T as MyAlias>::Item` with `<T as ConcreteTrait>::Item`.
  2. Ensure the alias does not accidentally appear as the `trait_id` of a projection; expand aliases before building `NormalizesTo` goals.
  3. If you maintain solver dispatch, confirm trait-alias candidates are skipped for `NormalizesTo` goals.

Example fix

// before — projecting an associated type through a trait alias
#![feature(trait_alias)]
trait Concrete { type Item; }
trait Alias = Concrete;
fn f<T: Alias>() -> T::Item { todo!() } // ICE / wrong
// after — project through the concrete trait
fn f<T: Concrete>() -> T::Item { todo!() }
Defensive patterns

Strategy: validation

Validate before calling

// Trait aliases are not allowed to have associated types. Detect a
// trait-alias DefId before projecting.
fn is_trait_alias(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
    matches!(tcx.def_kind(trait_def_id), DefKind::TraitAlias)
}
if is_trait_alias(tcx, did) {
    return Err("cannot project associated type from a trait alias");
}

Type guard

fn is_real_trait_not_alias(tcx: TyCtxt<'_>, did: DefId) -> bool {
    matches!(tcx.def_kind(did), DefKind::Trait)
}

Try / catch

use std::panic;
match panic::catch_unwind(panic::AssertUnwindSafe(|| solver.normalizes_to(goal))) {
    Ok(v) => v,
    Err(_) => Err("trait aliases carry no associated types; project through a concrete trait"),
}

Prevention

When it happens

Trigger: A `NormalizesTo` goal whose trait ref refers to a trait alias (the `trait_alias` feature) is assembled by the candidate logic that should only fire for concrete traits. Reproducible with `#![feature(trait_alias)]` plus an attempt to name an associated item on the alias.

Common situations: Users of `trait_alias` who write `<T as MyAlias>::Item` expecting the alias to carry the associated type of its target (it does not — you must use the concrete trait ref).

Related errors


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