Use the correct type for Self in generic classes and generic interfaces (#4087)

In a `class C(T:! type)`, the type `Self` should be `C(T)`, not merely
`C`. Similarly, in an `interface I(T:! type)`, the type of self should
be `I(T)`, not merely `I`.
This commit is contained in:
Richard Smith
2024-06-28 20:20:40 +00:00
committed by GitHub
parent 19c5596fd8
commit 10a198a9e6
24 changed files with 395 additions and 224 deletions
+13 -5
View File
@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/check/context.h"
#include "toolchain/check/eval.h"
#include "toolchain/check/generic.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"
@@ -152,10 +152,18 @@ auto HandleInterfaceDefinitionStart(Context& context,
// Declare and introduce `Self`.
if (!interface_info.is_defined()) {
// TODO: Once we support parameterized interfaces, this won't be the right
// type. For `interface X(T:! type)`, the type of `Self` is `X(T)`, whereas
// this will be simply `X`.
auto self_type_id = context.GetTypeIdForTypeInst(interface_decl_id);
SemIR::TypeId self_type_id = SemIR::TypeId::Invalid;
if (interface_info.is_generic()) {
auto instance_id =
MakeGenericSelfInstance(context, interface_info.generic_id);
self_type_id = context.GetTypeIdForTypeConstant(
TryEvalInst(context, SemIR::InstId::Invalid,
SemIR::InterfaceType{.type_id = SemIR::TypeId::TypeType,
.interface_id = interface_id,
.instance_id = instance_id}));
} else {
self_type_id = context.GetTypeIdForTypeInst(interface_decl_id);
}
// We model `Self` as a symbolic binding whose type is the interface.
// Because there is no equivalent non-symbolic value, we use `Invalid` as