mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +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:
@@ -665,25 +665,9 @@ auto ResolveSpecificDecl(Context& context, SemIR::LocId loc_id,
|
||||
// Set a placeholder value as the decl block ID so we won't attempt to
|
||||
// recursively resolve the same specific.
|
||||
specific.decl_block_id = SemIR::InstBlockId::Empty;
|
||||
|
||||
// When resolving a specific for an `impl`, we will rebuild and evaluate any
|
||||
// `LookupImplWitness` instructions in the `impl` declaration. These lookups
|
||||
// should not find the `impl` that contains them or they become cyclical.
|
||||
const auto& generic = context.generics().Get(specific.generic_id);
|
||||
bool is_impl_decl = false;
|
||||
if (auto decl =
|
||||
context.insts().TryGetAs<SemIR::ImplDecl>(generic.decl_id)) {
|
||||
is_impl_decl = true;
|
||||
context.forbidden_impls().push_back(decl->impl_id);
|
||||
}
|
||||
|
||||
std::tie(specific.decl_block_id, specific.decl_block_has_error) =
|
||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||
SemIR::GenericInstIndex::Region::Declaration);
|
||||
|
||||
if (is_impl_decl) {
|
||||
context.forbidden_impls().pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user