Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch TypeId::TypeType to TypeType::SingletonTypeId, and similar #4619

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions toolchain/check/call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static auto PerformCallToGenericClass(Context& context, SemIR::LocId loc_id,
return SemIR::InstId::BuiltinErrorInst;
}
return context.GetOrAddInst<SemIR::ClassType>(
loc_id, {.type_id = SemIR::TypeId::TypeType,
loc_id, {.type_id = SemIR::TypeType::SingletonTypeId,
.class_id = class_id,
.specific_id = *callee_specific_id});
}
Expand Down Expand Up @@ -202,7 +202,7 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
case SemIR::InitRepr::Incomplete:
// Don't form an initializing expression with an incomplete type.
// CheckFunctionReturnType will have diagnosed this for us if needed.
return_info.type_id = SemIR::TypeId::Error;
return_info.type_id = SemIR::ErrorInst::SingletonTypeId;
break;
}

Expand Down
20 changes: 11 additions & 9 deletions toolchain/check/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ Context::Context(const Lex::TokenizedBuffer& tokens, DiagnosticEmitter& emitter,
// special `TypeId` values.
type_ids_for_type_constants_.Insert(
SemIR::ConstantId::ForTemplateConstant(SemIR::InstId::BuiltinErrorInst),
SemIR::TypeId::Error);
SemIR::ErrorInst::SingletonTypeId);
type_ids_for_type_constants_.Insert(
SemIR::ConstantId::ForTemplateConstant(SemIR::InstId::BuiltinTypeType),
SemIR::TypeId::TypeType);
SemIR::TypeType::SingletonTypeId);

// TODO: Remove this and add a `VerifyOnFinish` once we properly push and pop
// in the right places.
Expand Down Expand Up @@ -492,7 +492,7 @@ auto Context::AppendLookupScopesForConstant(
}
return true;
}
if (base_const_id == SemIR::ConstantId::Error) {
if (base_const_id == SemIR::ErrorInst::SingletonConstantId) {
// Lookup into this scope should fail without producing an error.
scopes->push_back(LookupScope{.name_scope_id = SemIR::NameScopeId::Invalid,
.specific_id = SemIR::SpecificId::Invalid});
Expand Down Expand Up @@ -761,9 +761,9 @@ auto Context::SetBlockArgResultBeforeConstantUse(SemIR::InstId select_id,
const_id = constant_values().Get(literal.value().value.ToBool() ? if_true
: if_false);
} else {
CARBON_CHECK(cond_const_id == SemIR::ConstantId::Error,
CARBON_CHECK(cond_const_id == SemIR::ErrorInst::SingletonConstantId,
"Unexpected constant branch condition.");
const_id = SemIR::ConstantId::Error;
const_id = SemIR::ErrorInst::SingletonConstantId;
}

if (const_id.is_constant()) {
Expand Down Expand Up @@ -908,7 +908,7 @@ class TypeCompleter {
}
// For a pointer representation, the pointee also needs to be complete.
if (value_rep.kind == SemIR::ValueRepr::Pointer) {
if (value_rep.type_id == SemIR::TypeId::Error) {
if (value_rep.type_id == SemIR::ErrorInst::SingletonTypeId) {
break;
}
auto pointee_type_id =
Expand Down Expand Up @@ -1295,7 +1295,8 @@ auto Context::GetTypeIdForTypeConstant(SemIR::ConstantId constant_id)
auto type_id =
insts().Get(constant_values().GetInstId(constant_id)).type_id();
// TODO: For now, we allow values of facet type to be used as types.
CARBON_CHECK(IsFacetType(type_id) || constant_id == SemIR::ConstantId::Error,
CARBON_CHECK(IsFacetType(type_id) ||
constant_id == SemIR::ErrorInst::SingletonConstantId,
"Forming type ID for non-type constant of type {0}",
types().GetAsInst(type_id));

Expand All @@ -1308,15 +1309,16 @@ auto Context::FacetTypeFromInterface(SemIR::InterfaceId interface_id,
SemIR::FacetTypeId facet_type_id = facet_types().Add(
SemIR::FacetTypeInfo{.impls_constraints = {{interface_id, specific_id}},
.other_requirements = false});
return {.type_id = SemIR::TypeId::TypeType, .facet_type_id = facet_type_id};
return {.type_id = SemIR::TypeType::SingletonTypeId,
.facet_type_id = facet_type_id};
}

// Gets or forms a type_id for a type, given the instruction kind and arguments.
template <typename InstT, typename... EachArgT>
static auto GetTypeImpl(Context& context, EachArgT... each_arg)
-> SemIR::TypeId {
// TODO: Remove inst_id parameter from TryEvalInst.
InstT inst = {SemIR::TypeId::TypeType, each_arg...};
InstT inst = {SemIR::TypeType::SingletonTypeId, each_arg...};
return context.GetTypeIdForTypeConstant(
TryEvalInst(context, SemIR::InstId::Invalid, inst));
}
Expand Down
4 changes: 2 additions & 2 deletions toolchain/check/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,12 @@ class Context {
-> SemIR::TypeId {
return TryToCompleteType(type_id, diagnoser, abstract_diagnoser)
? type_id
: SemIR::TypeId::Error;
: SemIR::ErrorInst::SingletonTypeId;
}

// Returns whether `type_id` represents a facet type.
auto IsFacetType(SemIR::TypeId type_id) -> bool {
return type_id == SemIR::TypeId::TypeType ||
return type_id == SemIR::TypeType::SingletonTypeId ||
types().Is<SemIR::FacetType>(type_id);
}

Expand Down
20 changes: 11 additions & 9 deletions toolchain/check/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
CARBON_CHECK(dest_class_info.inheritance_kind != SemIR::Class::Abstract);
auto object_repr_id =
dest_class_info.GetObjectRepr(context.sem_ir(), dest_type.specific_id);
if (object_repr_id == SemIR::TypeId::Error) {
if (object_repr_id == SemIR::ErrorInst::SingletonTypeId) {
return SemIR::InstId::BuiltinErrorInst;
}
auto dest_struct_type =
Expand Down Expand Up @@ -866,7 +866,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}
}

if (target.type_id == SemIR::TypeId::TypeType) {
if (target.type_id == SemIR::TypeType::SingletonTypeId) {
// A tuple of types converts to type `type`.
// TODO: This should apply even for non-literal tuples.
if (auto tuple_literal = value.TryAs<SemIR::TupleLiteral>()) {
Expand Down Expand Up @@ -913,7 +913,7 @@ static auto PerformCopy(Context& context, SemIR::InstId expr_id)
-> SemIR::InstId {
auto expr = context.insts().Get(expr_id);
auto type_id = expr.type_id();
if (type_id == SemIR::TypeId::Error) {
if (type_id == SemIR::ErrorInst::SingletonTypeId) {
return SemIR::InstId::BuiltinErrorInst;
}

Expand Down Expand Up @@ -943,8 +943,9 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,

// Start by making sure both sides are valid. If any part is invalid, the
// result is invalid and we shouldn't error.
if (sem_ir.insts().Get(expr_id).type_id() == SemIR::TypeId::Error ||
target.type_id == SemIR::TypeId::Error) {
if (sem_ir.insts().Get(expr_id).type_id() ==
SemIR::ErrorInst::SingletonTypeId ||
target.type_id == SemIR::ErrorInst::SingletonTypeId) {
return SemIR::InstId::BuiltinErrorInst;
}

Expand Down Expand Up @@ -1215,10 +1216,11 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id,

auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id)
-> TypeExpr {
auto type_inst_id =
ConvertToValueOfType(context, loc_id, value_id, SemIR::TypeId::TypeType);
auto type_inst_id = ConvertToValueOfType(context, loc_id, value_id,
SemIR::TypeType::SingletonTypeId);
if (type_inst_id == SemIR::InstId::BuiltinErrorInst) {
return {.inst_id = type_inst_id, .type_id = SemIR::TypeId::Error};
return {.inst_id = type_inst_id,
.type_id = SemIR::ErrorInst::SingletonTypeId};
}

auto type_const_id = context.constant_values().Get(type_inst_id);
Expand All @@ -1227,7 +1229,7 @@ auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id)
"cannot evaluate type expression");
context.emitter().Emit(loc_id, TypeExprEvaluationFailure);
return {.inst_id = SemIR::InstId::BuiltinErrorInst,
.type_id = SemIR::TypeId::Error};
.type_id = SemIR::ErrorInst::SingletonTypeId};
}

return {.inst_id = type_inst_id,
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id,
struct TypeExpr {
// The converted expression of type `type`, or `InstId::BuiltinErrorInst`.
SemIR::InstId inst_id;
// The corresponding type, or `TypeId::Error`.
// The corresponding type, or `ErrorInst::SingletonTypeId`.
SemIR::TypeId type_id;
};

Expand Down
48 changes: 25 additions & 23 deletions toolchain/check/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static auto GetPhase(EvalContext& eval_context, SemIR::ConstantId constant_id)
-> Phase {
if (!constant_id.is_constant()) {
return Phase::Runtime;
} else if (constant_id == SemIR::ConstantId::Error) {
} else if (constant_id == SemIR::ErrorInst::SingletonConstantId) {
return Phase::UnknownDueToError;
} else if (constant_id.is_template()) {
return Phase::Template;
Expand Down Expand Up @@ -246,16 +246,17 @@ static auto MakeConstantResult(Context& context, SemIR::Inst inst, Phase phase)
return context.constants().GetOrAdd(inst,
SemIR::ConstantStore::IsSymbolic);
case Phase::UnknownDueToError:
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
case Phase::Runtime:
return SemIR::ConstantId::NotConstant;
}
}

// Forms a `constant_id` describing why an evaluation was not constant.
static auto MakeNonConstantResult(Phase phase) -> SemIR::ConstantId {
return phase == Phase::UnknownDueToError ? SemIR::ConstantId::Error
: SemIR::ConstantId::NotConstant;
return phase == Phase::UnknownDueToError
? SemIR::ErrorInst::SingletonConstantId
: SemIR::ConstantId::NotConstant;
}

// Converts a bool value into a ConstantId.
Expand Down Expand Up @@ -460,14 +461,14 @@ static auto ReplaceFieldWithConstantValue(EvalContext& eval_context,
// If the specified fields of the given typed instruction have constant values,
// replaces the fields with their constant values and builds a corresponding
// constant value. Otherwise returns `ConstantId::NotConstant`. Returns
// `ConstantId::Error` if any subexpression is an error.
// `ErrorInst::SingletonConstantId` if any subexpression is an error.
//
// The constant value is then checked by calling `validate_fn(typed_inst)`,
// which should return a `bool` indicating whether the new constant is valid. If
// validation passes, `transform_fn(typed_inst)` is called to produce the final
// constant instruction, and a corresponding ConstantId for the new constant is
// returned. If validation fails, it should produce a suitable error message.
// `ConstantId::Error` is returned.
// `ErrorInst::SingletonConstantId` is returned.
template <typename InstT, typename ValidateFn, typename TransformFn,
typename... EachFieldIdT>
static auto RebuildIfFieldsAreConstantImpl(
Expand All @@ -482,7 +483,7 @@ static auto RebuildIfFieldsAreConstantImpl(
&phase) &&
...)) {
if (phase == Phase::UnknownDueToError || !validate_fn(typed_inst)) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
return MakeConstantResult(eval_context.context(), transform_fn(typed_inst),
phase);
Expand Down Expand Up @@ -603,7 +604,7 @@ static auto PerformArrayIndex(EvalContext& eval_context, SemIR::ArrayIndex inst)
eval_context.emitter().Emit(
inst.index_id, ArrayIndexOutOfBounds,
{.type = index->type_id, .value = index_val}, aggregate_type_id);
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
}
}
Expand Down Expand Up @@ -670,7 +671,7 @@ static auto MakeIntTypeResult(Context& context, SemIRLoc loc,
.int_kind = int_kind,
.bit_width_id = width_id};
if (!ValidateIntType(context, loc, result)) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
return MakeConstantResult(context, result, phase);
}
Expand Down Expand Up @@ -798,7 +799,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
case SemIR::BuiltinFunctionKind::IntUMod:
if (context.ints().Get(rhs.int_id).isZero()) {
DiagnoseDivisionByZero(context, loc);
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
break;
default:
Expand Down Expand Up @@ -830,7 +831,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift,
{.type = rhs.type_id, .value = rhs_orig_val});
// TODO: Is it useful to recover by returning 0 or -1?
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}

if (builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift) {
Expand Down Expand Up @@ -1110,7 +1111,7 @@ static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc,
break;
}
if (!ValidateFloatBitWidth(context, loc, arg_ids[0])) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
return context.constant_values().Get(
SemIR::InstId::BuiltinLegacyFloatType);
Expand Down Expand Up @@ -1224,7 +1225,7 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
//
// TODO: Use a better representation for this.
if (call.args_id == SemIR::InstBlockId::Invalid) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}

// Find the constant value of the callee.
Expand Down Expand Up @@ -1257,7 +1258,7 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
ReplaceFieldWithConstantValue(eval_context, &call, &SemIR::Call::args_id,
&phase);
if (phase == Phase::UnknownDueToError) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}

// If any operand of the call is non-constant, the call is non-constant.
Expand Down Expand Up @@ -1294,10 +1295,11 @@ static auto MakeFacetTypeResult(Context& context,
const SemIR::FacetTypeInfo& info, Phase phase)
-> SemIR::ConstantId {
SemIR::FacetTypeId facet_type_id = context.facet_types().Add(info);
return MakeConstantResult(context,
SemIR::FacetType{.type_id = SemIR::TypeId::TypeType,
.facet_type_id = facet_type_id},
phase);
return MakeConstantResult(
context,
SemIR::FacetType{.type_id = SemIR::TypeType::SingletonTypeId,
.facet_type_id = facet_type_id},
phase);
}

// Implementation for `TryEvalInst`, wrapping `Context` with `EvalContext`.
Expand Down Expand Up @@ -1485,7 +1487,7 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
// A non-generic class declaration evaluates to the class type.
return MakeConstantResult(
eval_context.context(),
SemIR::ClassType{.type_id = SemIR::TypeId::TypeType,
SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId,
.class_id = class_decl.class_id,
.specific_id = SemIR::SpecificId::Invalid},
Phase::Template);
Expand Down Expand Up @@ -1702,10 +1704,10 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
if (auto facet_type = base_facet_inst.TryAs<SemIR::FacetType>()) {
info = GetConstantFacetTypeInfo(eval_context, facet_type->facet_type_id,
&phase);
} else if (base_facet_type_id == SemIR::TypeId::Error) {
return SemIR::ConstantId::Error;
} else if (base_facet_type_id == SemIR::ErrorInst::SingletonTypeId) {
return SemIR::ErrorInst::SingletonConstantId;
} else {
CARBON_CHECK(base_facet_type_id == SemIR::TypeId::TypeType,
CARBON_CHECK(base_facet_type_id == SemIR::TypeType::SingletonTypeId,
"Unexpected type_id: {0}, inst: {1}", base_facet_type_id,
base_facet_inst);
}
Expand Down Expand Up @@ -1747,7 +1749,7 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
!value.value.ToBool());
}
if (phase == Phase::UnknownDueToError) {
return SemIR::ConstantId::Error;
return SemIR::ErrorInst::SingletonConstantId;
}
break;
}
Expand Down
4 changes: 2 additions & 2 deletions toolchain/check/function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ auto CheckFunctionTypeMatches(Context& context,
new_function.GetDeclaredReturnType(context.sem_ir());
auto prev_return_type_id =
prev_function.GetDeclaredReturnType(context.sem_ir(), prev_specific_id);
if (new_return_type_id == SemIR::TypeId::Error ||
prev_return_type_id == SemIR::TypeId::Error) {
if (new_return_type_id == SemIR::ErrorInst::SingletonTypeId ||
prev_return_type_id == SemIR::ErrorInst::SingletonTypeId) {
return false;
}
if (!context.types().AreEqualAcrossDeclarations(new_return_type_id,
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/handle_alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ auto HandleParseNode(Context& context, Parse::AliasId /*node_id*/) -> bool {
CARBON_DIAGNOSTIC(AliasRequiresNameRef, Error,
"alias initializer must be a name reference");
context.emitter().Emit(expr_node, AliasRequiresNameRef);
alias_type_id = SemIR::TypeId::Error;
alias_type_id = SemIR::ErrorInst::SingletonTypeId;
alias_value_id = SemIR::InstId::BuiltinErrorInst;
}
auto alias_id = context.AddInst<SemIR::BindAlias>(
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/handle_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool {
context, context.insts().GetLocId(bound_inst_id), bound_inst_id,
context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType));
context.AddInstAndPush<SemIR::ArrayType>(
node_id, {.type_id = SemIR::TypeId::TypeType,
node_id, {.type_id = SemIR::TypeType::SingletonTypeId,
.bound_id = bound_inst_id,
.element_type_id = element_type_id});
return true;
Expand Down
4 changes: 2 additions & 2 deletions toolchain/check/handle_binding_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ auto HandleParseNode(Context& context, Parse::AddrId node_id) -> bool {
context.insts().Get(param_pattern_id).type_id());
if (pointer_type) {
auto addr_pattern_id = context.AddPatternInst<SemIR::AddrPattern>(
node_id,
{.type_id = SemIR::TypeId::AutoType, .inner_id = param_pattern_id});
node_id, {.type_id = SemIR::AutoType::SingletonTypeId,
.inner_id = param_pattern_id});
context.node_stack().Push(node_id, addr_pattern_id);
} else {
CARBON_DIAGNOSTIC(
Expand Down
Loading
Loading