{"id":"4c2679f5b7a380eb","repo":"rust-lang/rust","slug":"unexpected-type-self-ty","errorCode":null,"errorMessage":"unexpected type `{self_ty:?}`","messagePattern":"unexpected type `(.+?)`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_next_trait_solver/src/solve/trait_goals.rs","lineNumber":911,"sourceCode":"                            // FIXME(try_as_dyn): check what kind of projections we can allow\n                            ExistentialPredicate::Projection(_) => return Err(NoSolution.into()),\n                            // Auto traits do not affect lifetimes outside of specialization,\n                            // which is disabled in reflection.\n                            ExistentialPredicate::AutoTrait(_) => {}\n                        }\n                    }\n                    ecx.add_goal(\n                        GoalSource::Misc,\n                        goal.with(cx, ty::OutlivesPredicate(ty_lifetime, lifetime)),\n                    )?;\n                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)\n                }\n\n                ty::Bound(..)\n                | ty::Infer(\n                    ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),\n                ) => {\n                    panic!(\"unexpected type `{self_ty:?}`\")\n                }\n\n                _ => Err(NoSolution.into()),\n            }\n        })\n    }\n\n    fn consider_builtin_field_candidate(\n        ecx: &mut EvalCtxt<'_, D>,\n        goal: Goal<I, Self>,\n    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {\n        if goal.predicate.polarity != ty::PredicatePolarity::Positive {\n            return Err(NoSolution.into());\n        }\n        if let ty::Adt(def, args) = goal.predicate.self_ty().kind()\n            && let Some(FieldInfo { base, ty, .. }) =\n                def.field_representing_type_info(ecx.cx(), args)\n            && {","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L893-L929","documentation":"In the trait-goal `consider_builtin_try_as_dyn_candidate` (trait_goals.rs:911), the match on `self_ty.kind()` panics for `ty::Bound(..)` and `ty::Infer(TyVar | FreshTy | FreshIntTy | FreshFloatTy)`. The try_as_dyn candidate (reflection mode) expects a concrete self type; a bound var or unresolved inference variable should not reach it. Hitting this arm is a solver-invariant violation.","triggerScenarios":"A `try_as_dyn` trait goal whose self type is a `Bound` var or unbound `TyVar`/`Fresh*` reaches the builtin candidate under `-Znext-solver` reflection mode.","commonSituations":"Nightly users running reflection mode (`-Znext-solver=reflection`) or the try-as-dyn experiment, where a generic/escaping-bound self type wasn't resolved before the candidate ran; typically after a rustc update.","solutions":["Report at https://github.com/rust-lang/rust/issues with `{self_ty:?}` from the panic.","Drop `-Znext-solver=reflection` / `-Znext-solver`.","Annotate the self type so it resolves before the candidate.","`rustup update nightly`."],"exampleFix":"// before — self type unknown in a try_as_dyn context under reflection\nlet x = reflect_thing(); // returns inferred type\n// after — annotate the concrete type\nlet x: Concrete = reflect_thing::<Concrete>();","handlingStrategy":"validation","validationCode":"// The solver found an unexpected self-type in a trait goal.\n// Common cause: the Self type of a bound is a closure, generator, or\n// other inferred type that the solver cannot normalise.\n// Validate by naming the Self type explicitly.\ntrait Marker {}\n// BAD:  let f = || (); impl Marker for typeof(f) {}  (impossible to name)\n// GOOD: struct NamedFn; impl Marker for NamedFn {}\nstruct NamedFn;\nimpl Marker for NamedFn {}\nfn use_marker<T: Marker>() { use_marker::<NamedFn>(); }","typeGuard":"// Never put unnameable types (closures, async blocks, generators) as the\n// Self type of a trait impl. Replace them with a named struct/enum:\nstruct Handler;\nimpl Trait for Handler { /* ... */ }\n// If you need closure semantics, store the closure in a field of a named type.","tryCatchPattern":null,"preventionTips":["Never implement traits directly on closures, async blocks, or other compiler-generated types — wrap them in a named struct.","Provide an explicit `Self` type in trait goals via turbofish rather than letting inference pick an anonymous type.","When a bound fails with this ICE, replace the inferred self type with a named type and re-test."],"tags":["rustc","trait-solver","next-solver","ice","try-as-dyn","reflection","inference"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}