diff --git a/toolchain/check/call.cpp b/toolchain/check/call.cpp index 6ce11baa0026d..9c0dfc3e913a9 100644 --- a/toolchain/check/call.cpp +++ b/toolchain/check/call.cpp @@ -97,7 +97,7 @@ static auto PerformCallToGenericClass(Context& context, SemIR::LocId loc_id, return SemIR::InstId::BuiltinErrorInst; } return context.GetOrAddInst( - loc_id, {.type_id = SemIR::TypeId::TypeType, + loc_id, {.type_id = SemIR::TypeType::SingletonTypeId, .class_id = class_id, .specific_id = *callee_specific_id}); } @@ -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; } diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 775dd4eeecf09..b3b66e0d14384 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -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. @@ -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}); @@ -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()) { @@ -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 = @@ -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)); @@ -1308,7 +1309,8 @@ 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. @@ -1316,7 +1318,7 @@ template 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)); } diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 6160b791575df..2c696a9bf7e50 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -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(type_id); } diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 21b60a4277853..56c496c5bc8a4 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -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 = @@ -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()) { @@ -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; } @@ -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; } @@ -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); @@ -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, diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index 5630e68ea8203..e0b6be6774c3f 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -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; }; diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 83f893a7c50e4..57d3c1c46b929 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -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; @@ -246,7 +246,7 @@ 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; } @@ -254,8 +254,9 @@ static auto MakeConstantResult(Context& context, SemIR::Inst inst, Phase phase) // 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. @@ -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 static auto RebuildIfFieldsAreConstantImpl( @@ -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); @@ -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; } } } @@ -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); } @@ -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: @@ -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) { @@ -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); @@ -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. @@ -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. @@ -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`. @@ -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); @@ -1702,10 +1704,10 @@ static auto TryEvalInstInContext(EvalContext& eval_context, if (auto facet_type = base_facet_inst.TryAs()) { 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); } @@ -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; } diff --git a/toolchain/check/function.cpp b/toolchain/check/function.cpp index c92c9b6df6f84..d14973408cf48 100644 --- a/toolchain/check/function.cpp +++ b/toolchain/check/function.cpp @@ -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, diff --git a/toolchain/check/handle_alias.cpp b/toolchain/check/handle_alias.cpp index 1a84eb4cc3417..ff96f6b700a72 100644 --- a/toolchain/check/handle_alias.cpp +++ b/toolchain/check/handle_alias.cpp @@ -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( diff --git a/toolchain/check/handle_array.cpp b/toolchain/check/handle_array.cpp index a7b89680611c4..1d4c284e692e5 100644 --- a/toolchain/check/handle_array.cpp +++ b/toolchain/check/handle_array.cpp @@ -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( - 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; diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index cd3a5e4049c30..7d1c1132ffd20 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -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( - 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( diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index 0fabcbd3d72b5..a15be0600d08c 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -206,9 +206,10 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, auto decl_block_id = context.inst_block_stack().Pop(); // Add the class declaration. - auto class_decl = SemIR::ClassDecl{.type_id = SemIR::TypeId::TypeType, - .class_id = SemIR::ClassId::Invalid, - .decl_block_id = decl_block_id}; + auto class_decl = + SemIR::ClassDecl{.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = SemIR::ClassId::Invalid, + .decl_block_id = decl_block_id}; auto class_decl_id = context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, class_decl)); @@ -250,11 +251,11 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, auto& class_info = context.classes().Get(class_decl.class_id); auto specific_id = context.generics().GetSelfSpecific(class_info.generic_id); - class_info.self_type_id = context.GetTypeIdForTypeConstant( - TryEvalInst(context, SemIR::InstId::Invalid, - SemIR::ClassType{.type_id = SemIR::TypeId::TypeType, - .class_id = class_decl.class_id, - .specific_id = specific_id})); + class_info.self_type_id = context.GetTypeIdForTypeConstant(TryEvalInst( + context, SemIR::InstId::Invalid, + SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = class_decl.class_id, + .specific_id = specific_id})); } if (!is_definition && context.IsImplFile() && !is_extern) { @@ -398,7 +399,7 @@ auto HandleParseNode(Context& context, Parse::AdaptDeclId node_id) -> bool { return context.emitter().Build(node_id, AbstractTypeInAdaptDecl, adapted_inst_id); }); - if (adapted_type_id == SemIR::TypeId::Error) { + if (adapted_type_id == SemIR::ErrorInst::SingletonTypeId) { adapted_inst_id = SemIR::InstId::BuiltinErrorInst; } @@ -436,7 +437,7 @@ struct BaseInfo { SemIR::InstId inst_id; }; constexpr BaseInfo BaseInfo::Error = { - .type_id = SemIR::TypeId::Error, + .type_id = SemIR::ErrorInst::SingletonTypeId, .scope_id = SemIR::NameScopeId::Invalid, .inst_id = SemIR::InstId::BuiltinErrorInst}; } // namespace @@ -463,7 +464,7 @@ static auto CheckBaseType(Context& context, Parse::NodeId node_id, base_type_inst_id); }); - if (base_type_id == SemIR::TypeId::Error) { + if (base_type_id == SemIR::ErrorInst::SingletonTypeId) { return BaseInfo::Error; } @@ -538,7 +539,7 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { .base_type_inst_id = base_info.inst_id, .index = SemIR::ElementIndex::Invalid}); - if (base_info.type_id != SemIR::TypeId::Error) { + if (base_info.type_id != SemIR::ErrorInst::SingletonTypeId) { auto base_class_info = context.classes().Get( context.types().GetAs(base_info.type_id).class_id); class_info.is_dynamic |= base_class_info.is_dynamic; @@ -631,9 +632,10 @@ static auto AddStructTypeFields( field_decl.index = SemIR::ElementIndex{static_cast(struct_type_fields.size())}; context.ReplaceInstPreservingConstantValue(field_decl_id, field_decl); - if (field_decl.type_id == SemIR::TypeId::Error) { + if (field_decl.type_id == SemIR::ErrorInst::SingletonTypeId) { struct_type_fields.push_back( - {.name_id = field_decl.name_id, .type_id = SemIR::TypeId::Error}); + {.name_id = field_decl.name_id, + .type_id = SemIR::ErrorInst::SingletonTypeId}); continue; } auto unbound_element_type = diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 6e5c69639a406..6de37a2e90e90 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -101,7 +101,7 @@ auto HandleParseNode(Context& context, Parse::DefaultSelfImplAsId node_id) CARBON_DIAGNOSTIC(ImplAsOutsideClass, Error, "`impl as` can only be used in a class"); context.emitter().Emit(node_id, ImplAsOutsideClass); - self_type_id = SemIR::TypeId::Error; + self_type_id = SemIR::ErrorInst::SingletonTypeId; } // Build the implicit access to the enclosing `Self`. @@ -112,7 +112,7 @@ auto HandleParseNode(Context& context, Parse::DefaultSelfImplAsId node_id) // handling of the `Self` expression. auto self_inst_id = context.AddInst( node_id, - SemIR::NameRef{.type_id = SemIR::TypeId::TypeType, + SemIR::NameRef{.type_id = SemIR::TypeType::SingletonTypeId, .name_id = SemIR::NameId::SelfType, .value_id = context.types().GetInstId(self_type_id)}); diff --git a/toolchain/check/handle_index.cpp b/toolchain/check/handle_index.cpp index 1a8261a0935af..1fcbaccff56e2 100644 --- a/toolchain/check/handle_index.cpp +++ b/toolchain/check/handle_index.cpp @@ -165,7 +165,7 @@ auto HandleParseNode(Context& context, Parse::IndexExprId node_id) -> bool { default: { auto elem_id = SemIR::InstId::BuiltinErrorInst; - if (operand_type_id != SemIR::TypeId::Error) { + if (operand_type_id != SemIR::ErrorInst::SingletonTypeId) { elem_id = PerformIndexWith(context, node_id, operand_inst_id, operand_type_id, index_inst_id); } diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index c6260c3d3d42f..a981d728f09d7 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -52,8 +52,9 @@ static auto BuildInterfaceDecl(Context& context, auto decl_block_id = context.inst_block_stack().Pop(); // Add the interface declaration. - auto interface_decl = SemIR::InterfaceDecl{ - SemIR::TypeId::TypeType, SemIR::InterfaceId::Invalid, decl_block_id}; + auto interface_decl = + SemIR::InterfaceDecl{SemIR::TypeType::SingletonTypeId, + SemIR::InterfaceId::Invalid, decl_block_id}; auto interface_decl_id = context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, interface_decl)); diff --git a/toolchain/check/handle_operator.cpp b/toolchain/check/handle_operator.cpp index 20b48691fb255..6cc7b5c5d9a45 100644 --- a/toolchain/check/handle_operator.cpp +++ b/toolchain/check/handle_operator.cpp @@ -215,8 +215,8 @@ auto HandleParseNode(Context& context, Parse::PostfixOperatorStarId node_id) auto value_id = context.node_stack().PopExpr(); auto inner_type_id = ExprAsType(context, node_id, value_id).type_id; context.AddInstAndPush( - node_id, - {.type_id = SemIR::TypeId::TypeType, .pointee_id = inner_type_id}); + node_id, {.type_id = SemIR::TypeType::SingletonTypeId, + .pointee_id = inner_type_id}); return true; } @@ -268,7 +268,8 @@ auto HandleParseNode(Context& context, Parse::PrefixOperatorConstId node_id) } auto inner_type_id = ExprAsType(context, node_id, value_id).type_id; context.AddInstAndPush( - node_id, {.type_id = SemIR::TypeId::TypeType, .inner_id = inner_type_id}); + node_id, + {.type_id = SemIR::TypeType::SingletonTypeId, .inner_id = inner_type_id}); return true; } @@ -314,7 +315,7 @@ auto HandleParseNode(Context& context, Parse::PrefixOperatorStarId node_id) TokenOnly(node_id), DerefOfNonPointer, not_pointer_type_id); // TODO: Check for any facet here, rather than only a type. - if (not_pointer_type_id == SemIR::TypeId::TypeType) { + if (not_pointer_type_id == SemIR::TypeType::SingletonTypeId) { CARBON_DIAGNOSTIC( DerefOfType, Note, "to form a pointer type, write the `*` after the pointee type"); diff --git a/toolchain/check/handle_struct.cpp b/toolchain/check/handle_struct.cpp index 53bc187831e98..a372c78d1ec5d 100644 --- a/toolchain/check/handle_struct.cpp +++ b/toolchain/check/handle_struct.cpp @@ -169,7 +169,8 @@ auto HandleParseNode(Context& context, Parse::StructTypeLiteralId node_id) } else { auto fields_id = context.struct_type_fields().AddCanonical(fields); context.AddInstAndPush( - node_id, {.type_id = SemIR::TypeId::TypeType, .fields_id = fields_id}); + node_id, + {.type_id = SemIR::TypeType::SingletonTypeId, .fields_id = fields_id}); } context.struct_type_fields_stack().PopArray(); diff --git a/toolchain/check/handle_where.cpp b/toolchain/check/handle_where.cpp index bd26bd623251b..bef9c70de5abe 100644 --- a/toolchain/check/handle_where.cpp +++ b/toolchain/check/handle_where.cpp @@ -16,12 +16,12 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool { auto [self_node, self_id] = context.node_stack().PopExprWithNodeId(); auto self_type_id = ExprAsType(context, self_node, self_id).type_id; // Only facet types may have `where` restrictions. - if (self_type_id != SemIR::TypeId::Error && + if (self_type_id != SemIR::ErrorInst::SingletonTypeId && !context.IsFacetType(self_type_id)) { CARBON_DIAGNOSTIC(WhereOnNonFacetType, Error, "left argument of `where` operator must be a facet type"); context.emitter().Emit(self_node, WhereOnNonFacetType); - self_type_id = SemIR::TypeId::Error; + self_type_id = SemIR::ErrorInst::SingletonTypeId; } // Introduce a name scope so that we can remove the `.Self` entry we are @@ -94,7 +94,7 @@ auto HandleParseNode(Context& context, Parse::RequirementImplsId node_id) // Check lhs is a facet and rhs is a facet type. auto lhs_as_type = ExprAsType(context, lhs_node, lhs_id); auto rhs_as_type = ExprAsType(context, rhs_node, rhs_id); - if (rhs_as_type.type_id != SemIR::TypeId::Error && + if (rhs_as_type.type_id != SemIR::ErrorInst::SingletonTypeId && !context.IsFacetType(rhs_as_type.type_id)) { CARBON_DIAGNOSTIC( ImplsOnNonFacetType, Error, @@ -126,7 +126,7 @@ auto HandleParseNode(Context& context, Parse::WhereExprId node_id) -> bool { context.node_stack().Pop(); SemIR::InstBlockId requirements_id = context.args_type_info_stack().Pop(); context.AddInstAndPush( - node_id, {.type_id = SemIR::TypeId::TypeType, + node_id, {.type_id = SemIR::TypeType::SingletonTypeId, .period_self_id = period_self_id, .requirements_id = requirements_id}); return true; diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 66dc1bb4fe7c1..1a949715dc86b 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -170,7 +170,7 @@ static auto BuildInterfaceWitness( auto decl = context.insts().Get(decl_id); CARBON_KIND_SWITCH(decl) { case CARBON_KIND(SemIR::StructValue struct_value): { - if (struct_value.type_id == SemIR::TypeId::Error) { + if (struct_value.type_id == SemIR::ErrorInst::SingletonTypeId) { return SemIR::InstId::BuiltinErrorInst; } auto type_inst = context.types().GetAsInst(struct_value.type_id); @@ -229,7 +229,7 @@ auto BuildImplWitness(Context& context, SemIR::ImplId impl_id) CARBON_CHECK(impl.is_being_defined()); auto facet_type_id = context.GetTypeIdForTypeInst(impl.constraint_id); - if (facet_type_id == SemIR::TypeId::Error) { + if (facet_type_id == SemIR::ErrorInst::SingletonTypeId) { return SemIR::InstId::BuiltinErrorInst; } auto facet_type = context.types().TryGetAs(facet_type_id); diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index e4ec561983257..81ac6408bdf06 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1287,7 +1287,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto adapted_type_inst_id = - AddLoadedImportRef(resolver, SemIR::TypeId::TypeType, + AddLoadedImportRef(resolver, SemIR::TypeType::SingletonTypeId, inst.adapted_type_inst_id, adapted_type_const_id); // Create a corresponding instruction to represent the declaration. @@ -1318,7 +1318,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::AssociatedEntityType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto entity_type_const_id = GetLocalConstantId(resolver, inst.entity_type_id); auto interface_inst_id = GetLocalConstantId(resolver, inst.interface_type_id); @@ -1328,7 +1328,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = SemIR::TypeId::TypeType, + {.type_id = SemIR::TypeType::SingletonTypeId, .interface_type_id = resolver.local_context().GetTypeIdForTypeConstant(interface_inst_id), .entity_type_id = resolver.local_context().GetTypeIdForTypeConstant( @@ -1346,7 +1346,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto base_type_inst_id = - AddLoadedImportRef(resolver, SemIR::TypeId::TypeType, + AddLoadedImportRef(resolver, SemIR::TypeType::SingletonTypeId, inst.base_type_inst_id, base_type_const_id); // Create a corresponding instruction to represent the declaration. @@ -1415,7 +1415,7 @@ static auto MakeIncompleteClass(ImportContext& context, const SemIR::Class& import_class, SemIR::SpecificId enclosing_specific_id) -> std::pair { - SemIR::ClassDecl class_decl = {.type_id = SemIR::TypeId::TypeType, + SemIR::ClassDecl class_decl = {.type_id = SemIR::TypeType::SingletonTypeId, .class_id = SemIR::ClassId::Invalid, .decl_block_id = SemIR::InstBlockId::Empty}; auto class_decl_id = context.local_context().AddPlaceholderInstInNoBlock( @@ -1566,7 +1566,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::ClassType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto class_const_id = GetLocalConstantId( resolver, resolver.import_classes().Get(inst.class_id).first_owning_decl_id); @@ -1588,10 +1588,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, class_const_inst.type_id()); auto specific_id = GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data); - return ResolveAs(resolver, - {.type_id = SemIR::TypeId::TypeType, - .class_id = generic_class_type.class_id, - .specific_id = specific_id}); + return ResolveAs( + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = generic_class_type.class_id, + .specific_id = specific_id}); } } @@ -1614,7 +1614,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::ConstType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto inner_const_id = GetLocalConstantId(resolver, inst.inner_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); @@ -1623,7 +1623,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, resolver.local_context().GetTypeIdForTypeConstant(inner_const_id); return ResolveAs( resolver, - {.type_id = SemIR::TypeId::TypeType, .inner_id = inner_type_id}); + {.type_id = SemIR::TypeType::SingletonTypeId, .inner_id = inner_type_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -1753,7 +1753,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::FunctionType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto fn_val_id = GetLocalConstantInstId( resolver, resolver.import_functions().Get(inst.function_id).first_decl_id()); @@ -1763,7 +1763,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto fn_type_id = resolver.local_insts().Get(fn_val_id).type_id(); return ResolveAs( - resolver, {.type_id = SemIR::TypeId::TypeType, + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .function_id = resolver.local_types() .GetAs(fn_type_id) .function_id, @@ -1773,7 +1773,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::GenericClassType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto class_val_id = GetLocalConstantInstId( resolver, resolver.import_classes().Get(inst.class_id).first_owning_decl_id); @@ -1790,7 +1790,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::GenericInterfaceType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto interface_val_id = GetLocalConstantInstId( resolver, resolver.import_interfaces().Get(inst.interface_id).first_owning_decl_id); @@ -1910,10 +1910,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, // Create instructions for self and constraint to hold the symbolic constant // value for a generic impl. - new_impl.self_id = AddLoadedImportRef(resolver, SemIR::TypeId::TypeType, - import_impl.self_id, self_const_id); + new_impl.self_id = + AddLoadedImportRef(resolver, SemIR::TypeType::SingletonTypeId, + import_impl.self_id, self_const_id); new_impl.constraint_id = - AddLoadedImportRef(resolver, SemIR::TypeId::TypeType, + AddLoadedImportRef(resolver, SemIR::TypeType::SingletonTypeId, import_impl.constraint_id, constraint_const_id); if (import_impl.is_defined()) { @@ -1937,12 +1938,12 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, // Return the constant for the instruction of the imported constant. auto constant_id = resolver.import_constant_values().Get(inst_id); if (!constant_id.is_valid()) { - return ResolveResult::Done(SemIR::ConstantId::Error); + return ResolveResult::Done(SemIR::ErrorInst::SingletonConstantId); } if (!constant_id.is_constant()) { resolver.local_context().TODO( inst_id, "Non-constant ImportRefLoaded (comes up with var)"); - return ResolveResult::Done(SemIR::ConstantId::Error); + return ResolveResult::Done(SemIR::ErrorInst::SingletonConstantId); } auto new_constant_id = GetLocalConstantId( @@ -1957,7 +1958,7 @@ static auto MakeInterfaceDecl(ImportContext& context, SemIR::SpecificId enclosing_specific_id) -> std::pair { SemIR::InterfaceDecl interface_decl = { - .type_id = SemIR::TypeId::TypeType, + .type_id = SemIR::TypeType::SingletonTypeId, .interface_id = SemIR::InterfaceId::Invalid, .decl_block_id = SemIR::InstBlockId::Empty}; auto interface_decl_id = context.local_context().AddPlaceholderInstInNoBlock( @@ -2099,7 +2100,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } return ResolveAs( - resolver, {.type_id = SemIR::TypeId::TypeType, + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .facet_value_inst_id = facet_value_inst_id}); } @@ -2120,7 +2121,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::FacetType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); const SemIR::FacetTypeInfo& facet_type_info = resolver.import_facet_types().Get(inst.facet_type_id); @@ -2180,8 +2181,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, .rewrite_constraints = rewrite_constraints, .other_requirements = facet_type_info.other_requirements}); return ResolveAs( - resolver, - {.type_id = SemIR::TypeId::TypeType, .facet_type_id = facet_type_id}); + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, + .facet_type_id = facet_type_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2253,21 +2254,21 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::IntType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto bit_width_id = GetLocalConstantInstId(resolver, inst.bit_width_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); } return ResolveAs(resolver, - {.type_id = SemIR::TypeId::TypeType, + {.type_id = SemIR::TypeType::SingletonTypeId, .int_kind = inst.int_kind, .bit_width_id = bit_width_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::PointerType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto pointee_const_id = GetLocalConstantId(resolver, inst.pointee_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); @@ -2276,8 +2277,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, auto pointee_type_id = resolver.local_context().GetTypeIdForTypeConstant(pointee_const_id); return ResolveAs( - resolver, - {.type_id = SemIR::TypeId::TypeType, .pointee_id = pointee_type_id}); + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, + .pointee_id = pointee_type_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2300,7 +2301,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::StructType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto orig_fields = resolver.import_struct_type_fields().Get(inst.fields_id); llvm::SmallVector field_const_ids; field_const_ids.reserve(orig_fields.size()); @@ -2323,7 +2324,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } return ResolveAs( - resolver, {.type_id = SemIR::TypeId::TypeType, + resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .fields_id = resolver.local_struct_type_fields().AddCanonical( new_fields)}); } @@ -2345,7 +2346,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::TupleType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto orig_elem_type_ids = resolver.import_type_blocks().Get(inst.elements_id); llvm::SmallVector elem_const_ids; @@ -2387,7 +2388,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::UnboundElementType inst) -> ResolveResult { - CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); + CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto class_const_id = GetLocalConstantId(resolver, inst.class_type_id); auto elem_const_id = GetLocalConstantId(resolver, inst.element_type_id); if (resolver.HasNewWork()) { @@ -2396,7 +2397,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = SemIR::TypeId::TypeType, + {.type_id = SemIR::TypeType::SingletonTypeId, .class_type_id = resolver.local_context().GetTypeIdForTypeConstant(class_const_id), .element_type_id = @@ -2536,7 +2537,7 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, resolver.local_context().TODO( SemIR::LocId(AddImportIRInst(resolver, inst_id)), llvm::formatv("TryResolveInst on {0}", untyped_inst.kind()).str()); - return {.const_id = SemIR::ConstantId::Error}; + return {.const_id = SemIR::ErrorInst::SingletonConstantId}; } // Try to resolve the constant value instead. Note that this can only // retry once. diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 2b7f484cfdfa9..a8de6d19c55e1 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -271,7 +271,7 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, context.types().TryGetAs(type_id)) { if (lookup_in_type_of_base) { SemIR::TypeId base_type_id = context.insts().Get(base_id).type_id(); - if (base_type_id != SemIR::TypeId::TypeType && + if (base_type_id != SemIR::TypeType::SingletonTypeId && context.IsFacetType(base_type_id)) { // Handles `T.F` when `T` is a non-type facet. @@ -467,7 +467,7 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, return SemIR::InstId::BuiltinErrorInst; } - if (base_type_id != SemIR::TypeId::Error) { + if (base_type_id != SemIR::ErrorInst::SingletonTypeId) { CARBON_DIAGNOSTIC(QualifiedExprUnsupported, Error, "type {0} does not support qualified expressions", TypeOfInstId); @@ -514,7 +514,8 @@ auto PerformCompoundMemberAccess( // If we didn't perform impl lookup or instance binding, that's an error // because the base expression is not used for anything. - if (member_id == member_expr_id && member.type_id() != SemIR::TypeId::Error) { + if (member_id == member_expr_id && + member.type_id() != SemIR::ErrorInst::SingletonTypeId) { CARBON_DIAGNOSTIC(CompoundMemberAccessDoesNotUseBase, Error, "member name of type {0} in compound member access is " "not an instance member or an interface member", @@ -555,13 +556,13 @@ auto PerformTupleAccess(Context& context, SemIR::LocId loc_id, return diag_non_constant_index(); } - SemIR::TypeId element_type_id = SemIR::TypeId::Error; + SemIR::TypeId element_type_id = SemIR::ErrorInst::SingletonTypeId; auto index_node_id = context.insts().GetLocId(index_inst_id); index_inst_id = ConvertToValueOfType( context, index_node_id, index_inst_id, context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType)); auto index_const_id = context.constant_values().Get(index_inst_id); - if (index_const_id == SemIR::ConstantId::Error) { + if (index_const_id == SemIR::ErrorInst::SingletonConstantId) { return SemIR::InstId::BuiltinErrorInst; } else if (!index_const_id.is_template()) { return diag_non_constant_index(); diff --git a/toolchain/check/merge.cpp b/toolchain/check/merge.cpp index 44e50bf89033b..1d2a38307f46a 100644 --- a/toolchain/check/merge.cpp +++ b/toolchain/check/merge.cpp @@ -183,7 +183,8 @@ static auto EntityHasParamError(Context& context, const DeclParams& info) if (param_patterns_id.is_valid() && param_patterns_id != SemIR::InstBlockId::Empty) { for (auto param_id : context.inst_blocks().Get(param_patterns_id)) { - if (context.insts().Get(param_id).type_id() == SemIR::TypeId::Error) { + if (context.insts().Get(param_id).type_id() == + SemIR::ErrorInst::SingletonTypeId) { return true; } } diff --git a/toolchain/check/pointer_dereference.cpp b/toolchain/check/pointer_dereference.cpp index 7026f2d4a8a7c..8f437110a420f 100644 --- a/toolchain/check/pointer_dereference.cpp +++ b/toolchain/check/pointer_dereference.cpp @@ -25,11 +25,11 @@ auto PerformPointerDereference( base_id = ConvertToValueExpr(context, base_id); auto type_id = context.types().GetUnqualifiedType( context.insts().Get(base_id).type_id()); - auto result_type_id = SemIR::TypeId::Error; + auto result_type_id = SemIR::ErrorInst::SingletonTypeId; if (auto pointer_type = context.types().TryGetAs(type_id)) { result_type_id = pointer_type->pointee_id; - } else if (type_id != SemIR::TypeId::Error) { + } else if (type_id != SemIR::ErrorInst::SingletonTypeId) { diagnose_not_pointer(type_id); } return context.AddInst( diff --git a/toolchain/docs/adding_features.md b/toolchain/docs/adding_features.md index 8f14b2aabb0cd..0d1008f579350 100644 --- a/toolchain/docs/adding_features.md +++ b/toolchain/docs/adding_features.md @@ -280,12 +280,12 @@ If the resulting SemIR needs a new instruction: - Set `.is_type = InstIsType::Always` in its `Kind` definition. - When constructing instructions of this kind, pass - `SemIR::TypeId::TypeType` in as the value of the `type_id` field, as - in: + `SemIR::TypeType::SingletonTypeId` in as the value of the `type_id` + field, as in: ``` SemIR::InstId inst_id = context.AddInst( - node_id, {.type_id = SemIR::TypeId::TypeType, ...}); + node_id, {.type_id = SemIR::TypeType::SingletonTypeId, ...}); ``` - Although most instructions have distinct types represented by diff --git a/toolchain/sem_ir/class.cpp b/toolchain/sem_ir/class.cpp index 96008c8ea1fad..3a99993e3c33c 100644 --- a/toolchain/sem_ir/class.cpp +++ b/toolchain/sem_ir/class.cpp @@ -17,7 +17,7 @@ static auto GetFoundationType(const File& file, SpecificId specific_id, return TypeId::Invalid; } if (inst_id == SemIR::InstId::BuiltinErrorInst) { - return TypeId::Error; + return ErrorInst::SingletonTypeId; } return TypeId::ForTypeConstant(GetConstantValueInSpecific( file, specific_id, @@ -41,8 +41,8 @@ auto Class::GetObjectRepr(const File& file, SpecificId specific_id) const } auto witness_id = GetConstantValueInSpecific(file, specific_id, complete_type_witness_id); - if (witness_id == ConstantId::Error) { - return TypeId::Error; + if (witness_id == ErrorInst::SingletonConstantId) { + return ErrorInst::SingletonTypeId; } return file.insts() .GetAs(file.constant_values().GetInstId(witness_id)) diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index d9987d161b11a..948f247a9d2e2 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -36,10 +36,12 @@ File::File(CheckIRId check_ir_id, inst_blocks_(allocator_), constants_(this) { // `type` and the error type are both complete types. - types_.SetValueRepr(TypeId::TypeType, - {.kind = ValueRepr::Copy, .type_id = TypeId::TypeType}); - types_.SetValueRepr(TypeId::Error, - {.kind = ValueRepr::Copy, .type_id = TypeId::Error}); + types_.SetValueRepr( + TypeType::SingletonTypeId, + {.kind = ValueRepr::Copy, .type_id = TypeType::SingletonTypeId}); + types_.SetValueRepr( + ErrorInst::SingletonTypeId, + {.kind = ValueRepr::Copy, .type_id = ErrorInst::SingletonTypeId}); insts_.Reserve(SingletonInstKinds.size()); for (auto kind : SingletonInstKinds) { diff --git a/toolchain/sem_ir/function.cpp b/toolchain/sem_ir/function.cpp index f02067d974d37..3ea8a8806d638 100644 --- a/toolchain/sem_ir/function.cpp +++ b/toolchain/sem_ir/function.cpp @@ -36,7 +36,7 @@ auto GetCalleeFunction(const File& sem_ir, InstId callee_id) -> CalleeFunction { auto val_inst = sem_ir.insts().Get(val_id); auto struct_val = val_inst.TryAs(); if (!struct_val) { - result.is_error = val_inst.type_id() == SemIR::TypeId::Error; + result.is_error = val_inst.type_id() == SemIR::ErrorInst::SingletonTypeId; return result; } auto fn_type = sem_ir.types().TryGetAs(struct_val->type_id); diff --git a/toolchain/sem_ir/ids.cpp b/toolchain/sem_ir/ids.cpp index 6acce679e7209..dfbf33b8f31d8 100644 --- a/toolchain/sem_ir/ids.cpp +++ b/toolchain/sem_ir/ids.cpp @@ -5,6 +5,7 @@ #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/singleton_insts.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::SemIR { @@ -127,11 +128,11 @@ auto InstBlockId::Print(llvm::raw_ostream& out) const -> void { auto TypeId::Print(llvm::raw_ostream& out) const -> void { out << "type"; - if (*this == TypeType) { + if (*this == TypeType::SingletonTypeId) { out << "TypeType"; - } else if (*this == AutoType) { + } else if (*this == AutoType::SingletonTypeId) { out << "AutoType"; - } else if (*this == Error) { + } else if (*this == ErrorInst::SingletonTypeId) { out << "Error"; } else { out << "("; diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 599d1a8c15036..90b947f6df080 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -113,9 +113,6 @@ constexpr InstId InstId::PackageNamespace = InstId(BuiltinInstKind::ValidCount); struct ConstantId : public IdBase, public Printable { // An ID for an expression that is not constant. static const ConstantId NotConstant; - // An ID for an expression whose phase cannot be determined because it - // contains an error. This is always modeled as a template constant. - static const ConstantId Error; // An explicitly invalid ID. static const ConstantId Invalid; @@ -183,8 +180,6 @@ struct ConstantId : public IdBase, public Printable { }; constexpr ConstantId ConstantId::NotConstant = ConstantId(NotConstantIndex); -constexpr ConstantId ConstantId::Error = - ConstantId::ForTemplateConstant(InstId::BuiltinErrorInst); constexpr ConstantId ConstantId::Invalid = ConstantId(InvalidIndex); // The ID of a EntityName. @@ -636,15 +631,6 @@ struct TypeId : public IdBase, public Printable { // `InstIdAsType` or `TypeOfInstId` as the diagnostic argument type. using DiagnosticType = DiagnosticTypeInfo; - // The builtin TypeType. - static const TypeId TypeType; - - // The builtin placeholder type for patterns with deduced types. - static const TypeId AutoType; - - // The builtin Error. - static const TypeId Error; - // An explicitly invalid ID. static const TypeId Invalid; @@ -663,11 +649,6 @@ struct TypeId : public IdBase, public Printable { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr TypeId TypeId::TypeType = TypeId::ForTypeConstant( - ConstantId::ForTemplateConstant(InstId::BuiltinTypeType)); -constexpr TypeId TypeId::AutoType = TypeId::ForTypeConstant( - ConstantId::ForTemplateConstant(InstId::BuiltinAutoType)); -constexpr TypeId TypeId::Error = TypeId::ForTypeConstant(ConstantId::Error); constexpr TypeId TypeId::Invalid = TypeId(InvalidIndex); // The ID of a type block. diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 41efba4b52abd..21ed41bf7c5f4 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -134,8 +134,8 @@ class Inst : public Printable { // Error uses a self-referential type so that it's not accidentally treated // as a normal type. Every other builtin is a type, including the // self-referential TypeType. - auto type_id = - kind == InstKind::ErrorInst ? TypeId::Error : TypeId::TypeType; + auto type_id = kind == InstKind::ErrorInst ? ErrorInst::SingletonTypeId + : TypeType::SingletonTypeId; return Inst(kind, type_id, InstId::InvalidIndex, InstId::InvalidIndex); } diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 18b708df0fc34..090873fe1db7e 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -19,6 +19,7 @@ // - Either a `Kind` constant, or a `Kinds` constant and an `InstKind kind;` // member. These are described below. // - Optionally, a `SingletonInstId` if it is a singleton instruction. +// Similarly, there may be `SingletonConstantId` and `SingletonTypeId`. // - Optionally, a `TypeId type_id;` member, for instructions that produce a // value. This includes instructions that produce an abstract value, such as a // `Namespace`, for which a placeholder type should be used. @@ -55,6 +56,8 @@ struct AutoType { .is_type = InstIsType::Always, .constant_kind = InstConstantKind::Always}); static constexpr auto SingletonInstId = MakeSingletonInstId(); + static constexpr auto SingletonTypeId = + TypeId::ForTypeConstant(ConstantId::ForTemplateConstant(SingletonInstId)); TypeId type_id; }; @@ -587,6 +590,10 @@ struct ErrorInst { .is_type = InstIsType::Always, .constant_kind = InstConstantKind::Always}); static constexpr auto SingletonInstId = MakeSingletonInstId(); + static constexpr auto SingletonConstantId = + ConstantId::ForTemplateConstant(SingletonInstId); + static constexpr auto SingletonTypeId = + TypeId::ForTypeConstant(SingletonConstantId); TypeId type_id; }; @@ -1372,6 +1379,8 @@ struct TypeType { .is_type = InstIsType::Always, .constant_kind = InstConstantKind::Always}); static constexpr auto SingletonInstId = MakeSingletonInstId(); + static constexpr auto SingletonTypeId = + TypeId::ForTypeConstant(ConstantId::ForTemplateConstant(SingletonInstId)); TypeId type_id; };