mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:24:42 +01:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user