diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 3b18c58c65ab..f832bbaa9f2e 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -325,11 +325,24 @@ auto AddImpl(Context& context, const SemIR::Impl& impl, // Returns whether the `LookupImplWitness` of `witness_id` matches `interface`. static auto WitnessQueryMatchesInterface( - Context& context, SemIR::InstId witness_id, - const SemIR::SpecificInterface& interface) -> bool { - auto lookup = context.insts().GetAs(witness_id); - return interface == - context.specific_interfaces().Get(lookup.query_specific_interface_id); + Context& context, SemIR::LocId loc_id, SemIR::InstId impl_self, + SemIR::InstId access_witness_id, + const SemIR::SpecificInterface& impl_interface) -> bool { + auto lookup = + context.insts().GetAs(access_witness_id); + auto access_interface = + context.specific_interfaces().Get(lookup.query_specific_interface_id); + + // The `impl_interface` comes from an IdentifiedFacetType so it has `.Self` + // replaced. The access comes from a rewrite constraint, which do not have + // `.Self` replaced, so we need to do that here. + // + // TODO: Do this more eagerly as soon as we know the full decl before we + // construct the witness table from it? + SubstPeriodSelfCallbacks callbacks(&context, loc_id, + context.constant_values().Get(impl_self)); + access_interface = SubstPeriodSelf(context, callbacks, access_interface); + return access_interface == impl_interface; } auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id, @@ -351,8 +364,8 @@ auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id, [&](const SemIR::FacetTypeInfo::RewriteConstraint& rewrite) { auto access = context.insts().GetAs( GetImplWitnessAccessWithoutSubstitution(context, rewrite.lhs_id)); - return WitnessQueryMatchesInterface(context, access.witness_id, - impl.interface); + return WitnessQueryMatchesInterface(context, loc_id, impl.self_id, + access.witness_id, impl.interface); }); if (rewrites_into_interface_to_witness.empty()) { diff --git a/toolchain/check/testdata/impl/impl_as_named_constraint.carbon b/toolchain/check/testdata/impl/impl_as_named_constraint.carbon index 2e18c7aa92f4..6f97369b875b 100644 --- a/toolchain/check/testdata/impl/impl_as_named_constraint.carbon +++ b/toolchain/check/testdata/impl/impl_as_named_constraint.carbon @@ -210,7 +210,7 @@ fn G() { // F(C); } -// --- fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon +// --- todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon library "[[@TEST_NAME]]"; interface I(T:! type) { @@ -222,13 +222,6 @@ constraint N { } class C; -// CHECK:STDERR: fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon:[[@LINE+7]]:1: error: associated constant I1 not given a value in impl of interface I [ImplAssociatedConstantNeedsValue] -// CHECK:STDERR: impl C as N where .I1 = C {} -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon:[[@LINE-11]]:7: note: associated constant declared here [AssociatedConstantHere] -// CHECK:STDERR: let I1:! type; -// CHECK:STDERR: ^~~~~~~~~ -// CHECK:STDERR: impl C as N where .I1 = C {} fn F(_:! I(.Self) where .I1 = .Self) {}