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
+21
View File
@@ -5,6 +5,7 @@
#include "toolchain/check/subst.h"
#include "toolchain/check/eval.h"
#include "toolchain/check/generic.h"
#include "toolchain/sem_ir/copy_on_write_block.h"
#include "toolchain/sem_ir/ids.h"
@@ -77,6 +78,13 @@ static auto PushOperand(Context& context, Worklist& worklist,
worklist.Push(context.types().GetInstId(type_id));
}
break;
case SemIR::IdKind::For<SemIR::GenericInstanceId>:
if (auto instance_id = static_cast<SemIR::GenericInstanceId>(arg);
instance_id.is_valid()) {
PushOperand(context, worklist, SemIR::IdKind::For<SemIR::InstBlockId>,
context.generic_instances().Get(instance_id).args_id.index);
}
break;
default:
break;
}
@@ -128,6 +136,19 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind,
}
return new_type_block.GetCanonical().index;
}
case SemIR::IdKind::For<SemIR::GenericInstanceId>: {
auto instance_id = static_cast<SemIR::GenericInstanceId>(arg);
if (!instance_id.is_valid()) {
return arg;
}
auto& instance = context.generic_instances().Get(instance_id);
auto args_id =
PopOperand(context, worklist, SemIR::IdKind::For<SemIR::InstBlockId>,
instance.args_id.index);
return MakeGenericInstance(context, instance.generic_id,
static_cast<SemIR::InstBlockId>(args_id))
.index;
}
default:
return arg;
}