mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Support out-of-line definitions of members of generic classes and interfaces. (#4029)
Check the parameters specified in a name qualifier against the parameters of the entity that the qualifier refers to. For interfaces, this required adding minimal support for parameterized interface names. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
268dd04511
commit
7792e5fce3
@@ -5,6 +5,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/handle.h"
|
||||
#include "toolchain/check/interface.h"
|
||||
#include "toolchain/check/merge.h"
|
||||
#include "toolchain/check/modifiers.h"
|
||||
#include "toolchain/check/name_component.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
@@ -28,10 +29,6 @@ static auto BuildInterfaceDecl(Context& context,
|
||||
Parse::AnyInterfaceDeclId node_id)
|
||||
-> std::tuple<SemIR::InterfaceId, SemIR::InstId> {
|
||||
auto name = PopNameComponent(context);
|
||||
if (name.params_id.is_valid() || name.implicit_params_id.is_valid()) {
|
||||
context.TODO(node_id, "generic interface");
|
||||
}
|
||||
|
||||
auto name_context = context.decl_name_stack().FinishName(name);
|
||||
context.node_stack()
|
||||
.PopAndDiscardSoloNodeId<Parse::NodeKind::InterfaceIntroducer>();
|
||||
@@ -63,11 +60,20 @@ static auto BuildInterfaceDecl(Context& context,
|
||||
if (existing_id.is_valid()) {
|
||||
if (auto existing_interface_decl =
|
||||
context.insts().Get(existing_id).TryAs<SemIR::InterfaceDecl>()) {
|
||||
// This is a redeclaration of an existing interface.
|
||||
interface_decl.interface_id = existing_interface_decl->interface_id;
|
||||
|
||||
// TODO: Check that the generic parameter list agrees with the prior
|
||||
// declaration.
|
||||
// TODO: Implement full redeclaration checking. See `MergeClassDecl`. For
|
||||
// now we just check the generic parameters match.
|
||||
if (CheckRedeclParamsMatch(
|
||||
context,
|
||||
DeclParams(interface_decl_id, name.implicit_params_id,
|
||||
name.params_id),
|
||||
DeclParams(context.interfaces().Get(
|
||||
existing_interface_decl->interface_id)))) {
|
||||
// This is a redeclaration of an existing interface.
|
||||
interface_decl.interface_id = existing_interface_decl->interface_id;
|
||||
// TODO: If the new declaration is a definition, keep its parameter
|
||||
// and implicit parameter lists rather than the ones from the
|
||||
// previous declaration.
|
||||
}
|
||||
} else {
|
||||
// This is a redeclaration of something other than a interface.
|
||||
context.DiagnoseDuplicateName(interface_decl_id, existing_id);
|
||||
@@ -83,9 +89,14 @@ static auto BuildInterfaceDecl(Context& context,
|
||||
interface_decl.interface_id = context.interfaces().Add(
|
||||
{.name_id = name_context.name_id_for_new_inst(),
|
||||
.parent_scope_id = name_context.parent_scope_id_for_new_inst(),
|
||||
.implicit_param_refs_id = name.implicit_params_id,
|
||||
.param_refs_id = name.params_id,
|
||||
.decl_id = interface_decl_id});
|
||||
}
|
||||
|
||||
// TODO: For a generic interface declaration, set the `type_id` to a suitable
|
||||
// generic interface type rather than `type`.
|
||||
|
||||
// Write the interface ID into the InterfaceDecl.
|
||||
context.ReplaceInstBeforeConstantUse(interface_decl_id, interface_decl);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user