mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:51:12 +01:00
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.
43 lines
1.6 KiB
C++
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
|