Subst .Self in impl as rewrites (#7105)

This makes rewrites of a constraint that requires a generic `I(Self)`
work. The `Self` there is replaced in the identified facet type by the
impl-as self type. But the rewrite is for the interface `.I(.Self)`, so
they don't match. Once `.Self` is replaced with the impl-as self type,
then they match and the rewrite is applied.
This commit is contained in:
Dana Jansens
2026-04-24 20:51:20 +00:00
committed by GitHub
parent 824d7e3c83
commit 235267680b
2 changed files with 21 additions and 15 deletions
+20 -7
View File
@@ -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<SemIR::LookupImplWitness>(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<SemIR::LookupImplWitness>(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<SemIR::ImplWitnessAccess>(
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()) {