mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Make SemIR::TypeType be an empty FacetType instruction (#7813)
The type `type` is now a `FacetType` inst with no constraints. This brings the model implemented in the toolchain into better alignment with the language design. The `SemIR::TypeType` struct remains as a scope for holding the `TypeInstId`, `ConstantId`, and `TypeId` constants, but is not an `InstKind` anymore. The `TypeType` inst looks a lot like singletons, but there are many `FacetType` insts so it doesn't quite fit that model. So we put it alongside singletons with a fixed inst id but refer to it as a more general "builtin" inst that is not a singleton. `Namespace::PackageInstId` is similar, and we group it with `TypeType` conceptually as another builtin instruction with a fixed id. No conversion is needed anymore to use a `type` as a facet, since types also have a `FacetType` type. This simplifies and removes a number of helpers and branches throughout the code. The `TypeType` inst is now part of the constant store, so we end up printing it in the constants block in every test. But it's also named `type` rather than `%type` to preserve the majority of existing formatting behaviour, though this does look different from other constants. Assisted-by: Opus 5 was used to generate a first draft and validate the refactoring. Though nearly everything non-trivial the tool wrote has been modified or rewritten.
This commit is contained in:
@@ -148,22 +148,21 @@ static auto ScopeNeedsImplLookup(Context& context,
|
||||
SemIR::InstId inst_id =
|
||||
context.constant_values().GetInstId(name_scope_const_id);
|
||||
CARBON_CHECK(inst_id.has_value());
|
||||
SemIR::Inst inst = context.insts().Get(inst_id);
|
||||
|
||||
if (inst.Is<SemIR::FacetType>()) {
|
||||
// Don't perform impl lookup if an associated entity is named as a member of
|
||||
// a facet type.
|
||||
return false;
|
||||
}
|
||||
if (inst.Is<SemIR::Namespace>()) {
|
||||
if (context.insts().Is<SemIR::Namespace>(inst_id)) {
|
||||
// Don't perform impl lookup if an associated entity is named as a namespace
|
||||
// member.
|
||||
// TODO: This case is not yet listed in the design.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto type_id = context.types().GetTypeIdForTypeInstId(inst_id);
|
||||
// Don't perform impl lookup if an associated entity is named as a member of
|
||||
// a constrained facet type.
|
||||
//
|
||||
// Any other kind of scope is assumed to be a type that implements the
|
||||
// interface containing the associated entity, and impl lookup is performed.
|
||||
return true;
|
||||
return !context.types().IsConstrainedFacetType(type_id);
|
||||
}
|
||||
|
||||
static auto PerformImplWitnessAccessAndSubstitute(
|
||||
@@ -490,9 +489,8 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId base_id, SemIR::NameId name_id,
|
||||
bool required) -> SemIR::InstId {
|
||||
// Unwrap the facet value in `base_id` if possible.
|
||||
if (auto facet_value = TryGetCanonicalFacetValue(context, base_id);
|
||||
facet_value.has_value()) {
|
||||
base_id = facet_value;
|
||||
if (auto facet = TryGetCanonicalFacet(context, base_id); facet.has_value()) {
|
||||
base_id = facet;
|
||||
}
|
||||
|
||||
// If the base is a name scope, such as a class or namespace, perform lookup
|
||||
@@ -515,7 +513,7 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
|
||||
// `base_id` (as part the class case above), as the `base_id` facet should
|
||||
// have member names that directly name members of the `impl`.
|
||||
auto base_type_id = context.insts().Get(base_id).type_id();
|
||||
if (context.types().Is<SemIR::FacetType>(base_type_id)) {
|
||||
if (context.types().IsConstrainedFacetType(base_type_id)) {
|
||||
// Name lookup into a facet requires the facet type to be complete, so
|
||||
// that any names available through the facet type are known for the
|
||||
// facet.
|
||||
@@ -589,15 +587,15 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
|
||||
auto lookup_const_id =
|
||||
context.types().GetConstantId(unqualified_base_type_id);
|
||||
|
||||
// TODO: If the type is a facet, we look through it into the facet's type (a
|
||||
// FacetType) for names. According to the design, we shouldn't need to do
|
||||
// this, as the facet should have member names that directly name members of
|
||||
// the `impl`.
|
||||
auto base_type_as_facet = GetCanonicalFacetOrTypeValue(
|
||||
context, context.types().GetTypeInstId(base_type_id));
|
||||
// TODO: If the type is a constrained facet, we look through it into the
|
||||
// facet's type (a FacetType) for names. According to the design, we shouldn't
|
||||
// need to do this, as the facet should have member names that directly name
|
||||
// members of the `impl`.
|
||||
auto base_type_as_facet =
|
||||
GetCanonicalFacet(context, context.types().GetTypeInstId(base_type_id));
|
||||
auto base_type_facet_type_id =
|
||||
context.insts().Get(base_type_as_facet).type_id();
|
||||
if (context.types().Is<SemIR::FacetType>(base_type_facet_type_id)) {
|
||||
if (context.types().IsConstrainedFacetType(base_type_facet_type_id)) {
|
||||
lookup_const_id = context.types().GetConstantId(base_type_facet_type_id);
|
||||
}
|
||||
|
||||
@@ -606,11 +604,12 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
|
||||
if (AppendLookupScopesForConstant(
|
||||
context, loc_id, lookup_const_id,
|
||||
// The `self_type_const_id` should be the type of `base_id` even if
|
||||
// it's a facet.
|
||||
// it's a constrained facet.
|
||||
//
|
||||
// TODO: This can be replaced with `lookup_const_id` once we stop
|
||||
// having to look through the facet at its type for the scope.
|
||||
context.types().GetConstantId(base_type_id), /*extended_scope=*/false,
|
||||
// having to look through the constrained facet at its type for the
|
||||
// scope.
|
||||
base_type_id.AsConstantId(), /*extended_scope=*/false,
|
||||
&lookup_scopes)) {
|
||||
auto member_id = LookupMemberNameInScope(
|
||||
context, loc_id, base_id, name_id, lookup_const_id, lookup_scopes,
|
||||
|
||||
Reference in New Issue
Block a user