rust-lang/rust · critical

expected free alias, found {kind:?}

Error message

expected free alias, found {kind:?}

What it means

`normalize_free_alias` (free_alias.rs) normalizes top-level type aliases and const aliases gated behind `checked_type_aliases` / `type_alias_impl_trait`. Its match handles `AliasTermKind::FreeTy` and `FreeConst`; the `kind => panic!("expected free alias, found {kind:?}")` arm (line 54) fires when `free_alias.kind` is something else (Projection, Inherent, Opaque, Weak). The dispatcher is supposed to send only free aliases here, so a non-free kind means the projection-term dispatch routed the wrong alias category — a compiler bug.

Source

Thrown at compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs:54

                let free = cx.type_of(def_id.into()).instantiate(cx, free_alias.args);
                let free = self.normalize(GoalSource::Misc, goal.param_env, free)?;
                free.into()
            }
            ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id.into()) => {
                let free = cx.const_of_item(def_id.into()).instantiate(cx, free_alias.args);
                let free = self.normalize(GoalSource::Misc, goal.param_env, free)?;

                free.into()
            }
            ty::AliasTermKind::FreeConst { .. } => {
                return self.evaluate_const_and_instantiate_projection_term(
                    goal.param_env,
                    free_alias,
                    goal.predicate.term,
                    free_alias.expect_ct(),
                );
            }
            kind => panic!("expected free alias, found {kind:?}"),
        };

        self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.projection_term, actual)?;
        self.eq(goal.param_env, goal.predicate.term, actual)?;
        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
    }
}

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Report at https://github.com/rust-lang/rust/issues with the `{kind:?}` value from the panic and a minimal type-alias repro.
  2. Disable `-Znext-solver` and the `checked_type_aliases` / `type_alias_impl_trait` features.
  3. `rustup update nightly`.
  4. Simplify the alias (split nested aliases, avoid alias-to-alias chains) to dodge the broken dispatch.

Example fix

// before — nested free alias that confuses dispatch
type A = impl Iterator<Item = u8>;
type B = A; // alias-to-alias chain
// after — flatten to a single alias
type B = impl Iterator<Item = u8>;
Defensive patterns

Strategy: validation

Validate before calling

// The solver expected a *free* alias (an alias of an associated type or opaque
// type that is not further constrained) but found a different `kind`.
// Validate that every alias used in trait goals is a fully-resolvable
// associated-type alias or opaque type alias.
trait Assoc { type A; }
impl Assoc for () { type A = i32; }
// GOOD: <() as Assoc>::A  (free alias, normalises to i32)
fn ensure_alias_free<T: Assoc<A = i32>>() {} // constraint resolves alias

Type guard

// Reject alias kinds that are not associated-type or opaque aliases.
// In practice this means: don't pass generic-parameter aliases or
// placeholder aliases into solver goals directly.
// Type-level check via a marker:
trait IsFreeAlias {}
impl<T> IsFreeAlias for T where T: /* assoc-type alias constraint */ {}

Prevention

When it happens

Trigger: A projection term whose `AliasTermKind` is not `FreeTy`/`FreeConst` is handed to `normalize_free_alias`, typically because the dispatcher keyed off the wrong alias kind under `-Znext-solver` with `checked_type_aliases` or `type_alias_impl_trait` enabled.

Common situations: Nightly users of `#![feature(checked_type_aliases)]` or `#![feature(type_alias_impl_trait)]` under the next solver, often after mixing alias kinds (e.g. an opaque/weak alias mistaken for a free one) or after a rustc update to alias dispatch.

Related errors


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