diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 5d0b4ba58f4a..5baa617b34c5 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -42,6 +42,7 @@ cc_library( "return.cpp", "subpattern.cpp", "subst.cpp", + "type.cpp", "type_completion.cpp", ], hdrs = [ @@ -78,6 +79,7 @@ cc_library( "return.h", "subpattern.h", "subst.h", + "type.h", "type_completion.h", ], deps = [ diff --git a/toolchain/check/call.cpp b/toolchain/check/call.cpp index 4519b0c708cf..2f8cd71a6616 100644 --- a/toolchain/check/call.cpp +++ b/toolchain/check/call.cpp @@ -9,6 +9,7 @@ #include "toolchain/check/convert.h" #include "toolchain/check/deduce.h" #include "toolchain/check/function.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/builtin_function_kind.h" #include "toolchain/sem_ir/entity_with_params_base.h" @@ -118,8 +119,9 @@ static auto PerformCallToGenericInterface( if (!callee_specific_id) { return SemIR::ErrorInst::SingletonInstId; } - return context.GetOrAddInst(loc_id, context.FacetTypeFromInterface( - interface_id, *callee_specific_id)); + return context.GetOrAddInst( + loc_id, + FacetTypeFromInterface(context, interface_id, *callee_specific_id)); } auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, @@ -164,8 +166,8 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, callee_id = context.GetOrAddInst( context.insts().GetLocId(callee_id), SemIR::SpecificFunction{ - .type_id = context.GetSingletonType( - SemIR::SpecificFunctionType::SingletonInstId), + .type_id = GetSingletonType( + context, SemIR::SpecificFunctionType::SingletonInstId), .callee_id = callee_id, .specific_id = *callee_specific_id}); if (callee_function.self_type_id.has_value()) { @@ -201,7 +203,7 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, // For functions with an implicit return type, the return type is the // empty tuple type. if (!return_info.type_id.has_value()) { - return_info.type_id = context.GetTupleType({}); + return_info.type_id = GetTupleType(context, {}); } break; case SemIR::InitRepr::ByCopy: diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index db0d4e2786f1..2d3f10c8f328 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -18,6 +18,7 @@ #include "toolchain/check/import_cpp.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/node_id_traversal.h" +#include "toolchain/check/type.h" namespace Carbon::Check { @@ -92,7 +93,7 @@ auto CheckUnit::Run() -> void { auto CheckUnit::InitPackageScopeAndImports() -> void { // Importing makes many namespaces, so only canonicalize the type once. auto namespace_type_id = - context_.GetSingletonType(SemIR::NamespaceType::SingletonInstId); + GetSingletonType(context_, SemIR::NamespaceType::SingletonInstId); // Define the package scope, with an instruction for `package` expressions to // reference. diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 1007446c0582..15d0f4cf12d1 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -227,123 +227,6 @@ auto Context::Finalize() -> void { global_init_.Finalize(); } -auto Context::GetTypeIdForTypeConstant(SemIR::ConstantId constant_id) - -> SemIR::TypeId { - CARBON_CHECK(constant_id.is_constant(), - "Canonicalizing non-constant type: {0}", constant_id); - auto type_id = - insts().Get(constant_values().GetInstId(constant_id)).type_id(); - CARBON_CHECK(type_id == SemIR::TypeType::SingletonTypeId || - constant_id == SemIR::ErrorInst::SingletonConstantId, - "Forming type ID for non-type constant of type {0}", - types().GetAsInst(type_id)); - - return SemIR::TypeId::ForTypeConstant(constant_id); -} - -auto Context::FacetTypeFromInterface(SemIR::InterfaceId interface_id, - SemIR::SpecificId specific_id) - -> SemIR::FacetType { - SemIR::FacetTypeId facet_type_id = facet_types().Add( - SemIR::FacetTypeInfo{.impls_constraints = {{interface_id, specific_id}}, - .other_requirements = false}); - 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 -static auto GetTypeImpl(Context& context, EachArgT... each_arg) - -> SemIR::TypeId { - // TODO: Remove inst_id parameter from TryEvalInst. - InstT inst = {SemIR::TypeType::SingletonTypeId, each_arg...}; - return context.GetTypeIdForTypeConstant( - TryEvalInst(context, SemIR::InstId::None, inst)); -} - -// Gets or forms a type_id for a type, given the instruction kind and arguments, -// and completes the type. This should only be used when type completion cannot -// fail. -template -static auto GetCompleteTypeImpl(Context& context, EachArgT... each_arg) - -> SemIR::TypeId { - auto type_id = GetTypeImpl(context, each_arg...); - CompleteTypeOrCheckFail(context, type_id); - return type_id; -} - -auto Context::GetStructType(SemIR::StructTypeFieldsId fields_id) - -> SemIR::TypeId { - return GetTypeImpl(*this, fields_id); -} - -auto Context::GetTupleType(llvm::ArrayRef type_ids) - -> SemIR::TypeId { - return GetTypeImpl(*this, - type_blocks().AddCanonical(type_ids)); -} - -auto Context::GetAssociatedEntityType(SemIR::TypeId interface_type_id) - -> SemIR::TypeId { - return GetTypeImpl(*this, interface_type_id); -} - -auto Context::GetSingletonType(SemIR::InstId singleton_id) -> SemIR::TypeId { - CARBON_CHECK(SemIR::IsSingletonInstId(singleton_id)); - auto type_id = GetTypeIdForTypeInst(singleton_id); - // To keep client code simpler, complete builtin types before returning them. - CompleteTypeOrCheckFail(*this, type_id); - return type_id; -} - -auto Context::GetClassType(SemIR::ClassId class_id, - SemIR::SpecificId specific_id) -> SemIR::TypeId { - return GetTypeImpl(*this, class_id, specific_id); -} - -auto Context::GetFunctionType(SemIR::FunctionId fn_id, - SemIR::SpecificId specific_id) -> SemIR::TypeId { - return GetCompleteTypeImpl(*this, fn_id, specific_id); -} - -auto Context::GetFunctionTypeWithSelfType( - SemIR::InstId interface_function_type_id, SemIR::InstId self_id) - -> SemIR::TypeId { - return GetCompleteTypeImpl( - *this, interface_function_type_id, self_id); -} - -auto Context::GetGenericClassType(SemIR::ClassId class_id, - SemIR::SpecificId enclosing_specific_id) - -> SemIR::TypeId { - return GetCompleteTypeImpl(*this, class_id, - enclosing_specific_id); -} - -auto Context::GetGenericInterfaceType(SemIR::InterfaceId interface_id, - SemIR::SpecificId enclosing_specific_id) - -> SemIR::TypeId { - return GetCompleteTypeImpl( - *this, interface_id, enclosing_specific_id); -} - -auto Context::GetInterfaceType(SemIR::InterfaceId interface_id, - SemIR::SpecificId specific_id) -> SemIR::TypeId { - return GetTypeImpl( - *this, FacetTypeFromInterface(interface_id, specific_id).facet_type_id); -} - -auto Context::GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId { - return GetTypeImpl(*this, pointee_type_id); -} - -auto Context::GetUnboundElementType(SemIR::TypeId class_type_id, - SemIR::TypeId element_type_id) - -> SemIR::TypeId { - return GetTypeImpl(*this, class_type_id, - element_type_id); -} - auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void { output << "Check::Context\n"; diff --git a/toolchain/check/context.h b/toolchain/check/context.h index bb5f50bb42cc..21a5f4ed957f 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -178,97 +178,6 @@ class Context { sem_ir().insts().SetLocId(inst_id, SemIR::LocId(node_id)); } - // Returns the type ID for a constant that is a type value, i.e. it is a value - // of type `TypeType`. - // - // Facet values are of the same typishness as types, but are not themselves - // types, so they can not be passed here. They should be converted to a type - // through an `as type` conversion, that is, to a value of type `TypeType`. - auto GetTypeIdForTypeConstant(SemIR::ConstantId constant_id) -> SemIR::TypeId; - - // Returns the type ID for an instruction whose constant value is a type - // value, i.e. it is a value of type `TypeType`. - // - // Instructions whose values are facet values (see `FacetValue`) produce a - // value of the same typishness as types, but which are themselves not types, - // so they can not be passed here. They should be converted to a type through - // an `as type` conversion, such as to a `FacetAccessType` instruction whose - // value is of type `TypeType`. - auto GetTypeIdForTypeInst(SemIR::InstId inst_id) -> SemIR::TypeId { - return GetTypeIdForTypeConstant(constant_values().Get(inst_id)); - } - - // Returns whether `type_id` represents a facet type. - auto IsFacetType(SemIR::TypeId type_id) -> bool { - return type_id == SemIR::TypeType::SingletonTypeId || - types().Is(type_id); - } - - // Create a FacetType typed instruction object consisting of a single - // interface. - auto FacetTypeFromInterface(SemIR::InterfaceId interface_id, - SemIR::SpecificId specific_id) - -> SemIR::FacetType; - - // TODO: Consider moving these `Get*Type` functions to a separate class. - - // Gets the type to use for an unbound associated entity declared in this - // interface. For example, this is the type of `I.T` after - // `interface I { let T:! type; }`. - // The name of the interface is used for diagnostics. - // TODO: Should we use a different type for each such entity, or the same type - // for all associated entities? - auto GetAssociatedEntityType(SemIR::TypeId interface_type_id) - -> SemIR::TypeId; - - // Gets a singleton type. The returned type will be complete. Requires that - // `singleton_id` is already validated to be a singleton. - auto GetSingletonType(SemIR::InstId singleton_id) -> SemIR::TypeId; - - // Gets a class type. - auto GetClassType(SemIR::ClassId class_id, SemIR::SpecificId specific_id) - -> SemIR::TypeId; - - // Gets a function type. The returned type will be complete. - auto GetFunctionType(SemIR::FunctionId fn_id, SemIR::SpecificId specific_id) - -> SemIR::TypeId; - - // Gets the type of an associated function with the `Self` parameter bound to - // a particular value. The returned type will be complete. - auto GetFunctionTypeWithSelfType(SemIR::InstId interface_function_type_id, - SemIR::InstId self_id) -> SemIR::TypeId; - - // Gets a generic class type, which is the type of a name of a generic class, - // such as the type of `Vector` given `class Vector(T:! type)`. The returned - // type will be complete. - auto GetGenericClassType(SemIR::ClassId class_id, - SemIR::SpecificId enclosing_specific_id) - -> SemIR::TypeId; - - // Gets a generic interface type, which is the type of a name of a generic - // interface, such as the type of `AddWith` given - // `interface AddWith(T:! type)`. The returned type will be complete. - auto GetGenericInterfaceType(SemIR::InterfaceId interface_id, - SemIR::SpecificId enclosing_specific_id) - -> SemIR::TypeId; - - // Gets the facet type corresponding to a particular interface. - auto GetInterfaceType(SemIR::InterfaceId interface_id, - SemIR::SpecificId specific_id) -> SemIR::TypeId; - - // Returns a pointer type whose pointee type is `pointee_type_id`. - auto GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId; - - // Returns a struct type with the given fields. - auto GetStructType(SemIR::StructTypeFieldsId fields_id) -> SemIR::TypeId; - - // Returns a tuple type with the given element types. - auto GetTupleType(llvm::ArrayRef type_ids) -> SemIR::TypeId; - - // Returns an unbound element type. - auto GetUnboundElementType(SemIR::TypeId class_type_id, - SemIR::TypeId element_type_id) -> SemIR::TypeId; - // Adds an exported name. auto AddExport(SemIR::InstId inst_id) -> void { exports_.push_back(inst_id); } diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 19a8783ccb6d..060375ef6fee 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -16,6 +16,7 @@ #include "toolchain/check/impl_lookup.h" #include "toolchain/check/operator.h" #include "toolchain/check/pattern_match.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/copy_on_write_block.h" @@ -159,8 +160,8 @@ static auto MakeElementAccessInst(Context& context, SemIR::LocId loc_id, // index so that we don't need an integer literal instruction here, and // remove this special case. auto index_id = block.template AddInst( - loc_id, {.type_id = context.GetSingletonType( - SemIR::IntLiteralType::SingletonInstId), + loc_id, {.type_id = GetSingletonType( + context, SemIR::IntLiteralType::SingletonInstId), .int_id = context.ints().Add(static_cast(i))}); return block.template AddInst( loc_id, {elem_type_id, aggregate_id, index_id}); @@ -964,7 +965,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id, // iterative approach. type_ids.push_back(ExprAsType(context, loc_id, tuple_inst_id).type_id); } - auto tuple_type_id = context.GetTupleType(type_ids); + auto tuple_type_id = GetTupleType(context, type_ids); return sem_ir.types().GetInstId(tuple_type_id); } @@ -1298,7 +1299,7 @@ auto ConvertToBoolValue(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id) -> SemIR::InstId { return ConvertToValueOfType( context, loc_id, value_id, - context.GetSingletonType(SemIR::BoolType::SingletonInstId)); + GetSingletonType(context, SemIR::BoolType::SingletonInstId)); } auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node, @@ -1361,7 +1362,7 @@ auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id) } return {.inst_id = type_inst_id, - .type_id = context.GetTypeIdForTypeConstant(type_const_id)}; + .type_id = context.types().GetTypeIdForTypeConstantId(type_const_id)}; } } // namespace Carbon::Check diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index 9bc1677e19c4..e13fa65466ed 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -551,7 +551,8 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool { auto param_type_const_id = SubstConstant( context(), binding_type_id.AsConstantId(), substitutions_); CARBON_CHECK(param_type_const_id.has_value()); - binding_type_id = context().GetTypeIdForTypeConstant(param_type_const_id); + binding_type_id = + context().types().GetTypeIdForTypeConstantId(param_type_const_id); // TODO: Suppress diagnostics here if `diagnose_` is false. DiagnosticAnnotationScope annotate_diagnostics( diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 124b07e4b97b..4a01ee91eed6 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -8,6 +8,7 @@ #include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/generic.h" #include "toolchain/check/import_ref.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/diagnostic_emitter.h" #include "toolchain/diagnostics/format_providers.h" @@ -124,7 +125,7 @@ class EvalContext { // Gets the constant value of the specified type in this context. auto GetConstantValueAsType(SemIR::TypeId id) -> SemIR::TypeId { - return context().GetTypeIdForTypeConstant(GetConstantValue(id)); + return context().types().GetTypeIdForTypeConstantId(GetConstantValue(id)); } // Gets the instruction describing the constant value of the specified type in @@ -332,7 +333,7 @@ static auto GetConstantValue(EvalContext& eval_context, SemIR::TypeId type_id, Phase* phase) -> SemIR::TypeId { auto const_id = eval_context.GetConstantValue(type_id); *phase = LatestPhase(*phase, GetPhase(eval_context, const_id)); - return eval_context.context().GetTypeIdForTypeConstant(const_id); + return eval_context.context().types().GetTypeIdForTypeConstantId(const_id); } // If the given instruction block contains only constants, returns a @@ -689,7 +690,7 @@ static auto MakeIntTypeResult(Context& context, SemIRLoc loc, SemIR::IntKind int_kind, SemIR::InstId width_id, Phase phase) -> SemIR::ConstantId { auto result = SemIR::IntType{ - .type_id = context.GetSingletonType(SemIR::TypeType::SingletonInstId), + .type_id = GetSingletonType(context, SemIR::TypeType::SingletonInstId), .int_kind = int_kind, .bit_width_id = width_id}; if (!ValidateIntType(context, loc, result)) { @@ -1751,8 +1752,9 @@ static auto TryEvalInstInContext(EvalContext& eval_context, // A non-generic interface declaration evaluates to a facet type. return MakeConstantResult( eval_context.context(), - eval_context.context().FacetTypeFromInterface( - interface_decl.interface_id, SemIR::SpecificId::None), + FacetTypeFromInterface(eval_context.context(), + interface_decl.interface_id, + SemIR::SpecificId::None), Phase::Concrete); } @@ -2074,8 +2076,8 @@ static auto TryEvalInstInContext(EvalContext& eval_context, case CARBON_KIND(SemIR::RequireCompleteType require_complete): { auto phase = Phase::Concrete; - auto witness_type_id = eval_context.context().GetSingletonType( - SemIR::WitnessType::SingletonInstId); + auto witness_type_id = GetSingletonType( + eval_context.context(), SemIR::WitnessType::SingletonInstId); auto complete_type_id = GetConstantValue( eval_context, require_complete.complete_type_id, &phase); diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index 7c798d75f06c..1ae3ce150058 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -9,6 +9,7 @@ #include "toolchain/check/eval.h" #include "toolchain/check/generic_region_stack.h" #include "toolchain/check/subst.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" @@ -179,7 +180,7 @@ static auto AddGenericTypeToEvalBlock( SubstInst(context, context.types().GetInstId(type_id), RebuildGenericConstantInEvalBlockCallbacks( context, generic_id, region, loc_id, constants_in_generic)); - return context.GetTypeIdForTypeInst(type_inst_id); + return context.types().GetTypeIdForTypeInstId(type_inst_id); } // Adds instructions to compute the substituted value of `inst_id` in each @@ -500,20 +501,20 @@ auto GetInstForSpecific(Context& context, SemIR::SpecificId specific_id) CARBON_KIND_SWITCH(decl) { case CARBON_KIND(SemIR::ClassDecl class_decl): { return context.types().GetInstId( - context.GetClassType(class_decl.class_id, specific_id)); + GetClassType(context, class_decl.class_id, specific_id)); } case CARBON_KIND(SemIR::InterfaceDecl interface_decl): { return context.types().GetInstId( - context.GetInterfaceType(interface_decl.interface_id, specific_id)); + GetInterfaceType(context, interface_decl.interface_id, specific_id)); } case SemIR::FunctionDecl::Kind: { - return context.constant_values().GetInstId( - TryEvalInst(context, SemIR::InstId::None, - SemIR::SpecificFunction{ - .type_id = context.GetSingletonType( - SemIR::SpecificFunctionType::SingletonInstId), - .callee_id = generic.decl_id, - .specific_id = specific_id})); + return context.constant_values().GetInstId(TryEvalInst( + context, SemIR::InstId::None, + SemIR::SpecificFunction{ + .type_id = GetSingletonType( + context, SemIR::SpecificFunctionType::SingletonInstId), + .callee_id = generic.decl_id, + .specific_id = specific_id})); } case SemIR::AssociatedConstantDecl::Kind: { // TODO: We don't have a good instruction to use here. diff --git a/toolchain/check/handle_array.cpp b/toolchain/check/handle_array.cpp index d45c4f24cb3d..56b3bafe3c5b 100644 --- a/toolchain/check/handle_array.cpp +++ b/toolchain/check/handle_array.cpp @@ -5,6 +5,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/check/handle.h" +#include "toolchain/check/type.h" #include "toolchain/parse/node_kind.h" namespace Carbon::Check { @@ -51,7 +52,7 @@ auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool { bound_inst_id = ConvertToValueOfType( context, context.insts().GetLocId(bound_inst_id), bound_inst_id, - context.GetSingletonType(SemIR::IntLiteralType::SingletonInstId)); + GetSingletonType(context, SemIR::IntLiteralType::SingletonInstId)); context.AddInstAndPush( node_id, {.type_id = SemIR::TypeType::SingletonTypeId, .bound_id = bound_inst_id, diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index 6e21770d0f26..827856bf4daa 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -9,6 +9,7 @@ #include "toolchain/check/name_lookup.h" #include "toolchain/check/return.h" #include "toolchain/check/subpattern.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/ids.h" @@ -124,7 +125,7 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, context.parse_tree().As(node_id); auto& class_info = context.classes().Get(parent_class_decl->class_id); auto field_type_id = - context.GetUnboundElementType(class_info.self_type_id, cast_type_id); + GetUnboundElementType(context, class_info.self_type_id, cast_type_id); auto field_id = context.AddInst( binding_id, {.type_id = field_type_id, .name_id = name_id, diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index 50b854b47026..69f2eb6f8aa1 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -16,6 +16,7 @@ #include "toolchain/check/modifiers.h" #include "toolchain/check/name_component.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/parse/node_ids.h" #include "toolchain/sem_ir/function.h" @@ -243,8 +244,8 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, class_info.generic_id = BuildGenericDecl(context, class_decl_id); class_decl.class_id = context.classes().Add(class_info); if (class_info.has_parameters()) { - class_decl.type_id = context.GetGenericClassType( - class_decl.class_id, context.scope_stack().PeekSpecificId()); + class_decl.type_id = GetGenericClassType( + context, class_decl.class_id, context.scope_stack().PeekSpecificId()); } } else { FinishGenericRedecl(context, class_decl_id, class_info.generic_id); @@ -260,11 +261,12 @@ 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::None, - SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, - .class_id = class_decl.class_id, - .specific_id = specific_id})); + class_info.self_type_id = + context.types().GetTypeIdForTypeConstantId(TryEvalInst( + context, SemIR::InstId::None, + SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = class_decl.class_id, + .specific_id = specific_id})); } if (!is_definition && context.sem_ir().is_impl() && !is_extern) { @@ -542,8 +544,8 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { // The `base` value in the class scope has an unbound element type. Instance // binding will be performed when it's found by name lookup into an instance. - auto field_type_id = - context.GetUnboundElementType(class_info.self_type_id, base_info.type_id); + auto field_type_id = GetUnboundElementType(context, class_info.self_type_id, + base_info.type_id); class_info.base_id = context.AddInst( node_id, {.type_id = field_type_id, .base_type_inst_id = base_info.inst_id, @@ -628,9 +630,9 @@ static auto CheckCompleteAdapterClassType(Context& context, auto object_repr_id = context.types().GetObjectRepr(adapted_type_id); return context.AddInst( - node_id, - {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId), - .object_repr_id = object_repr_id}); + node_id, {.type_id = GetSingletonType( + context, SemIR::WitnessType::SingletonInstId), + .object_repr_id = object_repr_id}); } static auto AddStructTypeFields( @@ -689,8 +691,9 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, if (defining_vptr) { struct_type_fields.push_back( {.name_id = SemIR::NameId::Vptr, - .type_id = context.GetPointerType( - context.GetSingletonType(SemIR::VtableType::SingletonInstId))}); + .type_id = GetPointerType( + context, + GetSingletonType(context, SemIR::VtableType::SingletonInstId))}); } if (base_type_id.has_value()) { auto base_decl = context.insts().GetAs(class_info.base_id); @@ -745,16 +748,17 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, } } class_info.vtable_id = context.AddInst( - node_id, {.type_id = context.GetSingletonType( - SemIR::VtableType::SingletonInstId), + node_id, {.type_id = GetSingletonType( + context, SemIR::VtableType::SingletonInstId), .virtual_functions_id = context.inst_blocks().Add(vtable)}); } return context.AddInst( node_id, - {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId), - .object_repr_id = context.GetStructType( - AddStructTypeFields(context, struct_type_fields))}); + {.type_id = + GetSingletonType(context, SemIR::WitnessType::SingletonInstId), + .object_repr_id = GetStructType( + context, AddStructTypeFields(context, struct_type_fields))}); } auto HandleParseNode(Context& context, Parse::ClassDefinitionId node_id) diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 02c41743e1a1..8a1ff874212b 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -19,6 +19,7 @@ #include "toolchain/check/modifiers.h" #include "toolchain/check/name_component.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/sem_ir/builtin_function_kind.h" #include "toolchain/sem_ir/entry_point.h" @@ -309,8 +310,9 @@ static auto BuildFunctionDecl(Context& context, FinishGenericRedecl(context, decl_id, function_info.generic_id); // TODO: Validate that the redeclaration doesn't set an access modifier. } - function_decl.type_id = context.GetFunctionType( - function_decl.function_id, context.scope_stack().PeekSpecificId()); + function_decl.type_id = + GetFunctionType(context, function_decl.function_id, + context.scope_stack().PeekSpecificId()); // Write the function ID into the FunctionDecl. context.ReplaceInstBeforeConstantUse(decl_id, function_decl); @@ -351,7 +353,7 @@ static auto BuildFunctionDecl(Context& context, !function_info.param_patterns_id.has_value() || !context.inst_blocks().Get(function_info.param_patterns_id).empty() || (return_type_id.has_value() && - return_type_id != context.GetTupleType({}) && + return_type_id != GetTupleType(context, {}) && // TODO: Decide on valid return types for `Main.Run`. Perhaps we should // have an interface for this. return_type_id != MakeIntType(context, node_id, SemIR::IntKind::Signed, @@ -548,7 +550,7 @@ static auto IsValidBuiltinDeclaration(Context& context, // Get the return type. This is `()` if none was specified. auto return_type_id = function.GetDeclaredReturnType(context.sem_ir()); if (!return_type_id.has_value()) { - return_type_id = context.GetTupleType({}); + return_type_id = GetTupleType(context, {}); } return builtin_kind.IsValidType(context.sem_ir(), param_type_ids, diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 31571baa82b6..e2fc2c51f8f7 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -12,6 +12,7 @@ #include "toolchain/check/modifiers.h" #include "toolchain/check/name_lookup.h" #include "toolchain/check/pattern_match.h" +#include "toolchain/check/type.h" #include "toolchain/parse/typed_nodes.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" @@ -307,7 +308,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id, context.node_stack().PopExprWithNodeId(); auto [self_type_node, self_inst_id] = context.node_stack().PopWithNodeId(); - auto self_type_id = context.GetTypeIdForTypeInst(self_inst_id); + auto self_type_id = context.types().GetTypeIdForTypeInstId(self_inst_id); // Pop the `impl` introducer and any `forall` parameters as a "name". auto name = PopImplIntroducerAndParamsAsNameComponent(context, node_id); auto decl_block_id = context.inst_block_stack().Pop(); diff --git a/toolchain/check/handle_index.cpp b/toolchain/check/handle_index.cpp index a1899a762804..8e495098c475 100644 --- a/toolchain/check/handle_index.cpp +++ b/toolchain/check/handle_index.cpp @@ -11,6 +11,7 @@ #include "toolchain/check/literal.h" #include "toolchain/check/name_lookup.h" #include "toolchain/check/operator.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/diagnostic.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/typed_insts.h" @@ -53,9 +54,10 @@ static auto GetIndexWithArgs(Context& context, Parse::NodeId node_id, } for (const auto& impl : context.impls().array_ref()) { - auto impl_self_type_id = context.GetTypeIdForTypeInst(impl.self_id); + auto impl_self_type_id = + context.types().GetTypeIdForTypeInstId(impl.self_id); auto impl_constraint_type_id = - context.GetTypeIdForTypeInst(impl.constraint_id); + context.types().GetTypeIdForTypeInstId(impl.constraint_id); if (impl_self_type_id != self_id) { continue; @@ -115,7 +117,7 @@ static auto PerformIndexWith(Context& context, Parse::NodeId node_id, // The first argument of the `IndexWith` interface corresponds to the // `SubscriptType`, so first cast `index_inst_id` to that type. - auto subscript_type_id = context.GetTypeIdForTypeInst((*args)[0]); + auto subscript_type_id = context.types().GetTypeIdForTypeInstId((*args)[0]); auto cast_index_id = ConvertToValueOfType(context, node_id, index_inst_id, subscript_type_id); diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index 991315678697..19cf5a893664 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -10,6 +10,7 @@ #include "toolchain/check/modifiers.h" #include "toolchain/check/name_component.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { @@ -116,8 +117,9 @@ static auto BuildInterfaceDecl(Context& context, interface_info.generic_id = BuildGenericDecl(context, interface_decl_id); interface_decl.interface_id = context.interfaces().Add(interface_info); if (interface_info.has_parameters()) { - interface_decl.type_id = context.GetGenericInterfaceType( - interface_decl.interface_id, context.scope_stack().PeekSpecificId()); + interface_decl.type_id = + GetGenericInterfaceType(context, interface_decl.interface_id, + context.scope_stack().PeekSpecificId()); } } else { FinishGenericRedecl( @@ -163,8 +165,8 @@ auto HandleParseNode(Context& context, // Declare and introduce `Self`. SemIR::FacetType facet_type = - context.FacetTypeFromInterface(interface_id, self_specific_id); - SemIR::TypeId self_type_id = context.GetTypeIdForTypeConstant( + FacetTypeFromInterface(context, interface_id, self_specific_id); + SemIR::TypeId self_type_id = context.types().GetTypeIdForTypeConstantId( TryEvalInst(context, SemIR::InstId::None, facet_type)); // We model `Self` as a symbolic binding whose type is the interface. diff --git a/toolchain/check/handle_literal.cpp b/toolchain/check/handle_literal.cpp index b532d0f01d2b..0cbc60b966d2 100644 --- a/toolchain/check/handle_literal.cpp +++ b/toolchain/check/handle_literal.cpp @@ -7,6 +7,7 @@ #include "toolchain/check/handle.h" #include "toolchain/check/literal.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/typed_insts.h" @@ -16,7 +17,7 @@ auto HandleParseNode(Context& context, Parse::BoolLiteralFalseId node_id) -> bool { context.AddInstAndPush( node_id, - {.type_id = context.GetSingletonType(SemIR::BoolType::SingletonInstId), + {.type_id = GetSingletonType(context, SemIR::BoolType::SingletonInstId), .value = SemIR::BoolValue::False}); return true; } @@ -25,7 +26,7 @@ auto HandleParseNode(Context& context, Parse::BoolLiteralTrueId node_id) -> bool { context.AddInstAndPush( node_id, - {.type_id = context.GetSingletonType(SemIR::BoolType::SingletonInstId), + {.type_id = GetSingletonType(context, SemIR::BoolType::SingletonInstId), .value = SemIR::BoolValue::True}); return true; } @@ -76,8 +77,8 @@ auto HandleParseNode(Context& context, Parse::RealLiteralId node_id) -> bool { auto float_id = context.sem_ir().floats().Add(llvm::APFloat(double_val)); context.AddInstAndPush( - node_id, {.type_id = context.GetSingletonType( - SemIR::LegacyFloatType::SingletonInstId), + node_id, {.type_id = GetSingletonType( + context, SemIR::LegacyFloatType::SingletonInstId), .float_id = float_id}); return true; } @@ -85,7 +86,7 @@ auto HandleParseNode(Context& context, Parse::RealLiteralId node_id) -> bool { auto HandleParseNode(Context& context, Parse::StringLiteralId node_id) -> bool { context.AddInstAndPush( node_id, - {.type_id = context.GetSingletonType(SemIR::StringType::SingletonInstId), + {.type_id = GetSingletonType(context, SemIR::StringType::SingletonInstId), .string_literal_id = context.tokens().GetStringLiteralValue( context.parse_tree().node_token(node_id))}); return true; diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index fcdc93c982d2..450be40ecd30 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -9,6 +9,7 @@ #include "toolchain/check/name_component.h" #include "toolchain/check/name_lookup.h" #include "toolchain/check/pointer_dereference.h" +#include "toolchain/check/type.h" #include "toolchain/lex/token_kind.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/typed_insts.h" @@ -238,8 +239,8 @@ auto HandleParseNode(Context& context, Parse::DesignatorExprId node_id) auto HandleParseNode(Context& context, Parse::PackageExprId node_id) -> bool { context.AddInstAndPush( - node_id, {.type_id = context.GetSingletonType( - SemIR::NamespaceType::SingletonInstId), + node_id, {.type_id = GetSingletonType( + context, SemIR::NamespaceType::SingletonInstId), .name_id = SemIR::NameId::PackageNamespace, .value_id = SemIR::Namespace::PackageInstId}); return true; diff --git a/toolchain/check/handle_namespace.cpp b/toolchain/check/handle_namespace.cpp index 08f78775d34f..2e7b3df199f8 100644 --- a/toolchain/check/handle_namespace.cpp +++ b/toolchain/check/handle_namespace.cpp @@ -8,6 +8,7 @@ #include "toolchain/check/modifiers.h" #include "toolchain/check/name_component.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/name_scope.h" @@ -38,7 +39,7 @@ auto HandleParseNode(Context& context, Parse::NamespaceId node_id) -> bool { LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None); auto namespace_inst = SemIR::Namespace{ - context.GetSingletonType(SemIR::NamespaceType::SingletonInstId), + GetSingletonType(context, SemIR::NamespaceType::SingletonInstId), SemIR::NameScopeId::None, SemIR::InstId::None}; auto namespace_id = context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, namespace_inst)); diff --git a/toolchain/check/handle_operator.cpp b/toolchain/check/handle_operator.cpp index ad71e659c05c..02947f30d42f 100644 --- a/toolchain/check/handle_operator.cpp +++ b/toolchain/check/handle_operator.cpp @@ -8,6 +8,7 @@ #include "toolchain/check/handle.h" #include "toolchain/check/operator.h" #include "toolchain/check/pointer_dereference.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/diagnostic_emitter.h" namespace Carbon::Check { @@ -244,7 +245,7 @@ auto HandleParseNode(Context& context, Parse::PrefixOperatorAmpId node_id) break; } context.AddInstAndPush( - node_id, SemIR::AddrOf{.type_id = context.GetPointerType(type_id), + node_id, SemIR::AddrOf{.type_id = GetPointerType(context, type_id), .lvalue_id = value_id}); return true; } diff --git a/toolchain/check/handle_struct.cpp b/toolchain/check/handle_struct.cpp index cfb222e23205..33ea0a230f9d 100644 --- a/toolchain/check/handle_struct.cpp +++ b/toolchain/check/handle_struct.cpp @@ -6,6 +6,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/check/handle.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" namespace Carbon::Check { @@ -141,8 +142,8 @@ auto HandleParseNode(Context& context, Parse::StructLiteralId node_id) -> bool { /*is_struct_type_literal=*/false)) { context.node_stack().Push(node_id, SemIR::ErrorInst::SingletonInstId); } else { - auto type_id = context.GetStructType( - context.struct_type_fields().AddCanonical(fields)); + auto type_id = GetStructType( + context, context.struct_type_fields().AddCanonical(fields)); auto value_id = context.AddInst( node_id, {.type_id = type_id, .elements_id = elements_id}); diff --git a/toolchain/check/handle_tuple_literal.cpp b/toolchain/check/handle_tuple_literal.cpp index 8d7849e5a9fb..69e52e33057b 100644 --- a/toolchain/check/handle_tuple_literal.cpp +++ b/toolchain/check/handle_tuple_literal.cpp @@ -4,6 +4,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/handle.h" +#include "toolchain/check/type.h" namespace Carbon::Check { @@ -32,7 +33,7 @@ auto HandleParseNode(Context& context, Parse::TupleLiteralId node_id) -> bool { for (auto inst : inst_block) { type_ids.push_back(context.insts().Get(inst).type_id()); } - auto type_id = context.GetTupleType(type_ids); + auto type_id = GetTupleType(context, type_ids); auto value_id = context.AddInst( node_id, {.type_id = type_id, .elements_id = refs_id}); diff --git a/toolchain/check/handle_where.cpp b/toolchain/check/handle_where.cpp index 5280b4e0857a..ca57fc97a508 100644 --- a/toolchain/check/handle_where.cpp +++ b/toolchain/check/handle_where.cpp @@ -17,7 +17,7 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool { auto self_type_id = ExprAsType(context, self_node, self_id).type_id; // Only facet types may have `where` restrictions. if (self_type_id != SemIR::ErrorInst::SingletonTypeId && - !context.IsFacetType(self_type_id)) { + !context.types().IsFacetType(self_type_id)) { CARBON_DIAGNOSTIC(WhereOnNonFacetType, Error, "left argument of `where` operator must be a facet type"); context.emitter().Emit(self_node, WhereOnNonFacetType); @@ -107,7 +107,7 @@ auto HandleParseNode(Context& context, Parse::RequirementImplsId node_id) 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::ErrorInst::SingletonTypeId && - !context.IsFacetType(rhs_as_type.type_id)) { + !context.types().IsFacetType(rhs_as_type.type_id)) { CARBON_DIAGNOSTIC( ImplsOnNonFacetType, Error, "right argument of `impls` requirement must be a facet type"); diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 37e1bde3ddf3..84247be54480 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -13,6 +13,7 @@ #include "toolchain/check/import_ref.h" #include "toolchain/check/interface.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/diagnostic_emitter.h" #include "toolchain/sem_ir/generic.h" @@ -85,7 +86,8 @@ auto ImplWitnessForDeclaration(Context& context, const SemIR::Impl& impl) -> SemIR::InstId { CARBON_CHECK(!impl.has_definition_started()); - auto facet_type_id = context.GetTypeIdForTypeInst(impl.constraint_id); + auto facet_type_id = + context.types().GetTypeIdForTypeInstId(impl.constraint_id); if (facet_type_id == SemIR::ErrorInst::SingletonTypeId) { return SemIR::ErrorInst::SingletonInstId; } @@ -133,7 +135,8 @@ auto ImplWitnessForDeclaration(Context& context, const SemIR::Impl& impl) auto table_id = context.inst_blocks().Add(table); return context.AddInst( context.insts().GetLocId(impl.latest_decl_id()), - {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId), + {.type_id = + GetSingletonType(context, SemIR::WitnessType::SingletonInstId), .elements_id = table_id, .specific_id = context.generics().GetSelfSpecific(impl.generic_id)}); } @@ -162,7 +165,8 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context, if (witness_id == SemIR::ErrorInst::SingletonInstId) { return; } - auto facet_type_id = context.GetTypeIdForTypeInst(impl.constraint_id); + auto facet_type_id = + context.types().GetTypeIdForTypeInstId(impl.constraint_id); CARBON_CHECK(facet_type_id != SemIR::ErrorInst::SingletonTypeId); auto facet_type = context.types().GetAs(facet_type_id); const SemIR::FacetTypeInfo& facet_type_info = @@ -239,7 +243,7 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context, // value for `Self`. assoc_const_type_id = GetTypeForSpecificAssociatedEntity( context, impl.constraint_id, interface_type->specific_id, decl_id, - context.GetTypeIdForTypeInst(impl.self_id), witness_id); + context.types().GetTypeIdForTypeInstId(impl.self_id), witness_id); // Perform the conversion of the value to the type. We skipped this when // forming the facet type because the type of the associated constant @@ -283,7 +287,8 @@ auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void { return; } - auto facet_type_id = context.GetTypeIdForTypeInst(impl.constraint_id); + auto facet_type_id = + context.types().GetTypeIdForTypeInstId(impl.constraint_id); CARBON_CHECK(facet_type_id != SemIR::ErrorInst::SingletonTypeId); auto facet_type = context.types().GetAs(facet_type_id); const SemIR::FacetTypeInfo& facet_type_info = @@ -340,7 +345,8 @@ auto FinishImplWitness(Context& context, SemIR::Impl& impl) -> void { return; } - auto facet_type_id = context.GetTypeIdForTypeInst(impl.constraint_id); + auto facet_type_id = + context.types().GetTypeIdForTypeInstId(impl.constraint_id); CARBON_CHECK(facet_type_id != SemIR::ErrorInst::SingletonTypeId); auto facet_type = context.types().GetAs(facet_type_id); const SemIR::FacetTypeInfo& facet_type_info = @@ -354,7 +360,7 @@ auto FinishImplWitness(Context& context, SemIR::Impl& impl) -> void { auto witness = context.insts().GetAs(impl.witness_id); auto witness_block = context.inst_blocks().GetMutable(witness.elements_id); auto& impl_scope = context.name_scopes().Get(impl.scope_id); - auto self_type_id = context.GetTypeIdForTypeInst(impl.self_id); + auto self_type_id = context.types().GetTypeIdForTypeInstId(impl.self_id); auto assoc_entities = context.inst_blocks().Get(interface.associated_entities_id); llvm::SmallVector used_decl_ids; diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index 337825a04c72..fc8b8cf6211e 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -11,6 +11,7 @@ #include "toolchain/check/import_ref.h" #include "toolchain/check/merge.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/parse/node_ids.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/ids.h" @@ -508,7 +509,7 @@ static auto AddNamespaceFromOtherPackage(Context& context, SemIR::NameId name_id) -> SemIR::InstId { auto namespace_type_id = - context.GetSingletonType(SemIR::NamespaceType::SingletonInstId); + GetSingletonType(context, SemIR::NamespaceType::SingletonInstId); AddImportNamespaceResult result = CopySingleNameScopeFromImportIR( context, namespace_type_id, /*copied_namespaces=*/nullptr, import_ir_id, import_inst_id, import_ns.name_scope_id, parent_scope_id, name_id); diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index 286e9510a2e4..005bf6eb7a12 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -17,6 +17,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/import.h" +#include "toolchain/check/type.h" #include "toolchain/diagnostics/diagnostic.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/name_scope.h" @@ -99,7 +100,7 @@ static auto AddNamespace(Context& context, PackageNameId cpp_package_id, return AddImportNamespace( context, - context.GetSingletonType(SemIR::NamespaceType::SingletonInstId), + GetSingletonType(context, SemIR::NamespaceType::SingletonInstId), SemIR::NameId::ForPackageName(cpp_package_id), SemIR::NameScopeId::Package, /*diagnose_duplicate_namespace=*/false, diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 02e807622ebb..aeed0dff9635 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -10,6 +10,7 @@ #include "toolchain/check/eval.h" #include "toolchain/check/generic.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/parse/node_ids.h" #include "toolchain/sem_ir/constant.h" #include "toolchain/sem_ir/file.h" @@ -520,9 +521,9 @@ class ImportRefResolver : public ImportContext { import_ir().constant_values().GetInstId(import_type_const_id); SemIR::IsSingletonInstId(import_type_inst_id)) { // Builtins don't require constant resolution; we can use them directly. - return local_context().GetSingletonType(import_type_inst_id); + return GetSingletonType(local_context(), import_type_inst_id); } else { - return local_context().GetTypeIdForTypeConstant( + return local_context().types().GetTypeIdForTypeConstantId( ResolveConstant(import_type_id.AsConstantId())); } } @@ -1023,7 +1024,7 @@ static auto GetLocalParamPatternsId(ImportContext& context, auto entity_name = context.import_entity_names().Get(binding.entity_name_id); auto name_id = GetLocalNameId(context, entity_name.name_id); - auto type_id = context.local_context().GetTypeIdForTypeConstant( + auto type_id = context.local_context().types().GetTypeIdForTypeConstantId( GetLocalConstantIdChecked(context, binding.type_id)); auto new_param_id = SemIR::InstId::None; @@ -1062,7 +1063,7 @@ static auto GetLocalParamPatternsId(ImportContext& context, .subpattern_id = new_param_id, .runtime_index = param_pattern.runtime_index})); if (addr_inst) { - type_id = context.local_context().GetTypeIdForTypeConstant( + type_id = context.local_context().types().GetTypeIdForTypeConstantId( GetLocalConstantIdChecked(context, addr_inst->type_id)); new_param_id = context.local_context().AddInstInNoBlock( context.local_context().MakeImportedLocAndInst( @@ -1093,7 +1094,7 @@ static auto GetLocalReturnSlotPatternId( auto return_slot_pattern = context.import_insts().GetAs( param_pattern.subpattern_id); - auto type_id = context.local_context().GetTypeIdForTypeConstant( + auto type_id = context.local_context().types().GetTypeIdForTypeConstantId( GetLocalConstantIdChecked(context, return_slot_pattern.type_id)); auto new_return_slot_pattern_id = context.local_context().AddInstInNoBlock( @@ -1357,7 +1358,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto element_type_id = - resolver.local_context().GetTypeIdForTypeConstant(element_type_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + element_type_const_id); return ResolveAs( resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .bound_id = bound_id, @@ -1412,8 +1414,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } // In the second phase, create the associated constant and its declaration. - auto type_id = - resolver.local_context().GetTypeIdForTypeConstant(type_const_id); + auto type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( + type_const_id); std::tie(assoc_const_id, const_id) = MakeAssociatedConstant(resolver, import_assoc_const, type_id); } else { @@ -1456,10 +1458,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, auto decl_id = AddImportRef(resolver, inst.decl_id); return ResolveAs( - resolver, {.type_id = resolver.local_context().GetTypeIdForTypeConstant( - type_const_id), - .index = inst.index, - .decl_id = decl_id}); + resolver, + {.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( + type_const_id), + .index = inst.index, + .decl_id = decl_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -1475,8 +1478,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, {.type_id = SemIR::TypeType::SingletonTypeId, - .interface_type_id = resolver.local_context().GetTypeIdForTypeConstant( - interface_inst_id)}); + .interface_type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId( + interface_inst_id)}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -1498,7 +1502,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, resolver.local_context().MakeImportedLocAndInst( AddImportIRInst(resolver, import_inst_id), {.type_id = - resolver.local_context().GetTypeIdForTypeConstant(type_const_id), + resolver.local_context().types().GetTypeIdForTypeConstantId( + type_const_id), .base_type_inst_id = base_type_inst_id, .index = inst.index})); return ResolveResult::Done(resolver.local_constant_values().Get(inst_id), @@ -1517,9 +1522,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Vtable inst) auto virtual_functions_id = GetLocalCanonicalInstBlockId( resolver, inst.virtual_functions_id, virtual_functions); return ResolveAs( - resolver, {.type_id = resolver.local_context().GetTypeIdForTypeConstant( - type_const_id), - .virtual_functions_id = virtual_functions_id}); + resolver, + {.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( + type_const_id), + .virtual_functions_id = virtual_functions_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -1545,7 +1551,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, import_entity_name.is_template); return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .entity_name_id = entity_name_id, .value_id = SemIR::InstId::None}); } @@ -1568,7 +1575,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, import_entity_name.is_template); return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .entity_name_id = entity_name_id}); } @@ -1585,10 +1593,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } return ResolveAs( - resolver, {.type_id = resolver.local_context().GetSingletonType( - SemIR::BoundMethodType::SingletonInstId), - .object_id = object_id, - .function_decl_id = function_decl_id}); + resolver, + {.type_id = GetSingletonType(resolver.local_context(), + SemIR::BoundMethodType::SingletonInstId), + .object_id = object_id, + .function_decl_id = function_decl_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Call inst) @@ -1603,7 +1612,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Call inst) return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .callee_id = callee_id, .args_id = GetLocalCanonicalInstBlockId(resolver, inst.args_id, args)}); } @@ -1630,8 +1640,8 @@ static auto MakeIncompleteClass(ImportContext& context, .is_dynamic = import_class.is_dynamic}}); if (import_class.has_parameters()) { - class_decl.type_id = context.local_context().GetGenericClassType( - class_decl.class_id, enclosing_specific_id); + class_decl.type_id = GetGenericClassType( + context.local_context(), class_decl.class_id, enclosing_specific_id); } // Write the class ID into the ClassDecl. @@ -1756,13 +1766,14 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, SetGenericData(resolver, import_class.generic_id, new_class.generic_id, generic_data); new_class.self_type_id = - resolver.local_context().GetTypeIdForTypeConstant(self_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + self_const_id); if (import_class.is_defined()) { auto complete_type_witness_id = AddLoadedImportRef( resolver, - resolver.local_context().GetSingletonType( - SemIR::WitnessType::SingletonInstId), + GetSingletonType(resolver.local_context(), + SemIR::WitnessType::SingletonInstId), import_class.complete_type_witness_id, complete_type_witness_const_id); AddClassDefinition(resolver, import_class, new_class, complete_type_witness_id, base_id, adapt_id, vtable_id); @@ -1812,11 +1823,13 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveResult::Retry(); } auto object_repr_id = - resolver.local_context().GetTypeIdForTypeConstant(object_repr_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + object_repr_const_id); return ResolveAs( - resolver, {.type_id = resolver.local_context().GetSingletonType( - SemIR::WitnessType::SingletonInstId), - .object_repr_id = object_repr_id}); + resolver, + {.type_id = GetSingletonType(resolver.local_context(), + SemIR::WitnessType::SingletonInstId), + .object_repr_id = object_repr_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -1827,7 +1840,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveResult::Retry(); } auto inner_type_id = - resolver.local_context().GetTypeIdForTypeConstant(inner_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + inner_const_id); return ResolveAs( resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .inner_id = inner_type_id}); @@ -1850,7 +1864,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, resolver.local_context().MakeImportedLocAndInst( AddImportIRInst(resolver, import_inst_id), {.type_id = - resolver.local_context().GetTypeIdForTypeConstant(const_id), + resolver.local_context().types().GetTypeIdForTypeConstantId( + const_id), .name_id = GetLocalNameId(resolver, inst.name_id), .index = inst.index})); return ResolveResult::Done(resolver.local_constant_values().Get(inst_id), @@ -1878,8 +1893,8 @@ static auto MakeFunctionDecl(ImportContext& context, {.return_slot_pattern_id = SemIR::InstId::None, .builtin_function_kind = import_function.builtin_function_kind}}); - function_decl.type_id = context.local_context().GetFunctionType( - function_decl.function_id, specific_id); + function_decl.type_id = GetFunctionType( + context.local_context(), function_decl.function_id, specific_id); // Write the function ID and type into the FunctionDecl. context.local_context().ReplaceInstBeforeConstantUse(function_decl_id, @@ -2199,8 +2214,9 @@ static auto MakeInterfaceDecl(ImportContext& context, {}}); if (import_interface.has_parameters()) { - interface_decl.type_id = context.local_context().GetGenericInterfaceType( - interface_decl.interface_id, enclosing_specific_id); + interface_decl.type_id = GetGenericInterfaceType( + context.local_context(), interface_decl.interface_id, + enclosing_specific_id); } // Write the interface ID into the InterfaceDecl. @@ -2341,9 +2357,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } return ResolveAs( - resolver, {.type_id = resolver.local_context().GetSingletonType( - SemIR::WitnessType::SingletonInstId), - .facet_value_inst_id = facet_value_inst_id}); + resolver, + {.type_id = GetSingletonType(resolver.local_context(), + SemIR::WitnessType::SingletonInstId), + .facet_value_inst_id = facet_value_inst_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2423,7 +2440,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .type_inst_id = type_inst_id, .witness_inst_id = witness_inst_id}); } @@ -2439,10 +2457,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, auto specific_id = GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data); return ResolveAs( - resolver, {.type_id = resolver.local_context().GetSingletonType( - SemIR::WitnessType::SingletonInstId), - .elements_id = elements_id, - .specific_id = specific_id}); + resolver, + {.type_id = GetSingletonType(resolver.local_context(), + SemIR::WitnessType::SingletonInstId), + .elements_id = elements_id, + .specific_id = specific_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2456,7 +2475,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .witness_id = witness_id, .index = inst.index}); } @@ -2477,7 +2497,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .int_id = int_id}); } @@ -2511,8 +2532,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveResult::Retry(); } - auto namespace_type_id = resolver.local_context().GetSingletonType( - SemIR::NamespaceType::SingletonInstId); + auto namespace_type_id = GetSingletonType( + resolver.local_context(), SemIR::NamespaceType::SingletonInstId); auto namespace_decl = SemIR::Namespace{.type_id = namespace_type_id, .name_scope_id = SemIR::NameScopeId::None, @@ -2543,7 +2564,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto pointee_type_id = - resolver.local_context().GetTypeIdForTypeConstant(pointee_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + pointee_const_id); return ResolveAs( resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .pointee_id = pointee_type_id}); @@ -2562,11 +2584,13 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, } auto complete_type_id = - resolver.local_context().GetTypeIdForTypeConstant(complete_type_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + complete_type_const_id); return ResolveAs( - resolver, {.type_id = resolver.local_context().GetSingletonType( - SemIR::WitnessType::SingletonInstId), - .complete_type_id = complete_type_id}); + resolver, + {.type_id = GetSingletonType(resolver.local_context(), + SemIR::WitnessType::SingletonInstId), + .complete_type_id = complete_type_id}); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2578,8 +2602,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveResult::Retry(); } - auto type_id = - resolver.local_context().GetTypeIdForTypeConstant(type_const_id); + auto type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( + type_const_id); auto specific_id = GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data); return ResolveAs( @@ -2607,7 +2631,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, llvm::zip(orig_fields, field_const_ids)) { auto name_id = GetLocalNameId(resolver, orig_field.name_id); auto field_type_id = - resolver.local_context().GetTypeIdForTypeConstant(field_const_id); + resolver.local_context().types().GetTypeIdForTypeConstantId( + field_const_id); new_fields.push_back({.name_id = name_id, .type_id = field_type_id}); } @@ -2627,7 +2652,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .elements_id = GetLocalCanonicalInstBlockId(resolver, inst.elements_id, elems)}); } @@ -2651,11 +2677,12 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, elem_type_ids.reserve(orig_elem_type_ids.size()); for (auto elem_const_id : elem_const_ids) { elem_type_ids.push_back( - resolver.local_context().GetTypeIdForTypeConstant(elem_const_id)); + resolver.local_context().types().GetTypeIdForTypeConstantId( + elem_const_id)); } return ResolveResult::Done(resolver.local_types().GetConstantId( - resolver.local_context().GetTupleType(elem_type_ids))); + GetTupleType(resolver.local_context(), elem_type_ids))); } static auto TryResolveTypedInst(ImportRefResolver& resolver, @@ -2668,7 +2695,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, return ResolveAs( resolver, - {.type_id = resolver.local_context().GetTypeIdForTypeConstant(type_id), + {.type_id = + resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), .elements_id = GetLocalCanonicalInstBlockId(resolver, inst.elements_id, elems)}); } @@ -2687,9 +2715,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, resolver, {.type_id = SemIR::TypeType::SingletonTypeId, .class_type_id = - resolver.local_context().GetTypeIdForTypeConstant(class_const_id), + resolver.local_context().types().GetTypeIdForTypeConstantId( + class_const_id), .element_type_id = - resolver.local_context().GetTypeIdForTypeConstant(elem_const_id)}); + resolver.local_context().types().GetTypeIdForTypeConstantId( + elem_const_id)}); } // Tries to resolve the InstId, returning a canonical constant when ready, or diff --git a/toolchain/check/interface.cpp b/toolchain/check/interface.cpp index 9f6a9c4ed284..4a925755895a 100644 --- a/toolchain/check/interface.cpp +++ b/toolchain/check/interface.cpp @@ -7,6 +7,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/eval.h" #include "toolchain/check/generic.h" +#include "toolchain/check/type.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/typed_insts.h" @@ -34,7 +35,7 @@ auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id, // Name lookup for the declaration's name should name the associated entity, // not the declaration itself. - auto type_id = context.GetAssociatedEntityType(self_type_id); + auto type_id = GetAssociatedEntityType(context, self_type_id); return context.AddInst( context.insts().GetLocId(decl_id), {.type_id = type_id, .index = index, .decl_id = decl_id}); @@ -173,8 +174,9 @@ auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc, GetSelfFacet(context, interface_specific_id, context.functions().Get(fn->function_id).generic_id, self_type_id, self_witness_id); - return context.GetFunctionTypeWithSelfType( - context.types().GetInstId(interface_fn_type_id), self_facet_id); + return GetFunctionTypeWithSelfType( + context, context.types().GetInstId(interface_fn_type_id), + self_facet_id); } else { CARBON_FATAL("Unexpected kind for associated constant {0}", decl); } diff --git a/toolchain/check/literal.cpp b/toolchain/check/literal.cpp index b38b3b64ecfe..310e87b1c145 100644 --- a/toolchain/check/literal.cpp +++ b/toolchain/check/literal.cpp @@ -8,14 +8,15 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" namespace Carbon::Check { auto MakeIntLiteral(Context& context, Parse::NodeId node_id, IntId int_id) -> SemIR::InstId { return context.AddInst( - node_id, {.type_id = context.GetSingletonType( - SemIR::IntLiteralType::SingletonInstId), + node_id, {.type_id = GetSingletonType( + context, SemIR::IntLiteralType::SingletonInstId), .int_id = int_id}); } diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 646a3f39bb0a..cb9c463f257c 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -14,6 +14,7 @@ #include "toolchain/check/import_ref.h" #include "toolchain/check/interface.h" #include "toolchain/check/name_lookup.h" +#include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/diagnostic_emitter.h" #include "toolchain/sem_ir/function.h" @@ -194,13 +195,13 @@ static auto PerformImplLookup( return SemIR::ErrorInst::SingletonInstId; } - auto self_type_id = context.GetTypeIdForTypeConstant(type_const_id); + auto self_type_id = context.types().GetTypeIdForTypeConstantId(type_const_id); auto witness_id = LookupImplWitness(context, loc_id, type_const_id, assoc_type.interface_type_id.AsConstantId()); if (!witness_id.has_value()) { - auto interface_type_id = context.GetInterfaceType( - interface_type->interface_id, interface_type->specific_id); + auto interface_type_id = GetInterfaceType( + context, interface_type->interface_id, interface_type->specific_id); if (missing_impl_diagnoser) { // TODO: Pass in the expression whose type we are printing. CARBON_DIAGNOSTIC(MissingImplInMemberAccessNote, Note, @@ -286,7 +287,7 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, if (lookup_in_type_of_base) { SemIR::TypeId base_type_id = context.insts().Get(base_id).type_id(); if (base_type_id != SemIR::TypeType::SingletonTypeId && - context.IsFacetType(base_type_id)) { + context.types().IsFacetType(base_type_id)) { // Handles `T.F` when `T` is a non-type facet. auto base_as_type = ExprAsType(context, loc_id, base_id); @@ -308,8 +309,8 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, // Get the witness that `T` implements `base_type_id`. if (base_interface == *assoc_interface) { witness_inst_id = context.GetOrAddInst( - loc_id, {.type_id = context.GetSingletonType( - SemIR::WitnessType::SingletonInstId), + loc_id, {.type_id = GetSingletonType( + context, SemIR::WitnessType::SingletonInstId), .facet_value_inst_id = base_id}); // TODO: Result will eventually be a facet type witness instead of // an interface witness. Will need to use the index @@ -366,8 +367,8 @@ static auto PerformInstanceBinding(Context& context, SemIR::LocId loc_id, } return context.GetOrAddInst( - loc_id, {.type_id = context.GetSingletonType( - SemIR::BoundMethodType::SingletonInstId), + loc_id, {.type_id = GetSingletonType( + context, SemIR::BoundMethodType::SingletonInstId), .object_id = base_id, .function_decl_id = member_id}); } @@ -508,7 +509,7 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, // TODO: According to the design, this should be a "lookup in base" lookup, // not a "lookup in type of base" lookup, and the facet itself should have // member names that directly name members of the `impl`. - if (context.IsFacetType(base_type_id)) { + if (context.types().IsFacetType(base_type_id)) { return member_id; } @@ -591,7 +592,7 @@ auto PerformTupleAccess(Context& context, SemIR::LocId loc_id, auto index_node_id = context.insts().GetLocId(index_inst_id); index_inst_id = ConvertToValueOfType( context, index_node_id, index_inst_id, - context.GetSingletonType(SemIR::IntLiteralType::SingletonInstId)); + GetSingletonType(context, SemIR::IntLiteralType::SingletonInstId)); auto index_const_id = context.constant_values().Get(index_inst_id); if (index_const_id == SemIR::ErrorInst::SingletonConstantId) { return SemIR::ErrorInst::SingletonInstId; diff --git a/toolchain/check/name_lookup.cpp b/toolchain/check/name_lookup.cpp index deeac77226de..d06b50784b41 100644 --- a/toolchain/check/name_lookup.cpp +++ b/toolchain/check/name_lookup.cpp @@ -240,7 +240,8 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id, } if (auto base_as_class = base.TryAs()) { RequireDefinedType( - context, context.GetTypeIdForTypeConstant(base_const_id), loc_id, [&] { + context, context.types().GetTypeIdForTypeConstantId(base_const_id), + loc_id, [&] { CARBON_DIAGNOSTIC(QualifiedExprInIncompleteClassScope, Error, "member access into incomplete class {0}", InstIdAsType); @@ -254,7 +255,8 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id, } if (auto base_as_facet_type = base.TryAs()) { RequireDefinedType( - context, context.GetTypeIdForTypeConstant(base_const_id), loc_id, [&] { + context, context.types().GetTypeIdForTypeConstantId(base_const_id), + loc_id, [&] { CARBON_DIAGNOSTIC(QualifiedExprInUndefinedInterfaceScope, Error, "member access into undefined interface {0}", InstIdAsType); diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index 318c5c757ca7..119d70cb7c18 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -13,6 +13,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/check/subpattern.h" +#include "toolchain/check/type.h" namespace Carbon::Check { @@ -252,7 +253,7 @@ auto MatchContext::EmitPatternMatch(Context& context, auto scrutinee_ref = context.insts().Get(scrutinee_ref_id); auto new_scrutinee = context.AddInst( context.insts().GetLocId(scrutinee_ref_id), - {.type_id = context.GetPointerType(scrutinee_ref.type_id()), + {.type_id = GetPointerType(context, scrutinee_ref.type_id()), .lvalue_id = scrutinee_ref_id}); AddWork( {.pattern_id = addr_pattern.inner_id, .scrutinee_id = new_scrutinee}); diff --git a/toolchain/check/subst.cpp b/toolchain/check/subst.cpp index 00fe65a3ac12..dc1ab8920f86 100644 --- a/toolchain/check/subst.cpp +++ b/toolchain/check/subst.cpp @@ -172,7 +172,7 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind, if (!type_id.has_value()) { return arg; } - return context.GetTypeIdForTypeInst(worklist.Pop()).index; + return context.types().GetTypeIdForTypeInstId(worklist.Pop()).index; } case SemIR::IdKind::For: { return pop_block_id(SemIR::InstBlockId(arg)).index; @@ -183,9 +183,9 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind, SemIR::CopyOnWriteStructTypeFieldsBlock new_fields(context.sem_ir(), old_fields_id); for (auto i : llvm::reverse(llvm::seq(old_fields.size()))) { - new_fields.Set( - i, {.name_id = old_fields[i].name_id, - .type_id = context.GetTypeIdForTypeInst(worklist.Pop())}); + new_fields.Set(i, {.name_id = old_fields[i].name_id, + .type_id = context.types().GetTypeIdForTypeInstId( + worklist.Pop())}); } return new_fields.GetCanonical().index; } @@ -195,7 +195,8 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind, SemIR::CopyOnWriteTypeBlock new_type_block(context.sem_ir(), old_type_block_id); for (auto i : llvm::reverse(llvm::seq(size))) { - new_type_block.Set(i, context.GetTypeIdForTypeInst(worklist.Pop())); + new_type_block.Set( + i, context.types().GetTypeIdForTypeInstId(worklist.Pop())); } return new_type_block.GetCanonical().index; } diff --git a/toolchain/check/type.cpp b/toolchain/check/type.cpp new file mode 100644 index 000000000000..83beb66706ca --- /dev/null +++ b/toolchain/check/type.cpp @@ -0,0 +1,116 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/check/type.h" + +#include "toolchain/check/eval.h" +#include "toolchain/check/type_completion.h" + +namespace Carbon::Check { + +// Gets or forms a type_id for a type, given the instruction kind and arguments. +template +static auto GetTypeImpl(Context& context, EachArgT... each_arg) + -> SemIR::TypeId { + // TODO: Remove inst_id parameter from TryEvalInst. + InstT inst = {SemIR::TypeType::SingletonTypeId, each_arg...}; + return context.types().GetTypeIdForTypeConstantId( + TryEvalInst(context, SemIR::InstId::None, inst)); +} + +auto FacetTypeFromInterface(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId specific_id) -> SemIR::FacetType { + SemIR::FacetTypeId facet_type_id = context.facet_types().Add( + SemIR::FacetTypeInfo{.impls_constraints = {{interface_id, specific_id}}, + .other_requirements = false}); + 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, +// and completes the type. This should only be used when type completion cannot +// fail. +template +static auto GetCompleteTypeImpl(Context& context, EachArgT... each_arg) + -> SemIR::TypeId { + auto type_id = GetTypeImpl(context, each_arg...); + CompleteTypeOrCheckFail(context, type_id); + return type_id; +} + +auto GetStructType(Context& context, SemIR::StructTypeFieldsId fields_id) + -> SemIR::TypeId { + return GetTypeImpl(context, fields_id); +} + +auto GetTupleType(Context& context, llvm::ArrayRef type_ids) + -> SemIR::TypeId { + return GetTypeImpl( + context, context.type_blocks().AddCanonical(type_ids)); +} + +auto GetAssociatedEntityType(Context& context, SemIR::TypeId interface_type_id) + -> SemIR::TypeId { + return GetTypeImpl(context, interface_type_id); +} + +auto GetSingletonType(Context& context, SemIR::InstId singleton_id) + -> SemIR::TypeId { + CARBON_CHECK(SemIR::IsSingletonInstId(singleton_id)); + auto type_id = context.types().GetTypeIdForTypeInstId(singleton_id); + // To keep client code simpler, complete builtin types before returning them. + CompleteTypeOrCheckFail(context, type_id); + return type_id; +} + +auto GetClassType(Context& context, SemIR::ClassId class_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId { + return GetTypeImpl(context, class_id, specific_id); +} + +auto GetFunctionType(Context& context, SemIR::FunctionId fn_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId { + return GetCompleteTypeImpl(context, fn_id, specific_id); +} + +auto GetFunctionTypeWithSelfType(Context& context, + SemIR::InstId interface_function_type_id, + SemIR::InstId self_id) -> SemIR::TypeId { + return GetCompleteTypeImpl( + context, interface_function_type_id, self_id); +} + +auto GetGenericClassType(Context& context, SemIR::ClassId class_id, + SemIR::SpecificId enclosing_specific_id) + -> SemIR::TypeId { + return GetCompleteTypeImpl(context, class_id, + enclosing_specific_id); +} + +auto GetGenericInterfaceType(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId enclosing_specific_id) + -> SemIR::TypeId { + return GetCompleteTypeImpl( + context, interface_id, enclosing_specific_id); +} + +auto GetInterfaceType(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId { + return GetTypeImpl( + context, + FacetTypeFromInterface(context, interface_id, specific_id).facet_type_id); +} + +auto GetPointerType(Context& context, SemIR::TypeId pointee_type_id) + -> SemIR::TypeId { + return GetTypeImpl(context, pointee_type_id); +} + +auto GetUnboundElementType(Context& context, SemIR::TypeId class_type_id, + SemIR::TypeId element_type_id) -> SemIR::TypeId { + return GetTypeImpl(context, class_type_id, + element_type_id); +} + +} // namespace Carbon::Check diff --git a/toolchain/check/type.h b/toolchain/check/type.h new file mode 100644 index 000000000000..260dc853228e --- /dev/null +++ b/toolchain/check/type.h @@ -0,0 +1,83 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_CHECK_TYPE_H_ +#define CARBON_TOOLCHAIN_CHECK_TYPE_H_ + +#include "llvm/ADT/ArrayRef.h" +#include "toolchain/check/context.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::Check { + +// Create a FacetType typed instruction object consisting of a single +// interface. +auto FacetTypeFromInterface(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId specific_id) -> SemIR::FacetType; + +// Gets the type to use for an unbound associated entity declared in this +// interface. For example, this is the type of `I.T` after +// `interface I { let T:! type; }`. The name of the interface is used for +// diagnostics. +// TODO: Should we use a different type for each such entity, or the same type +// for all associated entities? +auto GetAssociatedEntityType(Context& context, SemIR::TypeId interface_type_id) + -> SemIR::TypeId; + +// Gets a singleton type. The returned type will be complete. Requires that +// `singleton_id` is already validated to be a singleton. +auto GetSingletonType(Context& context, SemIR::InstId singleton_id) + -> SemIR::TypeId; + +// Gets a class type. +auto GetClassType(Context& context, SemIR::ClassId class_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId; + +// Gets a function type. The returned type will be complete. +auto GetFunctionType(Context& context, SemIR::FunctionId fn_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId; + +// Gets the type of an associated function with the `Self` parameter bound to +// a particular value. The returned type will be complete. +auto GetFunctionTypeWithSelfType(Context& context, + SemIR::InstId interface_function_type_id, + SemIR::InstId self_id) -> SemIR::TypeId; + +// Gets a generic class type, which is the type of a name of a generic class, +// such as the type of `Vector` given `class Vector(T:! type)`. The returned +// type will be complete. +auto GetGenericClassType(Context& context, SemIR::ClassId class_id, + SemIR::SpecificId enclosing_specific_id) + -> SemIR::TypeId; + +// Gets a generic interface type, which is the type of a name of a generic +// interface, such as the type of `AddWith` given +// `interface AddWith(T:! type)`. The returned type will be complete. +auto GetGenericInterfaceType(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId enclosing_specific_id) + -> SemIR::TypeId; + +// Gets the facet type corresponding to a particular interface. +auto GetInterfaceType(Context& context, SemIR::InterfaceId interface_id, + SemIR::SpecificId specific_id) -> SemIR::TypeId; + +// Returns a pointer type whose pointee type is `pointee_type_id`. +auto GetPointerType(Context& context, SemIR::TypeId pointee_type_id) + -> SemIR::TypeId; + +// Returns a struct type with the given fields. +auto GetStructType(Context& context, SemIR::StructTypeFieldsId fields_id) + -> SemIR::TypeId; + +// Returns a tuple type with the given element types. +auto GetTupleType(Context& context, llvm::ArrayRef type_ids) + -> SemIR::TypeId; + +// Returns an unbound element type. +auto GetUnboundElementType(Context& context, SemIR::TypeId class_type_id, + SemIR::TypeId element_type_id) -> SemIR::TypeId; + +} // namespace Carbon::Check + +#endif // CARBON_TOOLCHAIN_CHECK_TYPE_H_ diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 4fa467e1f709..95b6ecc386c9 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -7,6 +7,7 @@ #include "llvm/ADT/SmallVector.h" #include "toolchain/base/kind_switch.h" #include "toolchain/check/generic.h" +#include "toolchain/check/type.h" namespace Carbon::Check { @@ -290,7 +291,8 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { } auto TypeCompleter::MakeEmptyValueRepr() const -> SemIR::ValueRepr { - return {.kind = SemIR::ValueRepr::None, .type_id = context_.GetTupleType({})}; + return {.kind = SemIR::ValueRepr::None, + .type_id = GetTupleType(context_, {})}; } auto TypeCompleter::MakeCopyValueRepr( @@ -307,7 +309,7 @@ auto TypeCompleter::MakePointerValueRepr( // TODO: Should we add `const` qualification to `pointee_id`? return {.kind = SemIR::ValueRepr::Pointer, .aggregate_kind = aggregate_kind, - .type_id = context_.GetPointerType(pointee_id)}; + .type_id = GetPointerType(context_, pointee_id)}; } auto TypeCompleter::GetNestedValueRepr(SemIR::TypeId nested_type_id) const @@ -375,8 +377,8 @@ auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, auto value_rep = same_as_object_rep ? type_id - : context_.GetStructType( - context_.struct_type_fields().AddCanonical(value_rep_fields)); + : GetStructType(context_, context_.struct_type_fields().AddCanonical( + value_rep_fields)); return BuildStructOrTupleValueRepr(fields.size(), value_rep, same_as_object_rep); } @@ -405,7 +407,7 @@ auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, } auto value_rep = - same_as_object_rep ? type_id : context_.GetTupleType(value_rep_elements); + same_as_object_rep ? type_id : GetTupleType(context_, value_rep_elements); return BuildStructOrTupleValueRepr(elements.size(), value_rep, same_as_object_rep); } @@ -488,10 +490,10 @@ auto RequireCompleteType(Context& context, SemIR::TypeId type_id, if (type_id.AsConstantId().is_symbolic()) { // TODO: Deduplicate these. context.AddInstInNoBlock(SemIR::LocIdAndInst( - loc_id, - SemIR::RequireCompleteType{.type_id = context.GetSingletonType( - SemIR::WitnessType::SingletonInstId), - .complete_type_id = type_id})); + loc_id, SemIR::RequireCompleteType{ + .type_id = GetSingletonType( + context, SemIR::WitnessType::SingletonInstId), + .complete_type_id = type_id})); } return true; diff --git a/toolchain/docs/adding_features.md b/toolchain/docs/adding_features.md index bfd0c49b56c3..099841c98558 100644 --- a/toolchain/docs/adding_features.md +++ b/toolchain/docs/adding_features.md @@ -298,11 +298,11 @@ If the resulting SemIR needs a new instruction: constructed as a special-case in [`File` construction](/toolchain/sem_ir/file.cpp). To get a type id for one of these builtin types, use something like - `context.GetSingletonType(SemIR::WitnessType::SingletonInstId)`, as in: + `GetSingletonType(context,SemIR::WitnessType::SingletonInstId)`, as in: ``` SemIR::TypeId witness_type_id = - context.GetSingletonType(SemIR::WitnessType::SingletonInstId); + GetSingletonType(context,SemIR::WitnessType::SingletonInstId); SemIR::InstId inst_id = context.AddInst( node_id, {.type_id = witness_type_id, ...}); ``` diff --git a/toolchain/sem_ir/type.cpp b/toolchain/sem_ir/type.cpp index f1f5acd5e52d..58eebfabfdf4 100644 --- a/toolchain/sem_ir/type.cpp +++ b/toolchain/sem_ir/type.cpp @@ -8,6 +8,26 @@ namespace Carbon::SemIR { +auto TypeStore::GetTypeIdForTypeConstantId(SemIR::ConstantId constant_id) const + -> SemIR::TypeId { + CARBON_CHECK(constant_id.is_constant(), + "Canonicalizing non-constant type: {0}", constant_id); + auto type_id = file_->insts() + .Get(file_->constant_values().GetInstId(constant_id)) + .type_id(); + CARBON_CHECK(type_id == SemIR::TypeType::SingletonTypeId || + constant_id == SemIR::ErrorInst::SingletonConstantId, + "Forming type ID for non-type constant of type {0}", + GetAsInst(type_id)); + + return SemIR::TypeId::ForTypeConstant(constant_id); +} + +auto TypeStore::GetTypeIdForTypeInstId(SemIR::InstId inst_id) const + -> SemIR::TypeId { + return GetTypeIdForTypeConstantId(file_->constant_values().Get(inst_id)); +} + auto TypeStore::GetInstId(TypeId type_id) const -> InstId { return file_->constant_values().GetInstId(GetConstantId(type_id)); } diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index cd37ee0e58e4..dc2669ae73a9 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -33,6 +33,25 @@ class TypeStore : public Yaml::Printable { return type_id.AsConstantId(); } + // Returns the type ID for a constant that is a type value, i.e. it is a value + // of type `TypeType`. + // + // Facet values are of the same typishness as types, but are not themselves + // types, so they can not be passed here. They should be converted to a type + // through an `as type` conversion, that is, to a value of type `TypeType`. + auto GetTypeIdForTypeConstantId(SemIR::ConstantId constant_id) const + -> SemIR::TypeId; + + // Returns the type ID for an instruction whose constant value is a type + // value, i.e. it is a value of type `TypeType`. + // + // Instructions whose values are facet values (see `FacetValue`) produce a + // value of the same typishness as types, but which are themselves not types, + // so they can not be passed here. They should be converted to a type through + // an `as type` conversion, such as to a `FacetAccessType` instruction whose + // value is of type `TypeType`. + auto GetTypeIdForTypeInstId(SemIR::InstId inst_id) const -> SemIR::TypeId; + // Returns the ID of the instruction used to define the specified type. auto GetInstId(TypeId type_id) const -> InstId; @@ -113,6 +132,12 @@ class TypeStore : public Yaml::Printable { // non-constant width and for IntLiteral. auto GetIntTypeInfo(TypeId int_type_id) const -> IntTypeInfo; + // Returns whether `type_id` represents a facet type. + auto IsFacetType(SemIR::TypeId type_id) const -> bool { + return type_id == SemIR::TypeType::SingletonTypeId || + Is(type_id); + } + // Returns a list of types that were completed in this file, in the order in // which they were completed. Earlier types in this list cannot contain // instances of later types.