mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
Generate thunks for functions in impls (#5390)
Generate a thunk when a function in an `impl` has a different signature than the function in the interface. This follows the design in [#3763](https://docs.carbon-lang.dev/proposals/p3763.html#impl-members-vs-interface-members), although some of the checks described there are not yet implemented. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
4f5d11a28b
commit
95903dc624
@@ -5,7 +5,6 @@
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "common/find.h"
|
||||
#include "toolchain/base/kind_switch.h"
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/control_flow.h"
|
||||
@@ -34,7 +33,6 @@
|
||||
#include "toolchain/sem_ir/function.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/pattern.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
@@ -85,18 +83,6 @@ auto HandleParseNode(Context& context, Parse::ReturnTypeId node_id) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the ID of the self parameter pattern, or None.
|
||||
// TODO: Do this during initial traversal of implicit params.
|
||||
static auto FindSelfPattern(Context& context,
|
||||
SemIR::InstBlockId implicit_param_patterns_id)
|
||||
-> SemIR::InstId {
|
||||
auto implicit_param_patterns =
|
||||
context.inst_blocks().GetOrEmpty(implicit_param_patterns_id);
|
||||
return FindIfOrNone(implicit_param_patterns, [&](auto implicit_param_id) {
|
||||
return SemIR::IsSelfPattern(context.sem_ir(), implicit_param_id);
|
||||
});
|
||||
}
|
||||
|
||||
// Diagnoses issues with the modifiers, removing modifiers that shouldn't be
|
||||
// present.
|
||||
static auto DiagnoseModifiers(Context& context,
|
||||
@@ -577,55 +563,20 @@ auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
static auto CheckFunctionDefinitionSignature(Context& context,
|
||||
SemIR::Function& function)
|
||||
-> void {
|
||||
auto params_to_complete =
|
||||
context.inst_blocks().GetOrEmpty(function.call_params_id);
|
||||
|
||||
// Check the return type is complete.
|
||||
if (function.return_slot_pattern_id.has_value()) {
|
||||
CheckFunctionReturnType(context,
|
||||
SemIR::LocId(function.return_slot_pattern_id),
|
||||
function, SemIR::SpecificId::None);
|
||||
params_to_complete = params_to_complete.drop_back();
|
||||
}
|
||||
|
||||
// Check the parameter types are complete.
|
||||
for (auto param_ref_id : params_to_complete) {
|
||||
if (param_ref_id == SemIR::ErrorInst::InstId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The parameter types need to be complete.
|
||||
RequireCompleteType(
|
||||
context, context.insts().GetAs<SemIR::AnyParam>(param_ref_id).type_id,
|
||||
SemIR::LocId(param_ref_id), [&] {
|
||||
CARBON_DIAGNOSTIC(
|
||||
IncompleteTypeInFunctionParam, Error,
|
||||
"parameter has incomplete type {0} in function definition",
|
||||
TypeOfInstId);
|
||||
return context.emitter().Build(
|
||||
param_ref_id, IncompleteTypeInFunctionParam, param_ref_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Processes a function definition after a signature for which we have already
|
||||
// built a function ID. This logic is shared between processing regular function
|
||||
// definitions and delayed parsing of inline method definitions.
|
||||
static auto HandleFunctionDefinitionAfterSignature(
|
||||
Context& context, Parse::FunctionDefinitionStartId node_id,
|
||||
SemIR::FunctionId function_id, SemIR::InstId decl_id) -> void {
|
||||
auto& function = context.functions().Get(function_id);
|
||||
|
||||
// Create the function scope and the entry block.
|
||||
context.scope_stack().PushForFunctionBody(decl_id);
|
||||
context.inst_block_stack().Push();
|
||||
context.region_stack().PushRegion(context.inst_block_stack().PeekOrAdd());
|
||||
StartGenericDefinition(context, function.generic_id);
|
||||
StartGenericDefinition(context,
|
||||
context.functions().Get(function_id).generic_id);
|
||||
|
||||
CheckFunctionDefinitionSignature(context, function);
|
||||
CheckFunctionDefinitionSignature(context, function_id);
|
||||
|
||||
context.node_stack().Push(node_id, function_id);
|
||||
}
|
||||
@@ -765,8 +716,9 @@ auto HandleParseNode(Context& context,
|
||||
|
||||
auto builtin_kind = LookupBuiltinFunctionKind(context, name_id);
|
||||
if (builtin_kind != SemIR::BuiltinFunctionKind::None) {
|
||||
CheckFunctionDefinitionSignature(context, function_id);
|
||||
|
||||
auto& function = context.functions().Get(function_id);
|
||||
CheckFunctionDefinitionSignature(context, function);
|
||||
if (IsValidBuiltinDeclaration(context, function, builtin_kind)) {
|
||||
function.builtin_function_kind = builtin_kind;
|
||||
// Build an empty generic definition if this is a generic builtin.
|
||||
|
||||
Reference in New Issue
Block a user