diff --git a/toolchain/check/action.cpp b/toolchain/check/action.cpp index 94a62b4b2791..c588f5f2c2aa 100644 --- a/toolchain/check/action.cpp +++ b/toolchain/check/action.cpp @@ -96,11 +96,11 @@ auto ActionIsDependent(Context& context, SemIR::Inst action_inst) -> bool { static auto AddDependentActionSpliceImpl(Context& context, SemIR::LocIdAndInst action, - SemIR::InstId result_type_inst_id) + SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId { auto inst_id = AddDependentActionInst(context, action); if (!result_type_inst_id.has_value()) { - result_type_inst_id = AddDependentActionInst( + result_type_inst_id = AddDependentActionTypeInst( context, action.loc_id, SemIR::TypeOfInst{.type_id = SemIR::TypeType::SingletonTypeId, .inst_id = inst_id}); @@ -160,7 +160,7 @@ static auto RefineOperands(Context& context, SemIR::LocId loc_id, } auto AddDependentActionSplice(Context& context, SemIR::LocIdAndInst action, - SemIR::InstId result_type_inst_id) + SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId { action.inst = RefineOperands(context, action.loc_id, action.inst); return AddDependentActionSpliceImpl(context, action, result_type_inst_id); diff --git a/toolchain/check/action.h b/toolchain/check/action.h index c26011189153..959670c3100f 100644 --- a/toolchain/check/action.h +++ b/toolchain/check/action.h @@ -47,13 +47,13 @@ auto OperandIsDependent(Context& context, SemIR::TypeId type_id) -> bool; // Adds an instruction to the current block to splice in the result of // performing a dependent action. auto AddDependentActionSplice(Context& context, SemIR::LocIdAndInst action, - SemIR::InstId result_type_inst_id) + SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId; // Convenience wrapper for `AddDependentActionSplice`. template auto AddDependentActionSplice(Context& context, LocT loc, InstT inst, - SemIR::InstId result_type_inst_id) + SemIR::TypeInstId result_type_inst_id) -> SemIR::InstId { return AddDependentActionSplice(context, SemIR::LocIdAndInst(loc, inst), result_type_inst_id); @@ -64,8 +64,8 @@ auto AddDependentActionSplice(Context& context, LocT loc, InstT inst, // block and creates an instruction to splice in the result of the action. template auto HandleAction(Context& context, SemIR::LocId loc_id, ActionT action_inst, - SemIR::InstId result_type_inst_id = SemIR::InstId::None) - -> SemIR::InstId { + SemIR::TypeInstId result_type_inst_id = + SemIR::TypeInstId::None) -> SemIR::InstId { if (ActionIsDependent(context, action_inst) || (result_type_inst_id.has_value() && OperandIsDependent(context, result_type_inst_id))) { diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index d0204baecb06..96a6a2f9d3ff 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1388,11 +1388,11 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc, CARBON_CHECK(arg_ids.size() == 2); auto lhs_facet_type_id = SemIR::FacetTypeId::None; auto rhs_facet_type_id = SemIR::FacetTypeId::None; - for (auto [facet_type_id, arg_id] : + for (auto [facet_type_id, type_arg_id] : llvm::zip(std::to_array({&lhs_facet_type_id, &rhs_facet_type_id}), - arg_ids)) { + context.types().GetBlockAsTypeInstIds(arg_ids))) { if (auto facet_type = - context.insts().TryGetAs(arg_id)) { + context.insts().TryGetAs(type_arg_id)) { *facet_type_id = facet_type->facet_type_id; } else { CARBON_DIAGNOSTIC(FacetTypeRequiredForTypeAndOperator, Error, @@ -1404,7 +1404,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc, // The `arg_id` instruction has no location in it for some reason. context.emitter().Emit( loc, FacetTypeRequiredForTypeAndOperator, - context.types().GetTypeIdForTypeInstId(arg_id)); + context.types().GetTypeIdForTypeInstId(type_arg_id)); } } // Allow errors to be diagnosed for both sides of the operator before diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index eabb8de18a4a..0a5680ce756a 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -525,8 +525,8 @@ class ImportRefResolver : public ImportContext { import_ir().types().GetConstantId(import_type_id); CARBON_CHECK(import_type_const_id.has_value()); - if (auto import_type_inst_id = - import_ir().constant_values().GetInstId(import_type_const_id); + if (auto import_type_inst_id = import_ir().types().GetAsTypeInstId( + 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 GetSingletonType(local_context(), import_type_inst_id); @@ -1911,7 +1911,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::ConstType inst) -> ResolveResult { CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); - auto inner_id = GetLocalConstantInstId(resolver, inst.inner_id); + auto inner_id = GetLocalTypeInstId(resolver, inst.inner_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); } @@ -2079,7 +2079,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, -> ResolveResult { CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); auto interface_function_type_id = - GetLocalConstantInstId(resolver, inst.interface_function_type_id); + GetLocalTypeInstId(resolver, inst.interface_function_type_id); auto self_id = GetLocalConstantInstId(resolver, inst.self_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); @@ -2690,7 +2690,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::PointerType inst) -> ResolveResult { CARBON_CHECK(inst.type_id == SemIR::TypeType::SingletonTypeId); - auto pointee_id = GetLocalConstantInstId(resolver, inst.pointee_id); + auto pointee_id = GetLocalTypeInstId(resolver, inst.pointee_id); if (resolver.HasNewWork()) { return ResolveResult::Retry(); } diff --git a/toolchain/check/inst.h b/toolchain/check/inst.h index 7b57c260c328..bc36fe28ad6d 100644 --- a/toolchain/check/inst.h +++ b/toolchain/check/inst.h @@ -100,11 +100,19 @@ auto AddDependentActionInst(Context& context, // Convenience wrapper for AddDependentActionInst. template auto AddDependentActionInst(Context& context, LocT loc, InstT inst) - -> decltype(AddDependentActionInst(context, - SemIR::LocIdAndInst(loc, inst))) { + -> SemIR::InstId { return AddDependentActionInst(context, SemIR::LocIdAndInst(loc, inst)); } +// Like AddDependentActionInst, but for instructions with a type_id of +// `TypeType`, which is encoded in the return type of `TypeInstId`. +template +auto AddDependentActionTypeInst(Context& context, LocT loc, InstT inst) + -> SemIR::TypeInstId { + return context.types().GetAsTypeInstId( + AddDependentActionInst(context, loc, inst)); +} + // Adds an instruction to the current pattern block, returning the produced // ID. // TODO: Is it possible to remove this and pattern_block_stack, now that diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 9a6f5faf0cb2..bfdd86fec688 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -100,6 +100,18 @@ class NodeStack { stack_.push_back({.node_id = node_id, .id = Id(id)}); } + // TODO: Most parse nodes don't know about TypeInstId, so downgrade TypeInstId + // to InstId to match expectations. We should teach parse nodes that will + // receive a TypeInstId to expect it, and this function can go away. + auto Push(Parse::NodeId node_id, SemIR::TypeInstId id) -> void { + auto kind = parse_tree_->node_kind(node_id); + if (NodeKindToIdKind(kind) == Id::KindFor()) { + Push(node_id, id); + } else { + Push(node_id, id); + } + } + // Returns whether there is a node of the specified kind on top of the stack. auto PeekIs(Parse::NodeKind kind) const -> bool { return !stack_.empty() && PeekNodeKind() == kind; diff --git a/toolchain/check/subst.cpp b/toolchain/check/subst.cpp index 8fa3499f0f64..1078a721eb85 100644 --- a/toolchain/check/subst.cpp +++ b/toolchain/check/subst.cpp @@ -339,6 +339,12 @@ auto SubstInst(Context& context, SemIR::InstId inst_id, return worklist.back().inst_id; } +auto SubstInst(Context& context, SemIR::TypeInstId inst_id, + const SubstInstCallbacks& callbacks) -> SemIR::TypeInstId { + return context.types().GetAsTypeInstId( + SubstInst(context, static_cast(inst_id), callbacks)); +} + namespace { // Callbacks for performing substitution of a set of Substitutions into a // symbolic constant. diff --git a/toolchain/check/subst.h b/toolchain/check/subst.h index f4706dd68a0c..351411ef4793 100644 --- a/toolchain/check/subst.h +++ b/toolchain/check/subst.h @@ -46,6 +46,8 @@ class SubstInstCallbacks { // is used to build a new instruction with the substituted operands. auto SubstInst(Context& context, SemIR::InstId inst_id, const SubstInstCallbacks& callbacks) -> SemIR::InstId; +auto SubstInst(Context& context, SemIR::TypeInstId inst_id, + const SubstInstCallbacks& callbacks) -> SemIR::TypeInstId; // A substitution that is being performed. struct Substitution { diff --git a/toolchain/check/type.cpp b/toolchain/check/type.cpp index 54742171e35b..343d30f92bab 100644 --- a/toolchain/check/type.cpp +++ b/toolchain/check/type.cpp @@ -105,7 +105,7 @@ auto GetAssociatedEntityType(Context& context, SemIR::InterfaceId interface_id, interface_specific_id); } -auto GetSingletonType(Context& context, SemIR::InstId singleton_id) +auto GetSingletonType(Context& context, SemIR::TypeInstId singleton_id) -> SemIR::TypeId { CARBON_CHECK(SemIR::IsSingletonInstId(singleton_id)); auto type_id = context.types().GetTypeIdForTypeInstId(singleton_id); @@ -125,7 +125,7 @@ auto GetFunctionType(Context& context, SemIR::FunctionId fn_id, } auto GetFunctionTypeWithSelfType(Context& context, - SemIR::InstId interface_function_type_id, + SemIR::TypeInstId interface_function_type_id, SemIR::InstId self_id) -> SemIR::TypeId { return GetCompleteTypeImpl( context, interface_function_type_id, self_id); @@ -152,7 +152,7 @@ auto GetInterfaceType(Context& context, SemIR::InterfaceId interface_id, FacetTypeFromInterface(context, interface_id, specific_id).facet_type_id); } -auto GetPointerType(Context& context, SemIR::InstId pointee_type_id) +auto GetPointerType(Context& context, SemIR::TypeInstId pointee_type_id) -> SemIR::TypeId { return GetTypeImpl(context, pointee_type_id); } diff --git a/toolchain/check/type.h b/toolchain/check/type.h index 11b21a622465..b72e7d5de0c0 100644 --- a/toolchain/check/type.h +++ b/toolchain/check/type.h @@ -35,7 +35,7 @@ auto GetAssociatedEntityType(Context& context, SemIR::InterfaceId interface_id, // 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) +auto GetSingletonType(Context& context, SemIR::TypeInstId singleton_id) -> SemIR::TypeId; // Gets a class type. @@ -49,7 +49,7 @@ auto GetFunctionType(Context& context, SemIR::FunctionId fn_id, // 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::TypeInstId 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, @@ -71,7 +71,7 @@ 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::InstId pointee_type_id) +auto GetPointerType(Context& context, SemIR::TypeInstId pointee_type_id) -> SemIR::TypeId; // Returns a struct type with the given fields. diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 0ad2660be54c..787ef6d3042e 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -257,9 +257,9 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { break; } case CARBON_KIND(SemIR::TupleType inst): { - for (auto element_type_id : - context_->inst_blocks().Get(inst.type_elements_id)) { - Push(context_->types().GetTypeIdForTypeInstId(element_type_id)); + for (auto element_type_id : context_->types().GetBlockAsTypeIds( + context_->inst_blocks().Get(inst.type_elements_id))) { + Push(element_type_id); } break; } diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index 0590e6fead33..f656ac3fc9c1 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -55,7 +55,7 @@ struct TypeParam { // Constraint that a type is a specific builtin. See ValidateSignature for // details. -template +template struct BuiltinType { static auto Check(const File& sem_ir, ValidateState& /*state*/, TypeId type_id) -> bool { diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 99007207a105..267ef92b7eaf 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -127,7 +127,8 @@ struct CalleeFunction { SemIR::SpecificId enclosing_specific_id; // The specific for the callee itself, in a resolved call. SemIR::SpecificId resolved_specific_id; - // The bound `Self` type. `None` if not a bound interface member. + // The bound `Self` type or facet value. `None` if not a bound interface + // member. SemIR::InstId self_type_id; // The bound `self` parameter. `None` if not a method. SemIR::InstId self_id; diff --git a/toolchain/sem_ir/singleton_insts.h b/toolchain/sem_ir/singleton_insts.h index 53650673170b..fec05850ac04 100644 --- a/toolchain/sem_ir/singleton_insts.h +++ b/toolchain/sem_ir/singleton_insts.h @@ -36,7 +36,7 @@ constexpr auto IsSingletonInstKind(InstKind kind) -> bool; // `InstT::SingletonInstId` in `typed_insts.h`. template requires(IsSingletonInstKind(InstKind::Make(Kind))) -constexpr auto MakeSingletonInstId() -> InstId; +constexpr auto MakeSingletonInstId() -> TypeInstId; // Returns true if the InstId corresponds to a singleton inst. constexpr auto IsSingletonInstId(InstId id) -> bool { @@ -67,9 +67,9 @@ constexpr auto IsSingletonInstKind(InstKind kind) -> bool { template requires(IsSingletonInstKind(InstKind::Make(Kind))) -constexpr auto MakeSingletonInstId() -> InstId { +constexpr auto MakeSingletonInstId() -> TypeInstId { auto index = Internal::GetSingletonInstIndex(InstKind::Make(Kind)); - return InstId(index); + return TypeInstId(index); } } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 7cc69cf710dc..e3d77e607ac8 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -612,7 +612,7 @@ struct ConstType { .deduce_through = true}); TypeId type_id; - InstId inner_id; + TypeInstId inner_id; }; // An action that performs simple conversion to a value expression of a given @@ -660,7 +660,7 @@ struct ErrorInst { {.ir_name = "", .is_type = InstIsType::Always, .constant_kind = InstConstantKind::Always}); - static constexpr auto SingletonInstId = MakeSingletonInstId(); + static constexpr InstId SingletonInstId = MakeSingletonInstId(); static constexpr auto SingletonConstantId = ConstantId::ForConcreteConstant(SingletonInstId); static constexpr auto SingletonTypeId = @@ -841,8 +841,9 @@ struct FunctionTypeWithSelfType { // The type of the function within the interface. This includes the // interface's SpecificId if applicable. This will be a `FunctionType` except // in error cases. - InstId interface_function_type_id; - // The value to use for `Self` in this function. + TypeInstId interface_function_type_id; + // The value to use for `Self` in this function. May be a type or a facet + // value. InstId self_id; }; @@ -1350,7 +1351,7 @@ struct PointerType { .deduce_through = true}); TypeId type_id; - InstId pointee_id; + TypeInstId pointee_id; }; // An action that performs type refinement for an instruction, by creating an