@@ -232,18 +232,30 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,
232232
233233 // The self type of the impl must match the type in the query, or this is an
234234 // `impl T as ...` for some other type `T` and should not be considered.
235- auto deduced_self_const_id = SemIR::GetConstantValueInSpecific (
235+ auto noncanonical_deduced_self_const_id = SemIR::GetConstantValueInSpecific (
236236 context.sem_ir (), specific_id, impl.self_id );
237+
237238 // In a generic `impl forall` the self type can be a FacetAccessType, which
238239 // will not be the same constant value as a query facet value. We move through
239240 // to the facet value here, and if the query was a FacetAccessType we did the
240241 // same there so they still match.
241- deduced_self_const_id =
242- GetCanonicalFacetOrTypeValue (context, deduced_self_const_id );
242+ auto deduced_self_const_id =
243+ GetCanonicalFacetOrTypeValue (context, noncanonical_deduced_self_const_id );
243244 if (query_self_const_id != deduced_self_const_id) {
244245 return EvalImplLookupResult::MakeNone ();
245246 }
246247
248+ // When working with a symbolic constant and a `final` impl, add an
249+ // instruction to support requiring an impl definition which may not
250+ // otherwise be generated.
251+ if (impl.is_final && deduced_self_const_id.is_symbolic ()) {
252+ AddInstInNoBlock (context, loc_id,
253+ SemIR::RequireImplDefinition{
254+ .type_id = GetSingletonType (
255+ context, SemIR::WitnessType::TypeInstId),
256+ .specific_id = specific_id});
257+ }
258+
247259 // The impl's constraint is a facet type which it is implementing for the self
248260 // type: the `I` in `impl ... as I`. The deduction step may be unable to be
249261 // fully applied to the types in the constraint and result in an error here,
0 commit comments