mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Make StartImplDecl into a more explicit GetOrAddImpl (Refactor Impl construction 2/7) (#6466)
The GetOrAddImpl operation looks for an existing `Impl` with a matching declaration and returns its ImplId, or finished the construction of a new `Impl`, adds it to the store and returns a fresh `ImplId`. This makes the case of reusing an existing `Impl` into a short early-out, demonstrating more clearly that we are reusing existing work, and avoiding duplicate work such as checking for diagnostics that would have already been checked in the previous (matching) declaration. The `ExtendImpl` helper is renamed to be more explicit about its behaviour, as `ApplyExtendImplAs`, and it constructs the data it needs from the `Impl` and the `extend_node_id`, eliminating the need for a `ExtendImplDecl` struct. This is part of #6420 which is being split up into a chain of smaller PRs. It is based on #6465.
This commit is contained in:
@@ -228,28 +228,34 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
|
||||
SemIR::ImplDecl{.impl_id = SemIR::ImplId::None,
|
||||
.decl_block_id = decl_block_id});
|
||||
|
||||
SemIR::Impl impl_info = {name_context.MakeEntityWithParamsBase(
|
||||
name, impl_decl_id,
|
||||
/*is_extern=*/false, SemIR::LibraryNameId::None),
|
||||
{.self_id = self_type_inst_id,
|
||||
.constraint_id = constraint_type_inst_id,
|
||||
// This requires that the facet type is identified.
|
||||
.interface = CheckConstraintIsInterface(
|
||||
context, impl_decl_id, constraint_type_inst_id),
|
||||
.is_final = is_final}};
|
||||
// This requires that the facet type is identified. It returns None if an
|
||||
// error was diagnosed.
|
||||
auto specific_interface = CheckConstraintIsInterface(context, impl_decl_id,
|
||||
constraint_type_inst_id);
|
||||
|
||||
std::optional<ExtendImplDecl> extend_impl;
|
||||
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
|
||||
extend_impl = ExtendImplDecl{
|
||||
.self_type_node_id = self_type_node,
|
||||
.constraint_type_id = constraint_type_id,
|
||||
.extend_node_id = introducer.modifier_node_id(ModifierOrder::Extend),
|
||||
};
|
||||
auto impl_id = SemIR::ImplId::None;
|
||||
{
|
||||
SemIR::Impl impl_info = {
|
||||
name_context.MakeEntityWithParamsBase(name, impl_decl_id,
|
||||
/*is_extern=*/false,
|
||||
SemIR::LibraryNameId::None),
|
||||
{.self_id = self_type_inst_id,
|
||||
.constraint_id = constraint_type_inst_id,
|
||||
.interface = specific_interface,
|
||||
.is_final = is_final}};
|
||||
auto extend_node = introducer.modifier_node_id(ModifierOrder::Extend);
|
||||
impl_id = GetOrAddImpl(context, node_id, name.implicit_params_loc_id,
|
||||
impl_info, is_definition, extend_node);
|
||||
}
|
||||
|
||||
return StartImplDecl(context, SemIR::LocId(node_id),
|
||||
name.implicit_params_loc_id, impl_info, is_definition,
|
||||
extend_impl);
|
||||
// `GetOrAddImpl` either filled in the `impl_info` and returned a fresh
|
||||
// ImplId, or if we're redeclaring a previous impl, returned an existing
|
||||
// ImplId. Write that ImplId into the ImplDecl instruction and finish it.
|
||||
auto impl_decl = context.insts().GetAs<SemIR::ImplDecl>(impl_decl_id);
|
||||
impl_decl.impl_id = impl_id;
|
||||
ReplaceInstBeforeConstantUse(context, impl_decl_id, impl_decl);
|
||||
|
||||
return {impl_id, impl_decl_id};
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::ImplDeclId node_id) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user