{"id":"3ed9d48c1769458a","repo":"rust-lang/rust","slug":"expected-free-alias-found-kind","errorCode":null,"errorMessage":"expected free alias, found {kind:?}","messagePattern":"expected free alias, found (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs","lineNumber":54,"sourceCode":"                let free = cx.type_of(def_id.into()).instantiate(cx, free_alias.args);\n                let free = self.normalize(GoalSource::Misc, goal.param_env, free)?;\n                free.into()\n            }\n            ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id.into()) => {\n                let free = cx.const_of_item(def_id.into()).instantiate(cx, free_alias.args);\n                let free = self.normalize(GoalSource::Misc, goal.param_env, free)?;\n\n                free.into()\n            }\n            ty::AliasTermKind::FreeConst { .. } => {\n                return self.evaluate_const_and_instantiate_projection_term(\n                    goal.param_env,\n                    free_alias,\n                    goal.predicate.term,\n                    free_alias.expect_ct(),\n                );\n            }\n            kind => panic!(\"expected free alias, found {kind:?}\"),\n        };\n\n        self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.projection_term, actual)?;\n        self.eq(goal.param_env, goal.predicate.term, actual)?;\n        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)\n    }\n}\n","sourceCodeStart":36,"sourceCodeEnd":62,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs#L36-L62","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Report at https://github.com/rust-lang/rust/issues with the `{kind:?}` value from the panic and a minimal type-alias repro.","Disable `-Znext-solver` and the `checked_type_aliases` / `type_alias_impl_trait` features.","`rustup update nightly`.","Simplify the alias (split nested aliases, avoid alias-to-alias chains) to dodge the broken dispatch."],"exampleFix":"// before — nested free alias that confuses dispatch\ntype A = impl Iterator<Item = u8>;\ntype B = A; // alias-to-alias chain\n// after — flatten to a single alias\ntype B = impl Iterator<Item = u8>;","handlingStrategy":"validation","validationCode":"// The solver expected a *free* alias (an alias of an associated type or opaque\n// type that is not further constrained) but found a different `kind`.\n// Validate that every alias used in trait goals is a fully-resolvable\n// associated-type alias or opaque type alias.\ntrait Assoc { type A; }\nimpl Assoc for () { type A = i32; }\n// GOOD: <() as Assoc>::A  (free alias, normalises to i32)\nfn ensure_alias_free<T: Assoc<A = i32>>() {} // constraint resolves alias","typeGuard":"// Reject alias kinds that are not associated-type or opaque aliases.\n// In practice this means: don't pass generic-parameter aliases or\n// placeholder aliases into solver goals directly.\n// Type-level check via a marker:\ntrait IsFreeAlias {}\nimpl<T> IsFreeAlias for T where T: /* assoc-type alias constraint */ {}","tryCatchPattern":null,"preventionTips":["Ensure every associated-type alias in scope is bound to a concrete definition (impl) or constrained before the solver inspects it.","Avoid leaving alias types ambiguous across crate boundaries; add explicit `where` bounds.","If using generic aliases, resolve them to concrete types before feeding into trait goals."],"tags":["rustc","trait-solver","next-solver","ice","type-alias","checked-type-aliases","type-alias-impl-trait"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}