Track the type as written in BaseDecl and AdaptDecl. (#4564)

Represent the type as an `InstId` rather than as a `TypeId` to preserve
how it was written and better support tracking its value in a generic.
Add accessors to `Class` to get the base and adapted type to reduce code
duplication, and add `TypeStore::GetObjectRepr` to make it easier to map
from a type to its possibly-adapted object representation type. In
passing, also move `GetIntTypeInfo` and `GetUnqualifiedType` into
`TypeStore`.

This fixes specifics of generic adapters to properly look at the
specific adapted type, and also fixes importing of adapters.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2024-11-27 22:26:30 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent e0db74a2a1
commit d6ec885eb3
51 changed files with 1530 additions and 415 deletions
+20 -22
View File
@@ -390,18 +390,19 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc,
}
// TODO: Support scoped entities other than just classes.
auto class_info = context.classes().Get(class_type->class_id);
const auto& class_info = context.classes().Get(class_type->class_id);
auto parent_type_id = class_info.self_type_id;
if (access_kind == SemIR::AccessKind::Private && is_parent_access) {
if (auto base_decl = context.insts().TryGetAsIfValid<SemIR::BaseDecl>(
class_info.base_id)) {
parent_type_id = base_decl->base_type_id;
} else if (auto adapt_decl =
context.insts().TryGetAsIfValid<SemIR::AdaptDecl>(
class_info.adapt_id)) {
parent_type_id = adapt_decl->adapted_type_id;
if (auto base_type_id =
class_info.GetBaseType(context.sem_ir(), class_type->specific_id);
base_type_id.is_valid()) {
parent_type_id = base_type_id;
} else if (auto adapted_type_id = class_info.GetAdaptedType(
context.sem_ir(), class_type->specific_id);
adapted_type_id.is_valid()) {
parent_type_id = adapted_type_id;
} else {
CARBON_FATAL("Expected parent for parent access");
}
@@ -957,7 +958,13 @@ class TypeCompleter {
if (inst.specific_id.is_valid()) {
ResolveSpecificDefinition(context_, inst.specific_id);
}
Push(class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id));
if (auto adapted_type_id =
class_info.GetAdaptedType(context_.sem_ir(), inst.specific_id);
adapted_type_id.is_valid()) {
Push(adapted_type_id);
} else {
Push(class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id));
}
break;
}
case CARBON_KIND(SemIR::ConstType inst): {
@@ -1127,12 +1134,10 @@ class TypeCompleter {
auto& class_info = context_.classes().Get(inst.class_id);
// The value representation of an adapter is the value representation of
// its adapted type.
if (class_info.adapt_id.is_valid()) {
return GetNestedValueRepr(SemIR::GetTypeInSpecific(
context_.sem_ir(), inst.specific_id,
context_.insts()
.GetAs<SemIR::AdaptDecl>(class_info.adapt_id)
.adapted_type_id));
if (auto adapted_type_id =
class_info.GetAdaptedType(context_.sem_ir(), inst.specific_id);
adapted_type_id.is_valid()) {
return GetNestedValueRepr(adapted_type_id);
}
// Otherwise, the value representation for a class is a pointer to the
// object representation.
@@ -1400,13 +1405,6 @@ auto Context::GetUnboundElementType(SemIR::TypeId class_type_id,
element_type_id);
}
auto Context::GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId {
if (auto const_type = types().TryGetAs<SemIR::ConstType>(type_id)) {
return const_type->inner_id;
}
return type_id;
}
auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void {
output << "Check::Context\n";