Avoid symbolic witnesses for .Self in an impl decl (#7564)

Point symbolic witnesses into `.Self` written inside an impl decl at the
impl that is being declared. This is tricky because the impl does not
yet exist. So we use a new instruction `ImplSelfWitness` which _will_ be
replaced by the `ImplWitness` once it becomes available. The
`ImplSelfWitness` acts like a symbolic witness, except it does not
perform lookup, since we know which impl we will get a witness from.

This prevents us from finding other impls when performing lookups into
`.Self` in an impl decl, which produces incorrect/incoherent results.
This commit is contained in:
Dana Jansens
2026-07-29 16:25:23 +00:00
committed by GitHub
parent 2ac425e591
commit f51c075f8b
94 changed files with 3221 additions and 2797 deletions
+31
View File
@@ -3800,6 +3800,34 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
.query_specific_interface_id = query_specific_interface_id});
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::ImplSelfWitness inst) -> ResolveResult {
CARBON_CHECK(resolver.import_types().GetTypeInstId(inst.type_id) ==
SemIR::WitnessType::TypeInstId);
auto period_self = GetLocalConstantInstId(resolver, inst.period_self);
auto import_specific_interface =
resolver.import_specific_interfaces().Get(inst.specific_interface_id);
auto specific_interface_data =
GetLocalSpecificInterfaceData(resolver, import_specific_interface);
if (resolver.HasNewWork()) {
return ResolveResult::Retry();
}
auto specific_interface = GetLocalSpecificInterface(
resolver, import_specific_interface, specific_interface_data);
auto specific_interface_id =
resolver.local_specific_interfaces().Add(specific_interface);
return ResolveResult::Deduplicated<SemIR::ImplSelfWitness>(
resolver, {.type_id = GetSingletonType(resolver.local_context(),
SemIR::WitnessType::TypeInstId),
.period_self = period_self,
.specific_interface_id = specific_interface_id});
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::ImplWitness inst) -> ResolveResult {
CARBON_CHECK(resolver.import_types().GetTypeInstId(inst.type_id) ==
@@ -4478,6 +4506,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
case CARBON_KIND(SemIR::GenericNamedConstraintType inst): {
return TryResolveTypedInst(resolver, inst);
}
case CARBON_KIND(SemIR::ImplSelfWitness inst): {
return TryResolveTypedInst(resolver, inst);
}
case CARBON_KIND(SemIR::ImplWitness inst): {
return TryResolveTypedInst(resolver, inst);
}