mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 19:44:57 +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:
@@ -17,6 +17,7 @@
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/singleton_insts.h"
|
||||
#include "toolchain/sem_ir/specific_interface.h"
|
||||
#include "toolchain/sem_ir/struct_type_field.h"
|
||||
#include "toolchain/sem_ir/type_info.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
@@ -476,9 +477,18 @@ class Stringifier {
|
||||
auto StringifyInst(InstId /*inst_id*/, ImplWitnessAccess inst) -> void {
|
||||
auto witness_inst_id =
|
||||
sem_ir_->constant_values().GetConstantInstId(inst.witness_id);
|
||||
auto lookup = sem_ir_->insts().GetAs<LookupImplWitness>(witness_inst_id);
|
||||
auto specific_interface =
|
||||
sem_ir_->specific_interfaces().Get(lookup.query_specific_interface_id);
|
||||
|
||||
auto specific_interface = SemIR::SpecificInterface::None;
|
||||
if (auto self_witness =
|
||||
sem_ir_->insts().TryGetAs<ImplSelfWitness>(witness_inst_id)) {
|
||||
specific_interface = sem_ir_->specific_interfaces().Get(
|
||||
self_witness->specific_interface_id);
|
||||
} else {
|
||||
auto lookup = sem_ir_->insts().GetAs<LookupImplWitness>(witness_inst_id);
|
||||
specific_interface = sem_ir_->specific_interfaces().Get(
|
||||
lookup.query_specific_interface_id);
|
||||
}
|
||||
|
||||
const auto& interface =
|
||||
sem_ir_->interfaces().Get(specific_interface.interface_id);
|
||||
if (!interface.associated_entities_id.has_value()) {
|
||||
@@ -514,16 +524,28 @@ class Stringifier {
|
||||
step_stack_->Push(".(");
|
||||
}
|
||||
|
||||
if (auto lookup =
|
||||
sem_ir_->insts().TryGetAs<LookupImplWitness>(witness_inst_id)) {
|
||||
bool period_self = false;
|
||||
if (auto self_witness =
|
||||
sem_ir_->insts().TryGetAs<ImplSelfWitness>(witness_inst_id)) {
|
||||
bool is_period_self = false;
|
||||
if (auto sym_name = sem_ir_->insts().TryGetAs<SymbolicBinding>(
|
||||
self_witness->period_self)) {
|
||||
auto name_id =
|
||||
sem_ir_->entity_names().Get(sym_name->entity_name_id).name_id;
|
||||
is_period_self = (name_id == NameId::PeriodSelf);
|
||||
}
|
||||
if (!is_period_self) {
|
||||
step_stack_->PushInstId(self_witness->period_self);
|
||||
}
|
||||
} else if (auto lookup = sem_ir_->insts().TryGetAs<LookupImplWitness>(
|
||||
witness_inst_id)) {
|
||||
bool is_period_self = false;
|
||||
if (auto sym_name = sem_ir_->insts().TryGetAs<SymbolicBinding>(
|
||||
lookup->query_self_inst_id)) {
|
||||
auto name_id =
|
||||
sem_ir_->entity_names().Get(sym_name->entity_name_id).name_id;
|
||||
period_self = (name_id == NameId::PeriodSelf);
|
||||
is_period_self = (name_id == NameId::PeriodSelf);
|
||||
}
|
||||
if (!period_self) {
|
||||
if (!is_period_self) {
|
||||
step_stack_->PushInstId(lookup->query_self_inst_id);
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user