Files
carbon-lang/toolchain/sem_ir/impl.cpp
T
Dana Jansens 0cf2448505 Get specific interfaces with correct specific from named constraints (#6435)
When forming an IdentifiedFacetType, we collect interfaces named by
require decls in named constraints that the facet type refers to. These
interfaces come with a specific, but the require decl is inside an named
constraint which may be generic. So we need the specific being applied
to the containing named constraint to also be applied to the require
decl and its target interfaces.

This uncovered that the facet type in require decls was not being
imported correctly, as it was not being attached to the require decl's
generic. This is fixed by making import of RequireImplsDecl multiphase,
so that the decl instruction exists before we resolve the facet type
within it. And by pointing the generic importing machinery to the
RequireImplsDecl, and from there to the RequireImpls structure to get
the generic id.

Then `ImplStore::GetOrAddLookupBucket` can use an IdentifiedFacetType to
correctly get the interface being impl'd, both in the local and the
imported named constraint case. Which allows us to correctly diagnose
redeclarations in the impl file of an impl of an interface through a
named constraint. And to correctly _not_ diagnose them when the specific
in the generic named constraint differs from other decls.
2025-12-01 18:59:02 +00:00

43 lines
1.6 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/sem_ir/impl.h"
#include "toolchain/base/kind_switch.h"
#include "toolchain/sem_ir/facet_type_info.h"
#include "toolchain/sem_ir/file.h"
#include "toolchain/sem_ir/specific_interface.h"
#include "toolchain/sem_ir/specific_named_constraint.h"
namespace Carbon::SemIR {
ImplStore::ImplStore(File& sem_ir)
: sem_ir_(sem_ir), values_(sem_ir.check_ir_id()) {}
auto ImplStore::GetOrAddLookupBucket(const Impl& impl) -> LookupBucketRef {
auto self_id = sem_ir_.constant_values().GetConstantInstId(impl.self_id);
auto impl_as_interface = SpecificInterface::None;
auto facet_type_type_id = TypeId::ForTypeConstant(
sem_ir_.constant_values().Get(impl.constraint_id));
if (auto facet_type =
sem_ir_.types().TryGetAs<FacetType>(facet_type_type_id)) {
auto identified_id =
sem_ir_.identified_facet_types().TryGetId(facet_type->facet_type_id);
if (identified_id.has_value()) {
const auto& identified =
sem_ir_.identified_facet_types().Get(identified_id);
if (identified.is_valid_impl_as_target()) {
impl_as_interface = identified.impl_as_target_interface();
}
}
}
return LookupBucketRef(*this,
lookup_
.Insert(std::pair{self_id, impl_as_interface},
[] { return ImplOrLookupBucketId::None; })
.value());
}
} // namespace Carbon::SemIR