mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 17:21:04 +01:00
Add an associated entity instruction and corresponding type for interface elements. (#3730)
When declaring an associated entity in an interface -- just associated functions for now -- create an associated entity value and corresponding type to represent a "slot in a witness table". Also track the list of associated entities on the interface so that we will eventually be able to check impls against them. Associated entities are represented as the integer index of their slot in a witness table. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
90369815ad
commit
33c1e9ca95
@@ -5,6 +5,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/decl_name_stack.h"
|
||||
#include "toolchain/check/interface.h"
|
||||
#include "toolchain/check/modifiers.h"
|
||||
#include "toolchain/parse/tree_node_location_translator.h"
|
||||
#include "toolchain/sem_ir/entry_point.h"
|
||||
@@ -126,9 +127,24 @@ static auto BuildFunctionDecl(Context& context,
|
||||
auto function_decl_id =
|
||||
context.AddPlaceholderInst({parse_node, function_decl});
|
||||
|
||||
// At interface scope, a function declaration introduces an associated
|
||||
// function.
|
||||
auto lookup_result_id = function_decl_id;
|
||||
if (name_context.enclosing_scope_id_for_new_inst().is_valid() &&
|
||||
!name_context.has_qualifiers) {
|
||||
auto scope_inst_id = context.name_scopes().GetInstIdIfValid(
|
||||
name_context.enclosing_scope_id_for_new_inst());
|
||||
if (auto interface_scope =
|
||||
context.insts().TryGetAsIfValid<SemIR::InterfaceDecl>(
|
||||
scope_inst_id)) {
|
||||
lookup_result_id = BuildAssociatedEntity(
|
||||
context, interface_scope->interface_id, function_decl_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether this is a redeclaration.
|
||||
auto existing_id =
|
||||
context.decl_name_stack().LookupOrAddName(name_context, function_decl_id);
|
||||
context.decl_name_stack().LookupOrAddName(name_context, lookup_result_id);
|
||||
if (existing_id.is_valid()) {
|
||||
if (auto existing_function_decl =
|
||||
context.insts().Get(existing_id).TryAs<SemIR::FunctionDecl>()) {
|
||||
@@ -136,6 +152,7 @@ static auto BuildFunctionDecl(Context& context,
|
||||
function_decl.function_id = existing_function_decl->function_id;
|
||||
|
||||
// TODO: Check that the signature matches!
|
||||
// TODO: Disallow redeclarations within classes?
|
||||
|
||||
// Track the signature from the definition, so that IDs in the body match
|
||||
// IDs in the signature.
|
||||
@@ -149,6 +166,8 @@ static auto BuildFunctionDecl(Context& context,
|
||||
}
|
||||
} else {
|
||||
// This is a redeclaration of something other than a function.
|
||||
// This includes the case where an associated function redeclares another
|
||||
// associated function.
|
||||
context.DiagnoseDuplicateName(function_decl_id, existing_id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user