diff --git a/toolchain/check/call.cpp b/toolchain/check/call.cpp index ca00a1211d75..577e2988b3e0 100644 --- a/toolchain/check/call.cpp +++ b/toolchain/check/call.cpp @@ -27,7 +27,7 @@ static auto PerformCallToGenericClass(Context& context, Parse::NodeId node_id, // TODO: Pass in information about the specific in which the generic class // name was found. // TODO: Perform argument deduction. - auto specific_id = SemIR::GenericInstanceId::Invalid; + auto specific_id = SemIR::SpecificId::Invalid; // Convert the arguments to match the parameters. auto converted_args_id = ConvertCallArgs( @@ -53,7 +53,7 @@ static auto PerformCallToGenericInterface(Context& context, // TODO: Pass in information about the specific in which the generic interface // name was found. // TODO: Perform argument deduction. - auto specific_id = SemIR::GenericInstanceId::Invalid; + auto specific_id = SemIR::SpecificId::Invalid; // Convert the arguments to match the parameters. auto converted_args_id = ConvertCallArgs( @@ -101,15 +101,15 @@ auto PerformCall(Context& context, Parse::NodeId node_id, // TODO: Properly determine the generic argument values for the call. For now, // we do so only if the function introduces no generic parameters beyond those // of the enclosing context. - auto specific_id = SemIR::GenericInstanceId::Invalid; - if (callee_function.instance_id.is_valid()) { + auto specific_id = SemIR::SpecificId::Invalid; + if (callee_function.specific_id.is_valid()) { auto enclosing_args_id = - context.generic_instances().Get(callee_function.instance_id).args_id; + context.specifics().Get(callee_function.specific_id).args_id; auto fn_params_id = context.generics().Get(callable.generic_id).bindings_id; if (context.inst_blocks().Get(fn_params_id).size() == context.inst_blocks().Get(enclosing_args_id).size()) { specific_id = - MakeGenericInstance(context, callable.generic_id, enclosing_args_id); + MakeSpecific(context, callable.generic_id, enclosing_args_id); } } diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index a88c7382821b..1d2f4dd049a7 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -206,8 +206,7 @@ static auto ImportCurrentPackage(Context& context, UnitInfo& unit_info, /*api_imports=*/nullptr, total_ir_count)); context.scope_stack().Push( - package_inst_id, SemIR::NameScopeId::Package, - SemIR::GenericInstanceId::Invalid, + package_inst_id, SemIR::NameScopeId::Package, SemIR::SpecificId::Invalid, context.name_scopes().Get(SemIR::NameScopeId::Package).has_error); } diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index abff033608e9..55f5a460a6d2 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -275,11 +275,11 @@ auto Context::LookupUnqualifiedName(Parse::NodeId node_id, scope_stack().LookupInLexicalScopes(name_id); // Walk the non-lexical scopes and perform lookups into each of them. - for (auto [index, lookup_scope_id, instance_id] : + for (auto [index, lookup_scope_id, specific_id] : llvm::reverse(non_lexical_scopes)) { if (auto non_lexical_result = LookupQualifiedName( node_id, name_id, - {.name_scope_id = lookup_scope_id, .instance_id = instance_id}, + {.name_scope_id = lookup_scope_id, .specific_id = specific_id}, /*required=*/false); non_lexical_result.inst_id.is_valid()) { return non_lexical_result; @@ -287,16 +287,16 @@ auto Context::LookupUnqualifiedName(Parse::NodeId node_id, } if (lexical_result.is_valid()) { - // A lexical scope never needs an associated generic instance. If there's a + // A lexical scope never needs an associated specific. If there's a // lexically enclosing generic, then it also encloses the point of use of // the name. - return {.instance_id = SemIR::GenericInstanceId::Invalid, + return {.specific_id = SemIR::SpecificId::Invalid, .inst_id = lexical_result}; } // We didn't find anything at all. DiagnoseNameNotFound(node_id, name_id); - return {.instance_id = SemIR::GenericInstanceId::Invalid, + return {.specific_id = SemIR::SpecificId::Invalid, .inst_id = SemIR::InstId::BuiltinError}; } @@ -320,13 +320,13 @@ auto Context::LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id, LookupScope scope, bool required) -> LookupResult { llvm::SmallVector scopes = {scope}; - LookupResult result = {.instance_id = SemIR::GenericInstanceId::Invalid, + LookupResult result = {.specific_id = SemIR::SpecificId::Invalid, .inst_id = SemIR::InstId::Invalid}; bool has_error = false; // Walk this scope and, if nothing is found here, the scopes it extends. while (!scopes.empty()) { - auto [scope_id, instance_id] = scopes.pop_back_val(); + auto [scope_id, specific_id] = scopes.pop_back_val(); const auto& name_scope = name_scopes().Get(scope_id); has_error |= name_scope.has_error; @@ -338,9 +338,9 @@ auto Context::LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id, scopes.reserve(scopes.size() + extended.size()); for (auto extended_id : llvm::reverse(extended)) { // TODO: Track a constant describing the extended scope, and substitute - // into it to determine its corresponding generic instance. + // into it to determine its corresponding specific. scopes.push_back({.name_scope_id = extended_id, - .instance_id = SemIR::GenericInstanceId::Invalid}); + .specific_id = SemIR::SpecificId::Invalid}); } continue; } @@ -356,19 +356,19 @@ auto Context::LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id, SemIR::NameId); emitter_->Emit(node_id, NameAmbiguousDueToExtend, name_id); // TODO: Add notes pointing to the scopes. - return {.instance_id = SemIR::GenericInstanceId::Invalid, + return {.specific_id = SemIR::SpecificId::Invalid, .inst_id = SemIR::InstId::BuiltinError}; } result.inst_id = scope_result_id; - result.instance_id = instance_id; + result.specific_id = specific_id; } if (required && !result.inst_id.is_valid()) { if (!has_error) { DiagnoseNameNotFound(node_id, name_id); } - return {.instance_id = SemIR::GenericInstanceId::Invalid, + return {.specific_id = SemIR::SpecificId::Invalid, .inst_id = SemIR::InstId::BuiltinError}; } @@ -715,8 +715,8 @@ class TypeCompleter { } return false; } - if (inst.instance_id.is_valid()) { - ResolveSpecificDefinition(context_, inst.instance_id); + if (inst.specific_id.is_valid()) { + ResolveSpecificDefinition(context_, inst.specific_id); } Push(class_info.object_repr_id); break; @@ -1012,8 +1012,8 @@ auto Context::TryToDefineType( return false; } - if (interface->instance_id.is_valid()) { - ResolveSpecificDefinition(*this, interface->instance_id); + if (interface->specific_id.is_valid()) { + ResolveSpecificDefinition(*this, interface->specific_id); } } @@ -1085,9 +1085,8 @@ auto Context::GetBuiltinType(SemIR::BuiltinInstKind kind) -> SemIR::TypeId { } auto Context::GetFunctionType(SemIR::FunctionId fn_id, - SemIR::GenericInstanceId instance_id) - -> SemIR::TypeId { - return GetCompleteTypeImpl(*this, fn_id, instance_id); + SemIR::SpecificId specific_id) -> SemIR::TypeId { + return GetCompleteTypeImpl(*this, fn_id, specific_id); } auto Context::GetGenericClassType(SemIR::ClassId class_id) -> SemIR::TypeId { diff --git a/toolchain/check/context.h b/toolchain/check/context.h index a60047176255..f6af95f3034f 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -30,16 +30,16 @@ namespace Carbon::Check { struct LookupScope { // The name scope in which names are searched. SemIR::NameScopeId name_scope_id; - // The generic instance for the name scope, or `Invalid` if the name scope is - // not an instance of a generic. - SemIR::GenericInstanceId instance_id; + // The specific for the name scope, or `Invalid` if the name scope is not + // defined by a generic or we should perform lookup into the generic itself. + SemIR::SpecificId specific_id; }; // A result produced by name lookup. struct LookupResult { - // The generic instance in which the lookup result was found. `Invalid` if the - // result was not found in a generic instance. - SemIR::GenericInstanceId instance_id; + // The specific in which the lookup result was found. `Invalid` if the result + // was not found in a specific. + SemIR::SpecificId specific_id; // The declaration that was found by name lookup. SemIR::InstId inst_id; }; @@ -288,8 +288,8 @@ class Context { auto GetBuiltinType(SemIR::BuiltinInstKind kind) -> SemIR::TypeId; // Gets a function type. The returned type will be complete. - auto GetFunctionType(SemIR::FunctionId fn_id, - SemIR::GenericInstanceId instance_id) -> SemIR::TypeId; + auto GetFunctionType(SemIR::FunctionId fn_id, SemIR::SpecificId specific_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 @@ -423,9 +423,7 @@ class Context { } auto impls() -> SemIR::ImplStore& { return sem_ir().impls(); } auto generics() -> SemIR::GenericStore& { return sem_ir().generics(); } - auto generic_instances() -> SemIR::GenericInstanceStore& { - return sem_ir().generic_instances(); - } + auto specifics() -> SemIR::SpecificStore& { return sem_ir().specifics(); } auto import_irs() -> ValueStore& { return sem_ir().import_irs(); } diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 24d378bd1603..850403adf555 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1119,7 +1119,7 @@ CARBON_DIAGNOSTIC(InCallToFunction, Note, "Calling function declared here."); // Convert the object argument in a method call to match the `self` parameter. static auto ConvertSelf(Context& context, SemIR::LocId call_loc_id, SemIR::InstId callee_id, - SemIR::GenericInstanceId callee_specific_id, + SemIR::SpecificId callee_specific_id, std::optional addr_pattern, SemIR::InstId self_param_id, SemIR::Param self_param, SemIR::InstId self_id) -> SemIR::InstId { @@ -1168,7 +1168,7 @@ static auto ConvertSelf(Context& context, SemIR::LocId call_loc_id, return ConvertToValueOfType( context, call_loc_id, self_or_addr_id, - SemIR::GetTypeInInstance(context.sem_ir(), callee_specific_id, + SemIR::GetTypeInSpecific(context.sem_ir(), callee_specific_id, self_param.type_id)); } @@ -1177,7 +1177,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, llvm::ArrayRef arg_refs, SemIR::InstId return_storage_id, const SemIR::EntityWithParamsBase& callee, - SemIR::GenericInstanceId callee_specific_id) + SemIR::SpecificId callee_specific_id) -> SemIR::InstBlockId { auto implicit_param_refs = context.inst_blocks().GetOrEmpty(callee.implicit_param_refs_id); @@ -1238,7 +1238,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, diag_param_index = i; auto param_type_id = - SemIR::GetTypeInInstance(context.sem_ir(), callee_specific_id, + SemIR::GetTypeInSpecific(context.sem_ir(), callee_specific_id, context.insts().Get(param_id).type_id()); // TODO: Convert to the proper expression category. For now, we assume // parameters are all `let` bindings. diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index 99fc7370d064..65f8219b7249 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -97,7 +97,7 @@ auto ConvertCallArgs(Context& context, SemIR::LocId call_loc_id, llvm::ArrayRef arg_refs, SemIR::InstId return_storage_id, const SemIR::EntityWithParamsBase& callee, - SemIR::GenericInstanceId callee_specific_id) + SemIR::SpecificId callee_specific_id) -> SemIR::InstBlockId; // Converts an expression for use as a type. diff --git a/toolchain/check/decl_name_stack.cpp b/toolchain/check/decl_name_stack.cpp index 1612426b94e1..1b54e2054f01 100644 --- a/toolchain/check/decl_name_stack.cpp +++ b/toolchain/check/decl_name_stack.cpp @@ -200,18 +200,18 @@ auto DeclNameStack::LookupOrAddName(NameContext name_context, static auto PushNameQualifierScope(Context& context, SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, - SemIR::GenericInstanceId instance_id, + SemIR::SpecificId specific_id, bool has_error = false) -> void { // If the qualifier has no parameters, we don't need to keep around a // parameter scope. context.scope_stack().PopIfEmpty(); // When declaring a member of a generic, resolve the self specific. - if (instance_id.is_valid()) { - ResolveSpecificDefinition(context, instance_id); + if (specific_id.is_valid()) { + ResolveSpecificDefinition(context, specific_id); } - context.scope_stack().Push(scope_inst_id, scope_id, instance_id, has_error); + context.scope_stack().Push(scope_inst_id, scope_id, specific_id, has_error); // An interface also introduces its 'Self' parameter into scope, despite it // not being redeclared as part of the qualifier. @@ -232,10 +232,10 @@ auto DeclNameStack::ApplyNameQualifier(const NameComponent& name) -> void { name_context.has_qualifiers = true; // Resolve the qualifier as a scope and enter the new scope. - auto [scope_id, instance_id] = ResolveAsScope(name_context, name); + auto [scope_id, specific_id] = ResolveAsScope(name_context, name); if (scope_id.is_valid()) { PushNameQualifierScope(*context_, name_context.resolved_inst_id, scope_id, - instance_id, + specific_id, context_->name_scopes().Get(scope_id).has_error); name_context.parent_scope_id = scope_id; } else { @@ -366,10 +366,9 @@ static auto DiagnoseQualifiedDeclInNonScope(Context& context, SemIRLoc use_loc, auto DeclNameStack::ResolveAsScope(const NameContext& name_context, const NameComponent& name) const - -> std::pair { - constexpr std::pair - InvalidResult = {SemIR::NameScopeId::Invalid, - SemIR::GenericInstanceId::Invalid}; + -> std::pair { + constexpr std::pair InvalidResult = { + SemIR::NameScopeId::Invalid, SemIR::SpecificId::Invalid}; if (!CheckQualifierIsResolved(*context_, name_context)) { return InvalidResult; @@ -396,7 +395,7 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context, return InvalidResult; } return {class_info.scope_id, - context_->generics().GetSelfInstance(class_info.generic_id)}; + context_->generics().GetSelfSpecific(class_info.generic_id)}; } case CARBON_KIND(SemIR::InterfaceDecl interface_decl): { const auto& interface_info = @@ -412,7 +411,7 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context, return InvalidResult; } return {interface_info.scope_id, - context_->generics().GetSelfInstance(interface_info.generic_id)}; + context_->generics().GetSelfSpecific(interface_info.generic_id)}; } case CARBON_KIND(SemIR::Namespace resolved_inst): { auto scope_id = resolved_inst.name_scope_id; @@ -432,7 +431,7 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context, // be used as a name qualifier. scope.is_closed_import = false; } - return {scope_id, SemIR::GenericInstanceId::Invalid}; + return {scope_id, SemIR::SpecificId::Invalid}; } default: { DiagnoseQualifiedDeclInNonScope(*context_, name_context.loc_id, diff --git a/toolchain/check/decl_name_stack.h b/toolchain/check/decl_name_stack.h index dd201a4d92f0..f5e1152cb960 100644 --- a/toolchain/check/decl_name_stack.h +++ b/toolchain/check/decl_name_stack.h @@ -253,7 +253,7 @@ class DeclNameStack { // the name doesn't resolve to a scope. auto ResolveAsScope(const NameContext& name_context, const NameComponent& name) const - -> std::pair; + -> std::pair; // The linked context. Context* context_; diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 7db8c621d46b..2804212ec012 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -31,7 +31,7 @@ class EvalContext { public: explicit EvalContext( Context& context, - SemIR::GenericInstanceId specific_id = SemIR::GenericInstanceId::Invalid, + SemIR::SpecificId specific_id = SemIR::SpecificId::Invalid, std::optional specific_eval_info = std::nullopt) : context_(context), specific_id_(specific_id), @@ -45,7 +45,7 @@ class EvalContext { return SemIR::ConstantId::Invalid; } - const auto& specific = generic_instances().Get(specific_id_); + const auto& specific = specifics().Get(specific_id_); auto args = inst_blocks().Get(specific.args_id); // Bindings past the ones with known arguments can appear as local @@ -67,14 +67,14 @@ class EvalContext { // While resolving a specific, map from previous instructions in the eval // block into their evaluated values. These values won't be present on the - // instance itself yet, so `GetConstantInInstance` won't be able to find + // specific itself yet, so `GetConstantInSpecific` won't be able to find // them. if (specific_eval_info_) { const auto& symbolic_info = constant_values().GetSymbolicConstant(const_id); if (symbolic_info.index.is_valid() && symbolic_info.generic_id == - generic_instances().Get(specific_id_).generic_id && + specifics().Get(specific_id_).generic_id && symbolic_info.index.region() == specific_eval_info_->region) { auto inst_id = specific_eval_info_->values[symbolic_info.index.index()]; CARBON_CHECK(inst_id.is_valid()) @@ -85,7 +85,7 @@ class EvalContext { } // Map from a specific constant value to the canonical value. - return GetConstantInInstance(sem_ir(), specific_id_, const_id); + return GetConstantInSpecific(sem_ir(), specific_id_, const_id); } // Gets the constant value of the specified instruction in this context. @@ -124,8 +124,8 @@ class EvalContext { auto interfaces() -> const ValueStore& { return sem_ir().interfaces(); } - auto generic_instances() -> const SemIR::GenericInstanceStore& { - return sem_ir().generic_instances(); + auto specifics() -> const SemIR::SpecificStore& { + return sem_ir().specifics(); } auto type_blocks() -> SemIR::BlockValueStore& { return sem_ir().type_blocks(); @@ -157,7 +157,7 @@ class EvalContext { // The type-checking context in which we're performing evaluation. Context& context_; // The specific that we are evaluating within. - SemIR::GenericInstanceId specific_id_; + SemIR::SpecificId specific_id_; // If we are currently evaluating an eval block for `specific_id_`, // information about that evaluation. std::optional specific_eval_info_; @@ -320,26 +320,25 @@ static auto GetConstantValue(EvalContext& eval_context, return type_block_id; } -// The constant value of a generic instance is the generic instance with the -// corresponding constant values for its arguments. +// The constant value of a specific is the specific with the corresponding +// constant values for its arguments. static auto GetConstantValue(EvalContext& eval_context, - SemIR::GenericInstanceId instance_id, Phase* phase) - -> SemIR::GenericInstanceId { - if (!instance_id.is_valid()) { - return SemIR::GenericInstanceId::Invalid; + SemIR::SpecificId specific_id, Phase* phase) + -> SemIR::SpecificId { + if (!specific_id.is_valid()) { + return SemIR::SpecificId::Invalid; } - const auto& instance = eval_context.generic_instances().Get(instance_id); - auto args_id = GetConstantValue(eval_context, instance.args_id, phase); + const auto& specific = eval_context.specifics().Get(specific_id); + auto args_id = GetConstantValue(eval_context, specific.args_id, phase); if (!args_id.is_valid()) { - return SemIR::GenericInstanceId::Invalid; + return SemIR::SpecificId::Invalid; } - if (args_id == instance.args_id) { - return instance_id; + if (args_id == specific.args_id) { + return specific_id; } - return MakeGenericInstance(eval_context.context(), instance.generic_id, - args_id); + return MakeSpecific(eval_context.context(), specific.generic_id, args_id); } // Replaces the specified field of the given typed instruction with its constant @@ -1095,7 +1094,7 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc, eval_context.insts().Get(call.callee_id).type_id()); CARBON_KIND_SWITCH(type_inst) { case CARBON_KIND(SemIR::GenericClassType generic_class): { - auto instance_id = MakeGenericInstance( + auto specific_id = MakeSpecific( eval_context.context(), eval_context.classes().Get(generic_class.class_id).generic_id, call.args_id); @@ -1103,21 +1102,20 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc, eval_context.context(), SemIR::ClassType{.type_id = call.type_id, .class_id = generic_class.class_id, - .instance_id = instance_id}, + .specific_id = specific_id}, phase); } case CARBON_KIND(SemIR::GenericInterfaceType generic_interface): { - auto instance_id = - MakeGenericInstance(eval_context.context(), - eval_context.interfaces() - .Get(generic_interface.interface_id) - .generic_id, - call.args_id); + auto specific_id = MakeSpecific(eval_context.context(), + eval_context.interfaces() + .Get(generic_interface.interface_id) + .generic_id, + call.args_id); return MakeConstantResult( eval_context.context(), SemIR::InterfaceType{.type_id = call.type_id, .interface_id = generic_interface.interface_id, - .instance_id = instance_id}, + .specific_id = specific_id}, phase); } default: { @@ -1187,13 +1185,13 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id, &SemIR::BoundMethod::object_id, &SemIR::BoundMethod::function_id); case SemIR::ClassType::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::ClassType::instance_id); + &SemIR::ClassType::specific_id); case SemIR::FunctionType::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::FunctionType::instance_id); + &SemIR::FunctionType::specific_id); case SemIR::InterfaceType::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::InterfaceType::instance_id); + &SemIR::InterfaceType::specific_id); case SemIR::InterfaceWitness::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, &SemIR::InterfaceWitness::elements_id); @@ -1288,7 +1286,7 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id, eval_context.context(), SemIR::ClassType{.type_id = SemIR::TypeId::TypeType, .class_id = class_decl.class_id, - .instance_id = SemIR::GenericInstanceId::Invalid}, + .specific_id = SemIR::SpecificId::Invalid}, Phase::Template); } case CARBON_KIND(SemIR::InterfaceDecl interface_decl): { @@ -1309,17 +1307,16 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id, // A non-generic interface declaration evaluates to the interface type. return MakeConstantResult( eval_context.context(), - SemIR::InterfaceType{ - .type_id = SemIR::TypeId::TypeType, - .interface_id = interface_decl.interface_id, - .instance_id = SemIR::GenericInstanceId::Invalid}, + SemIR::InterfaceType{.type_id = SemIR::TypeId::TypeType, + .interface_id = interface_decl.interface_id, + .specific_id = SemIR::SpecificId::Invalid}, Phase::Template); } - case CARBON_KIND(SemIR::SpecificConstant instance): { + case CARBON_KIND(SemIR::SpecificConstant specific): { // Pull the constant value out of the specific. - return SemIR::GetConstantValueInInstance( - eval_context.sem_ir(), instance.instance_id, instance.inst_id); + return SemIR::GetConstantValueInSpecific( + eval_context.sem_ir(), specific.specific_id, specific.inst_id); } // These cases are treated as being the unique canonical definition of the @@ -1371,8 +1368,8 @@ auto TryEvalInstInContext(EvalContext& eval_context, SemIR::InstId inst_id, const auto& bind_name = eval_context.entity_names().Get(bind.entity_name_id); - // If we know which instance we're evaluating within and this is an - // argument of that instance, its constant value is the corresponding + // If we know which specific we're evaluating within and this is an + // argument of that specific, its constant value is the corresponding // argument value. if (auto value = eval_context.GetCompileTimeBindValue(bind_name.bind_index); @@ -1482,11 +1479,10 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst) return TryEvalInstInContext(eval_context, inst_id, inst); } -auto TryEvalBlockForSpecific(Context& context, - SemIR::GenericInstanceId specific_id, +auto TryEvalBlockForSpecific(Context& context, SemIR::SpecificId specific_id, SemIR::GenericInstIndex::Region region) -> SemIR::InstBlockId { - auto generic_id = context.generic_instances().Get(specific_id).generic_id; + auto generic_id = context.specifics().Get(specific_id).generic_id; auto eval_block_id = context.generics().Get(generic_id).GetEvalBlock(region); auto eval_block = context.inst_blocks().Get(eval_block_id); diff --git a/toolchain/check/eval.h b/toolchain/check/eval.h index 668b33207906..d56a41ba4ff7 100644 --- a/toolchain/check/eval.h +++ b/toolchain/check/eval.h @@ -20,8 +20,7 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst) // Evaluates the eval block for a region of a specific. Produces a block // containing the evaluated constant values of the instructions in the eval // block. -auto TryEvalBlockForSpecific(Context& context, - SemIR::GenericInstanceId specific_id, +auto TryEvalBlockForSpecific(Context& context, SemIR::SpecificId specific_id, SemIR::GenericInstIndex::Region region) -> SemIR::InstBlockId; diff --git a/toolchain/check/function.cpp b/toolchain/check/function.cpp index 76fd8fb6ba85..9fbc569bb640 100644 --- a/toolchain/check/function.cpp +++ b/toolchain/check/function.cpp @@ -26,7 +26,7 @@ auto CheckFunctionTypeMatches(Context& context, auto new_return_type_id = new_function.GetDeclaredReturnType(context.sem_ir()); auto prev_return_type_id = prev_function.GetDeclaredReturnType( - context.sem_ir(), SemIR::GenericInstanceId::Invalid); + context.sem_ir(), SemIR::SpecificId::Invalid); if (new_return_type_id == SemIR::TypeId::Error || prev_return_type_id == SemIR::TypeId::Error) { return false; @@ -72,7 +72,7 @@ auto CheckFunctionTypeMatches(Context& context, auto CheckFunctionReturnType(Context& context, SemIRLoc loc, SemIR::Function& function, - SemIR::GenericInstanceId specific_id) + SemIR::SpecificId specific_id) -> SemIR::Function::ReturnSlot { // If we have already checked the return type, we have nothing to do. if (function.return_slot != SemIR::Function::ReturnSlot::NotComputed && diff --git a/toolchain/check/function.h b/toolchain/check/function.h index caf93ada44e6..455b29b8562b 100644 --- a/toolchain/check/function.h +++ b/toolchain/check/function.h @@ -40,7 +40,7 @@ auto CheckFunctionTypeMatches(Context& context, // necessary. auto CheckFunctionReturnType(Context& context, SemIRLoc loc, SemIR::Function& function, - SemIR::GenericInstanceId specific_id) + SemIR::SpecificId specific_id) -> SemIR::Function::ReturnSlot; } // namespace Carbon::Check diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index a6347f5031e4..d1048531084a 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -30,9 +30,8 @@ auto StartGenericDefinition(Context& context) -> void { // Adds an instruction `generic_inst_id` to the eval block for a generic region, // which is the current instruction block. The instruction `generic_inst_id` is // expected to compute the value of the constant described by `const_inst_id` in -// each instance of the generic. Forms and returns a corresponding symbolic -// constant ID that refers to the substituted value of that instruction in each -// instance of the generic. +// each specific. Forms and returns a corresponding symbolic constant ID that +// refers to the substituted value of that instruction in each specific. static auto AddGenericConstantInstToEvalBlock( Context& context, SemIR::GenericId generic_id, SemIR::GenericInstIndex::Region region, SemIR::InstId const_inst_id, @@ -124,9 +123,9 @@ class RebuildGenericConstantInEvalBlockCallbacks final } // namespace // Adds instructions to compute the substituted version of `type_id` in each -// instance of a generic into the eval block for the generic, which is the -// current instruction block. Returns a symbolic type ID that refers to the -// substituted type in each instance of the generic. +// specific into the eval block for the generic, which is the current +// instruction block. Returns a symbolic type ID that refers to the substituted +// type in each specific. static auto AddGenericTypeToEvalBlock( Context& context, SemIR::GenericId generic_id, SemIR::GenericInstIndex::Region region, @@ -142,9 +141,9 @@ static auto AddGenericTypeToEvalBlock( } // Adds instructions to compute the substituted value of `inst_id` in each -// instance of a generic into the eval block for the generic, which is the -// current instruction block. Returns a symbolic constant instruction ID that -// refers to the substituted constant value in each instance of the generic. +// specific into the eval block for the generic, which is the current +// instruction block. Returns a symbolic constant instruction ID that refers to +// the substituted constant value in each specific. static auto AddGenericConstantToEvalBlock( Context& context, SemIR::GenericId generic_id, SemIR::GenericInstIndex::Region region, @@ -164,7 +163,7 @@ static auto AddGenericConstantToEvalBlock( } // Builds and returns a block of instructions whose constant values need to be -// evaluated in order to resolve a generic instance. +// evaluated in order to resolve a generic to a specific. static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id, SemIR::GenericInstIndex::Region region) -> SemIR::InstBlockId { @@ -209,7 +208,7 @@ static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id, } // If the instruction has a symbolic constant value, then make a note that - // we'll need to evaluate this instruction in the generic instance. Update + // we'll need to evaluate this instruction when forming the specific. Update // the constant value of the instruction to refer to the result of that // eventual evaluation. if ((dep_kind & GenericRegionStack::DependencyKind::SymbolicConstant) != @@ -253,15 +252,15 @@ auto FinishGenericDecl(Context& context, SemIR::InstId decl_id) auto generic_id = context.generics().Add( SemIR::Generic{.decl_id = decl_id, .bindings_id = bindings_id, - .self_instance_id = SemIR::GenericInstanceId::Invalid}); + .self_specific_id = SemIR::SpecificId::Invalid}); auto decl_block_id = MakeGenericEvalBlock( context, generic_id, SemIR::GenericInstIndex::Region::Declaration); context.generic_region_stack().Pop(); context.generics().Get(generic_id).decl_block_id = decl_block_id; - auto self_instance_id = MakeGenericSelfInstance(context, generic_id); - context.generics().Get(generic_id).self_instance_id = self_instance_id; + auto self_specific_id = MakeSelfSpecific(context, generic_id); + context.generics().Get(generic_id).self_specific_id = self_specific_id; return generic_id; } @@ -290,33 +289,32 @@ auto FinishGenericDefinition(Context& context, SemIR::GenericId generic_id) context.generic_region_stack().Pop(); } -auto MakeGenericInstance(Context& context, SemIR::GenericId generic_id, - SemIR::InstBlockId args_id) - -> SemIR::GenericInstanceId { - auto instance_id = context.generic_instances().GetOrAdd(generic_id, args_id); +auto MakeSpecific(Context& context, SemIR::GenericId generic_id, + SemIR::InstBlockId args_id) -> SemIR::SpecificId { + auto specific_id = context.specifics().GetOrAdd(generic_id, args_id); // TODO: Remove this once we import generics properly. if (!generic_id.is_valid()) { - return instance_id; + return specific_id; } - // If this is the first time we've formed this instance, evaluate its decl - // block to form information about the instance. - if (!context.generic_instances().Get(instance_id).decl_block_id.is_valid()) { + // If this is the first time we've formed this specific, evaluate its decl + // block to form information about the specific. + if (!context.specifics().Get(specific_id).decl_block_id.is_valid()) { auto decl_block_id = TryEvalBlockForSpecific( - context, instance_id, SemIR::GenericInstIndex::Region::Declaration); - // Note that TryEvalBlockForSpecific may reallocate the list of generic - // instances, so re-lookup the instance here. - context.generic_instances().Get(instance_id).decl_block_id = decl_block_id; + context, specific_id, SemIR::GenericInstIndex::Region::Declaration); + // Note that TryEvalBlockForSpecific may reallocate the list of specifics, + // so re-lookup the specific here. + context.specifics().Get(specific_id).decl_block_id = decl_block_id; } - return instance_id; + return specific_id; } -auto MakeGenericSelfInstance(Context& context, SemIR::GenericId generic_id) - -> SemIR::GenericInstanceId { +auto MakeSelfSpecific(Context& context, SemIR::GenericId generic_id) + -> SemIR::SpecificId { if (!generic_id.is_valid()) { - return SemIR::GenericInstanceId::Invalid; + return SemIR::SpecificId::Invalid; } auto& generic = context.generics().Get(generic_id); @@ -330,16 +328,16 @@ auto MakeGenericSelfInstance(Context& context, SemIR::GenericId generic_id) } auto args_id = context.inst_blocks().AddCanonical(arg_ids); - // Build a corresponding instance. + // Build a corresponding specific. // TODO: This could be made more efficient. We don't need to perform // substitution here; we know we want identity mappings for all constants and // types. We could also consider not storing the mapping at all in this case. - return MakeGenericInstance(context, generic_id, args_id); + return MakeSpecific(context, generic_id, args_id); } -auto ResolveSpecificDefinition(Context& context, - SemIR::GenericInstanceId specific_id) -> bool { - auto& specific = context.generic_instances().Get(specific_id); +auto ResolveSpecificDefinition(Context& context, SemIR::SpecificId specific_id) + -> bool { + auto& specific = context.specifics().Get(specific_id); auto generic_id = specific.generic_id; // TODO: Remove this once we import generics properly. @@ -356,9 +354,9 @@ auto ResolveSpecificDefinition(Context& context, } auto definition_block_id = TryEvalBlockForSpecific( context, specific_id, SemIR::GenericInstIndex::Region::Definition); - // Note that TryEvalBlockForSpecific may reallocate the list of generic - // instances, so re-lookup the instance here. - context.generic_instances().Get(specific_id).definition_block_id = + // Note that TryEvalBlockForSpecific may reallocate the list of specifics, + // so re-lookup the specific here. + context.specifics().Get(specific_id).definition_block_id = definition_block_id; } return true; diff --git a/toolchain/check/generic.h b/toolchain/check/generic.h index f5c3ba49374d..63424681977a 100644 --- a/toolchain/check/generic.h +++ b/toolchain/check/generic.h @@ -31,26 +31,25 @@ auto FinishGenericRedecl(Context& context, SemIR::InstId decl_id, auto FinishGenericDefinition(Context& context, SemIR::GenericId generic_id) -> void; -// Builds a new generic instance, or finds an existing one if this instance of -// this generic has already been referenced. Performs substitution into the +// Builds a new specific, or finds an existing one if this generic has already +// been referenced with these arguments. Performs substitution into the // declaration, but not the definition, of the generic. // // `args_id` should be a canonical instruction block referring to constants. -auto MakeGenericInstance(Context& context, SemIR::GenericId generic_id, - SemIR::InstBlockId args_id) - -> SemIR::GenericInstanceId; +auto MakeSpecific(Context& context, SemIR::GenericId generic_id, + SemIR::InstBlockId args_id) -> SemIR::SpecificId; -// Builds the generic instance corresponding to the generic itself. For example, -// for a generic `G(T:! type)`, this is `G(T)`. For an invalid `generic_id`, -// returns an invalid instance ID. -auto MakeGenericSelfInstance(Context& context, SemIR::GenericId generic_id) - -> SemIR::GenericInstanceId; +// Builds the specific that describes how the generic should refer to itself. +// For example, for a generic `G(T:! type)`, this is the specific `G(T)`. For an +// invalid `generic_id`, returns an invalid specific ID. +auto MakeSelfSpecific(Context& context, SemIR::GenericId generic_id) + -> SemIR::SpecificId; // Attempts to resolve the definition of the given specific, by evaluating the // eval block of the corresponding generic and storing a corresponding value // block in the specific. Returns false if a definition is not available. -auto ResolveSpecificDefinition(Context& context, - SemIR::GenericInstanceId specific_id) -> bool; +auto ResolveSpecificDefinition(Context& context, SemIR::SpecificId specific_id) + -> bool; } // namespace Carbon::Check diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index 0d398df19815..49da8614a86c 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -252,13 +252,13 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, // declaration. auto& class_info = context.classes().Get(class_decl.class_id); if (class_info.is_generic()) { - auto instance_id = - context.generics().GetSelfInstance(class_info.generic_id); + auto specific_id = + context.generics().GetSelfSpecific(class_info.generic_id); class_info.self_type_id = context.GetTypeIdForTypeConstant( TryEvalInst(context, SemIR::InstId::Invalid, SemIR::ClassType{.type_id = SemIR::TypeId::TypeType, .class_id = class_decl.class_id, - .instance_id = instance_id})); + .specific_id = specific_id})); } else { class_info.self_type_id = context.GetTypeIdForTypeInst(class_decl_id); } @@ -293,7 +293,7 @@ auto HandleParseNode(Context& context, Parse::ClassDefinitionStartId node_id) // Enter the class scope. context.scope_stack().Push( class_decl_id, class_info.scope_id, - context.generics().GetSelfInstance(class_info.generic_id)); + context.generics().GetSelfSpecific(class_info.generic_id)); StartGenericDefinition(context); // Introduce `Self`. diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 0fe6899cde37..9723bcb61667 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -335,7 +335,7 @@ static auto HandleFunctionDefinitionAfterSignature( // Check the return type is complete. CheckFunctionReturnType(context, function.return_storage_id, function, - SemIR::GenericInstanceId::Invalid); + SemIR::SpecificId::Invalid); // Check the parameter types are complete. for (auto param_id : llvm::concat( diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index 91983b252e13..fac3f83586fa 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -144,7 +144,7 @@ auto HandleParseNode(Context& context, // Enter the interface scope. context.scope_stack().Push( interface_decl_id, interface_info.scope_id, - context.generics().GetSelfInstance(interface_info.generic_id)); + context.generics().GetSelfSpecific(interface_info.generic_id)); StartGenericDefinition(context); context.inst_block_stack().Push(); @@ -157,13 +157,13 @@ auto HandleParseNode(Context& context, if (!interface_info.is_defined()) { SemIR::TypeId self_type_id = SemIR::TypeId::Invalid; if (interface_info.is_generic()) { - auto instance_id = - context.generics().GetSelfInstance(interface_info.generic_id); + auto specific_id = + context.generics().GetSelfSpecific(interface_info.generic_id); self_type_id = context.GetTypeIdForTypeConstant( TryEvalInst(context, SemIR::InstId::Invalid, SemIR::InterfaceType{.type_id = SemIR::TypeId::TypeType, .interface_id = interface_id, - .instance_id = instance_id})); + .specific_id = specific_id})); } else { self_type_id = context.GetTypeIdForTypeInst(interface_decl_id); } diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index ae556aca73be..ac5f8107be7d 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -81,18 +81,18 @@ static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id, SemIR::NameId name_id) -> bool { auto result = context.LookupUnqualifiedName(node_id, name_id); auto value = context.insts().Get(result.inst_id); - auto type_id = SemIR::GetTypeInInstance(context.sem_ir(), result.instance_id, + auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id, value.type_id()); CARBON_CHECK(type_id.is_valid()) << "Missing type for " << value; - // If the named entity has a constant value that depends on its generic - // instance, store the instance too. - if (result.instance_id.is_valid() && + // If the named entity has a constant value that depends on its specific, + // store the specific too. + if (result.specific_id.is_valid() && context.constant_values().Get(result.inst_id).is_symbolic()) { result.inst_id = context.AddInst( node_id, {.type_id = type_id, .inst_id = result.inst_id, - .instance_id = result.instance_id}); + .specific_id = result.specific_id}); } context.AddInstAndPush( diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index fc8baa32eb6f..76f61bc4ed74 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -422,30 +422,30 @@ class ImportRefResolver { } // Gets a local argument list corresponding to the arguments of an imported - // generic instance. - auto GetLocalGenericInstanceArgs(SemIR::GenericInstanceId instance_id) + // specific. + auto GetLocalSpecificArgs(SemIR::SpecificId specific_id) -> llvm::SmallVector { - if (!instance_id.is_valid()) { + if (!specific_id.is_valid()) { return {}; } return GetLocalInstBlockContents( - import_ir_.generic_instances().Get(instance_id).args_id); + import_ir_.specifics().Get(specific_id).args_id); } - // Gets a local generic instance whose arguments were already imported by - // GetLocalGenericInstanceArgs. Does not add any new work. - auto GetLocalGenericInstance(SemIR::GenericInstanceId instance_id, - llvm::ArrayRef args) - -> SemIR::GenericInstanceId { - if (!instance_id.is_valid()) { - return SemIR::GenericInstanceId::Invalid; + // Gets a local specific whose arguments were already imported by + // GetLocalSpecificArgs. Does not add any new work. + auto GetLocalSpecific(SemIR::SpecificId specific_id, + llvm::ArrayRef args) + -> SemIR::SpecificId { + if (!specific_id.is_valid()) { + return SemIR::SpecificId::Invalid; } - const auto& instance = import_ir_.generic_instances().Get(instance_id); + const auto& specific = import_ir_.specifics().Get(specific_id); // TODO: Import the generic. auto generic_id = SemIR::GenericId::Invalid; - auto args_id = GetLocalCanonicalInstBlockId(instance.args_id, args); - // TODO: Also import the generic instance. - return context_.generic_instances().GetOrAdd(generic_id, args_id); + auto args_id = GetLocalCanonicalInstBlockId(specific.args_id, args); + // TODO: Also import the specific. + return context_.specifics().GetOrAdd(generic_id, args_id); } // Returns the ConstantId for each parameter's type. Adds unresolved constants @@ -1046,7 +1046,7 @@ class ImportRefResolver { CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); auto class_const_id = GetLocalConstantId(import_ir_.classes().Get(inst.class_id).decl_id); - auto args = GetLocalGenericInstanceArgs(inst.instance_id); + auto args = GetLocalSpecificArgs(inst.specific_id); if (HasNewWork(initial_work)) { return ResolveResult::Retry(); } @@ -1061,11 +1061,11 @@ class ImportRefResolver { } else { auto generic_class_type = context_.types().GetAs( class_const_inst.type_id()); - auto instance_id = GetLocalGenericInstance(inst.instance_id, args); + auto specific_id = GetLocalSpecific(inst.specific_id, args); return ResolveAs( {.type_id = SemIR::TypeId::TypeType, .class_id = generic_class_type.class_id, - .instance_id = instance_id}); + .specific_id = specific_id}); } } @@ -1164,7 +1164,7 @@ class ImportRefResolver { .return_slot = function.return_slot, .builtin_function_kind = function.builtin_function_kind}}); // TODO: Import this or recompute it. - auto specific_id = SemIR::GenericInstanceId::Invalid; + auto specific_id = SemIR::SpecificId::Invalid; function_decl.type_id = context_.GetFunctionType(function_decl.function_id, specific_id); // Write the function ID into the FunctionDecl. @@ -1182,8 +1182,8 @@ class ImportRefResolver { } auto fn_val = context_.insts().Get(fn_val_id); CARBON_CHECK(context_.types().Is(fn_val.type_id())); - // TODO: Import the correct generic instance and build a function type - // constant using it. + // TODO: Import the correct specific and build a function type constant + // using it. return {.const_id = context_.types().GetConstantId(fn_val.type_id())}; } @@ -1355,7 +1355,7 @@ class ImportRefResolver { CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); auto interface_const_id = GetLocalConstantId( import_ir_.interfaces().Get(inst.interface_id).decl_id); - auto args = GetLocalGenericInstanceArgs(inst.instance_id); + auto args = GetLocalSpecificArgs(inst.specific_id); if (HasNewWork(initial_work)) { return ResolveResult::Retry(); } @@ -1372,11 +1372,11 @@ class ImportRefResolver { auto generic_interface_type = context_.types().GetAs( interface_const_inst.type_id()); - auto instance_id = GetLocalGenericInstance(inst.instance_id, args); + auto specific_id = GetLocalSpecific(inst.specific_id, args); return ResolveAs( {.type_id = SemIR::TypeId::TypeType, .interface_id = generic_interface_type.interface_id, - .instance_id = instance_id}); + .specific_id = specific_id}); } } diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 10267fe32dd9..c91c90eaa1a5 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -27,7 +27,7 @@ static auto GetAsLookupScope(Context& context, Parse::NodeId node_id, auto base = context.insts().Get(base_id); if (auto base_as_namespace = base.TryAs()) { return LookupScope{.name_scope_id = base_as_namespace->name_scope_id, - .instance_id = SemIR::GenericInstanceId::Invalid}; + .specific_id = SemIR::SpecificId::Invalid}; } // TODO: Consider refactoring the near-identical class and interface support // below. @@ -43,7 +43,7 @@ static auto GetAsLookupScope(Context& context, Parse::NodeId node_id, }); auto& class_info = context.classes().Get(base_as_class->class_id); return LookupScope{.name_scope_id = class_info.scope_id, - .instance_id = base_as_class->instance_id}; + .specific_id = base_as_class->specific_id}; } if (auto base_as_interface = base.TryAs()) { context.TryToDefineType( @@ -58,7 +58,7 @@ static auto GetAsLookupScope(Context& context, Parse::NodeId node_id, auto& interface_info = context.interfaces().Get(base_as_interface->interface_id); return LookupScope{.name_scope_id = interface_info.scope_id, - .instance_id = base_as_interface->instance_id}; + .specific_id = base_as_interface->specific_id}; } // TODO: Per the design, if `base_id` is any kind of type, then lookup should // treat it as a name scope, even if it doesn't have members. For example, @@ -218,7 +218,7 @@ static auto LookupMemberNameInScope(Context& context, Parse::NodeId node_id, SemIR::NameId name_id, SemIR::ConstantId name_scope_const_id, LookupScope lookup_scope) -> SemIR::InstId { - LookupResult result = {.instance_id = SemIR::GenericInstanceId::Invalid, + LookupResult result = {.specific_id = SemIR::SpecificId::Invalid, .inst_id = SemIR::InstId::BuiltinError}; if (lookup_scope.name_scope_id.is_valid()) { result = context.LookupQualifiedName(node_id, name_id, lookup_scope); @@ -226,18 +226,18 @@ static auto LookupMemberNameInScope(Context& context, Parse::NodeId node_id, // TODO: This duplicates the work that HandleNameAsExpr does. Factor this out. auto inst = context.insts().Get(result.inst_id); - auto type_id = SemIR::GetTypeInInstance(context.sem_ir(), result.instance_id, + auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id, inst.type_id()); CARBON_CHECK(type_id.is_valid()) << "Missing type for member " << inst; - // If the named entity has a constant value that depends on its generic - // instance, store the instance too. - if (result.instance_id.is_valid() && + // If the named entity has a constant value that depends on its specific, + // store the specific too. + if (result.specific_id.is_valid() && context.constant_values().Get(result.inst_id).is_symbolic()) { result.inst_id = context.AddInst( node_id, {.type_id = type_id, .inst_id = result.inst_id, - .instance_id = result.instance_id}); + .specific_id = result.specific_id}); } // TODO: Use a different kind of instruction that also references the diff --git a/toolchain/check/operator.cpp b/toolchain/check/operator.cpp index 4bae63e6d0a2..7aab3388a863 100644 --- a/toolchain/check/operator.cpp +++ b/toolchain/check/operator.cpp @@ -38,10 +38,9 @@ static auto GetOperatorOpFunction(Context& context, Parse::AnyExprId node_id, return SemIR::InstId::Invalid; } - // TODO: For a parameterized interface, find the corresponding generic - // instance. + // TODO: For a parameterized interface, find the corresponding specific. LookupScope scope = {.name_scope_id = interface_scope_id, - .instance_id = SemIR::GenericInstanceId::Invalid}; + .specific_id = SemIR::SpecificId::Invalid}; // Lookup `Interface.Op`. auto op_ident_id = context.identifiers().Add(op.op_name); @@ -53,8 +52,8 @@ static auto GetOperatorOpFunction(Context& context, Parse::AnyExprId node_id, } // Look through import_refs and aliases. - auto op_const_id = GetConstantValueInInstance( - context.sem_ir(), op_result.instance_id, op_result.inst_id); + auto op_const_id = GetConstantValueInSpecific( + context.sem_ir(), op_result.specific_id, op_result.inst_id); auto op_id = context.constant_values().GetInstId(op_const_id); // We expect it to be an associated function. diff --git a/toolchain/check/scope_stack.cpp b/toolchain/check/scope_stack.cpp index 0e0837fe97f6..8df737f512e3 100644 --- a/toolchain/check/scope_stack.cpp +++ b/toolchain/check/scope_stack.cpp @@ -14,13 +14,13 @@ auto ScopeStack::VerifyOnFinish() -> void { } auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, - SemIR::GenericInstanceId instance_id, + SemIR::SpecificId specific_id, bool lexical_lookup_has_load_error) -> void { // If this scope doesn't have a specific of its own, it lives in the enclosing // scope's specific, if any. - auto enclosing_instance_id = instance_id; - if (!instance_id.is_valid() && !scope_stack_.empty()) { - enclosing_instance_id = PeekSpecificId(); + auto enclosing_specific_id = specific_id; + if (!specific_id.is_valid() && !scope_stack_.empty()) { + enclosing_specific_id = PeekSpecificId(); } compile_time_binding_stack_.PushArray(); @@ -28,7 +28,7 @@ auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, {.index = next_scope_index_, .scope_inst_id = scope_inst_id, .scope_id = scope_id, - .instance_id = enclosing_instance_id, + .specific_id = enclosing_specific_id, .next_compile_time_bind_index = SemIR::CompileTimeBindIndex( compile_time_binding_stack_.all_values_size()), .lexical_lookup_has_load_error = @@ -36,13 +36,13 @@ auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id, if (scope_id.is_valid()) { non_lexical_scope_stack_.push_back({.scope_index = next_scope_index_, .name_scope_id = scope_id, - .instance_id = enclosing_instance_id}); + .specific_id = enclosing_specific_id}); } else { // For lexical lookups, unqualified lookup doesn't know how to find the - // associated generic instance, so if we start adding lexical scopes with - // generic instances, we'll need to somehow track them in lookup. - CARBON_CHECK(!instance_id.is_valid()) - << "Lexical scope should not have an associated generic instance."; + // associated specific, so if we start adding lexical scopes associated with + // specifics, we'll need to somehow track them in lookup. + CARBON_CHECK(!specific_id.is_valid()) + << "Lexical scope should not have an associated specific."; } // TODO: Handle this case more gracefully. @@ -226,7 +226,7 @@ auto ScopeStack::Restore(SuspendedScope scope) -> void { non_lexical_scope_stack_.push_back( {.scope_index = scope.entry.index, .name_scope_id = scope.entry.scope_id, - .instance_id = scope.entry.instance_id}); + .specific_id = scope.entry.specific_id}); } scope_stack_.push_back(std::move(scope.entry)); } diff --git a/toolchain/check/scope_stack.h b/toolchain/check/scope_stack.h index 473ab5421f40..6e87bc66536c 100644 --- a/toolchain/check/scope_stack.h +++ b/toolchain/check/scope_stack.h @@ -47,8 +47,8 @@ class ScopeStack { // The corresponding name scope. SemIR::NameScopeId name_scope_id; - // The corresponding generic instance. - SemIR::GenericInstanceId instance_id; + // The corresponding specific. + SemIR::SpecificId specific_id; }; // Information about a scope that has been temporarily removed from the stack. @@ -58,11 +58,10 @@ class ScopeStack { // scopes. lexical_lookup_has_load_error is used to limit diagnostics when a // given namespace may contain a mix of both successful and failed name // imports. - auto Push( - SemIR::InstId scope_inst_id = SemIR::InstId::Invalid, - SemIR::NameScopeId scope_id = SemIR::NameScopeId::Invalid, - SemIR::GenericInstanceId instance_id = SemIR::GenericInstanceId::Invalid, - bool lexical_lookup_has_load_error = false) -> void; + auto Push(SemIR::InstId scope_inst_id = SemIR::InstId::Invalid, + SemIR::NameScopeId scope_id = SemIR::NameScopeId::Invalid, + SemIR::SpecificId specific_id = SemIR::SpecificId::Invalid, + bool lexical_lookup_has_load_error = false) -> void; // Pops the top scope from scope_stack_, cleaning up names from // lexical_lookup_. @@ -92,8 +91,8 @@ class ScopeStack { // associated with a specific. This will generally be the self specific of the // innermost enclosing generic, as there is no way to enter any other specific // scope. - auto PeekSpecificId() const -> SemIR::GenericInstanceId { - return Peek().instance_id; + auto PeekSpecificId() const -> SemIR::SpecificId { + return Peek().specific_id; } // Returns the current scope, if it is of the specified kind. Otherwise, @@ -181,8 +180,8 @@ class ScopeStack { // The name scope associated with this entry, if any. SemIR::NameScopeId scope_id; - // The generic instance associated with this entry, if any. - SemIR::GenericInstanceId instance_id; + // The specific associated with this entry, if any. + SemIR::SpecificId specific_id; // The next compile-time binding index to allocate in this scope. SemIR::CompileTimeBindIndex next_compile_time_bind_index; diff --git a/toolchain/check/subst.cpp b/toolchain/check/subst.cpp index cd7c53f3cdf2..dffd5515848e 100644 --- a/toolchain/check/subst.cpp +++ b/toolchain/check/subst.cpp @@ -82,11 +82,11 @@ static auto PushOperand(Context& context, Worklist& worklist, worklist.Push(context.types().GetInstId(type_id)); } break; - case SemIR::IdKind::For: - if (auto instance_id = static_cast(arg); - instance_id.is_valid()) { + case SemIR::IdKind::For: + if (auto specific_id = static_cast(arg); + specific_id.is_valid()) { PushOperand(context, worklist, SemIR::IdKind::For, - context.generic_instances().Get(instance_id).args_id.index); + context.specifics().Get(specific_id).args_id.index); } break; default: @@ -145,17 +145,17 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind, } return new_type_block.GetCanonical().index; } - case SemIR::IdKind::For: { - auto instance_id = SemIR::GenericInstanceId(arg); - if (!instance_id.is_valid()) { + case SemIR::IdKind::For: { + auto specific_id = SemIR::SpecificId(arg); + if (!specific_id.is_valid()) { return arg; } - auto& instance = context.generic_instances().Get(instance_id); + auto& specific = context.specifics().Get(specific_id); auto args_id = PopOperand(context, worklist, SemIR::IdKind::For, - instance.args_id.index); - return MakeGenericInstance(context, instance.generic_id, - SemIR::InstBlockId(args_id)) + specific.args_id.index); + return MakeSpecific(context, specific.generic_id, + SemIR::InstBlockId(args_id)) .index; } default: diff --git a/toolchain/check/testdata/basics/builtin_insts.carbon b/toolchain/check/testdata/basics/builtin_insts.carbon index d6646722c251..9b55fde946bf 100644 --- a/toolchain/check/testdata/basics/builtin_insts.carbon +++ b/toolchain/check/testdata/basics/builtin_insts.carbon @@ -22,7 +22,7 @@ // CHECK:STDOUT: functions: {} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} diff --git a/toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon b/toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon index cb1c74ed8c61..252df75a92d1 100644 --- a/toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon @@ -39,7 +39,7 @@ fn B() { // CHECK:STDOUT: function0: {name: name0, parent_scope: name_scope0, body: [block4]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -51,7 +51,7 @@ fn B() { // CHECK:STDOUT: insts: // CHECK:STDOUT: 'inst+0': {kind: Namespace, arg0: name_scope0, arg1: inst, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+1': {kind: FunctionDecl, arg0: function0, arg1: empty, type: type(inst+2)} -// CHECK:STDOUT: 'inst+2': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+2': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+3': {kind: TupleType, arg0: type_block0, type: typeTypeType} // CHECK:STDOUT: 'inst+4': {kind: StructValue, arg0: empty, type: type(inst+2)} // CHECK:STDOUT: 'inst+5': {kind: Return} @@ -114,7 +114,7 @@ fn B() { // CHECK:STDOUT: function1: {name: name1, parent_scope: name_scope1} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -129,13 +129,13 @@ fn B() { // CHECK:STDOUT: 'inst+1': {kind: ImportDecl, arg0: name1} // CHECK:STDOUT: 'inst+2': {kind: Namespace, arg0: name_scope1, arg1: inst+1, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+3': {kind: FunctionDecl, arg0: function0, arg1: empty, type: type(inst+4)} -// CHECK:STDOUT: 'inst+4': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+4': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+5': {kind: TupleType, arg0: type_block0, type: typeTypeType} // CHECK:STDOUT: 'inst+6': {kind: StructValue, arg0: empty, type: type(inst+4)} // CHECK:STDOUT: 'inst+7': {kind: NameRef, arg0: name1, arg1: inst+2, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+8': {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name0, type: type(inst+10)} // CHECK:STDOUT: 'inst+9': {kind: FunctionDecl, arg0: function1, arg1: empty, type: type(inst+10)} -// CHECK:STDOUT: 'inst+10': {kind: FunctionType, arg0: function1, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+10': {kind: FunctionType, arg0: function1, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+11': {kind: StructValue, arg0: empty, type: type(inst+10)} // CHECK:STDOUT: 'inst+12': {kind: NameRef, arg0: name1, arg1: inst+8, type: type(inst+10)} // CHECK:STDOUT: 'inst+13': {kind: Call, arg0: inst+12, arg1: block5, type: type(inst+5)} diff --git a/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon b/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon index 9b4a09a8ed7d..770e5650d1f8 100644 --- a/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon @@ -39,7 +39,7 @@ fn B() { // CHECK:STDOUT: function0: {name: name0, parent_scope: name_scope0, body: [block4]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -51,7 +51,7 @@ fn B() { // CHECK:STDOUT: insts: // CHECK:STDOUT: 'inst+0': {kind: Namespace, arg0: name_scope0, arg1: inst, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+1': {kind: FunctionDecl, arg0: function0, arg1: empty, type: type(inst+2)} -// CHECK:STDOUT: 'inst+2': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+2': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+3': {kind: TupleType, arg0: type_block0, type: typeTypeType} // CHECK:STDOUT: 'inst+4': {kind: StructValue, arg0: empty, type: type(inst+2)} // CHECK:STDOUT: 'inst+5': {kind: Return} @@ -93,7 +93,7 @@ fn B() { // CHECK:STDOUT: function1: {name: name1, parent_scope: name_scope1} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -108,13 +108,13 @@ fn B() { // CHECK:STDOUT: 'inst+1': {kind: ImportDecl, arg0: name1} // CHECK:STDOUT: 'inst+2': {kind: Namespace, arg0: name_scope1, arg1: inst+1, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+3': {kind: FunctionDecl, arg0: function0, arg1: empty, type: type(inst+4)} -// CHECK:STDOUT: 'inst+4': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+4': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+5': {kind: TupleType, arg0: type_block0, type: typeTypeType} // CHECK:STDOUT: 'inst+6': {kind: StructValue, arg0: empty, type: type(inst+4)} // CHECK:STDOUT: 'inst+7': {kind: NameRef, arg0: name1, arg1: inst+2, type: type(instNamespaceType)} // CHECK:STDOUT: 'inst+8': {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name0, type: type(inst+10)} // CHECK:STDOUT: 'inst+9': {kind: FunctionDecl, arg0: function1, arg1: empty, type: type(inst+10)} -// CHECK:STDOUT: 'inst+10': {kind: FunctionType, arg0: function1, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+10': {kind: FunctionType, arg0: function1, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+11': {kind: StructValue, arg0: empty, type: type(inst+10)} // CHECK:STDOUT: 'inst+12': {kind: NameRef, arg0: name1, arg1: inst+8, type: type(inst+10)} // CHECK:STDOUT: 'inst+13': {kind: Call, arg0: inst+12, arg1: block5, type: type(inst+5)} diff --git a/toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon b/toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon index 4d6b48094345..813f7357598e 100644 --- a/toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon @@ -30,7 +30,7 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: function0: {name: name0, parent_scope: name_scope0, return_storage: inst+13, return_slot: present, body: [block7]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} -// CHECK:STDOUT: generic_instances: {} +// CHECK:STDOUT: specifics: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -60,7 +60,7 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: 'inst+12': {kind: Converted, arg0: inst+9, arg1: inst+8, type: typeTypeType} // CHECK:STDOUT: 'inst+13': {kind: VarStorage, arg0: nameReturnSlot, type: type(inst+8)} // CHECK:STDOUT: 'inst+14': {kind: FunctionDecl, arg0: function0, arg1: block6, type: type(inst+15)} -// CHECK:STDOUT: 'inst+15': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+15': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+16': {kind: StructValue, arg0: empty, type: type(inst+15)} // CHECK:STDOUT: 'inst+17': {kind: PointerType, arg0: type(inst+8), type: typeTypeType} // CHECK:STDOUT: 'inst+18': {kind: NameRef, arg0: name1, arg1: inst+5, type: type(inst+1)} diff --git a/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon b/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon index 65c572852f25..1d59fd2e516e 100644 --- a/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon @@ -32,8 +32,8 @@ fn Foo[T:! type](n: T) -> (T, ()) { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: // CHECK:STDOUT: generic0: {decl: inst+16, bindings: block8} -// CHECK:STDOUT: generic_instances: -// CHECK:STDOUT: genericInstance0: {generic: generic0, args: block10} +// CHECK:STDOUT: specifics: +// CHECK:STDOUT: specific0: {generic: generic0, args: block10} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -77,7 +77,7 @@ fn Foo[T:! type](n: T) -> (T, ()) { // CHECK:STDOUT: 'inst+17': {kind: BindSymbolicName, arg0: entity_name0, arg1: inst, type: typeTypeType} // CHECK:STDOUT: 'inst+18': {kind: TupleType, arg0: type_block3, type: typeTypeType} // CHECK:STDOUT: 'inst+19': {kind: TupleType, arg0: type_block3, type: typeTypeType} -// CHECK:STDOUT: 'inst+20': {kind: FunctionType, arg0: function0, arg1: genericInstance, type: typeTypeType} +// CHECK:STDOUT: 'inst+20': {kind: FunctionType, arg0: function0, arg1: specific, type: typeTypeType} // CHECK:STDOUT: 'inst+21': {kind: StructValue, arg0: empty, type: type(inst+20)} // CHECK:STDOUT: 'inst+22': {kind: PointerType, arg0: type(symbolicConstant1), type: typeTypeType} // CHECK:STDOUT: 'inst+23': {kind: NameRef, arg0: name2, arg1: inst+6, type: type(symbolicConstant2)} diff --git a/toolchain/parse/node_ids.h b/toolchain/parse/node_ids.h index 3aaf3754ce78..343782b5c2cd 100644 --- a/toolchain/parse/node_ids.h +++ b/toolchain/parse/node_ids.h @@ -20,7 +20,7 @@ struct InvalidNodeId {}; // contain any of the information about the node, and serve as a handle that // can be used with the underlying tree to query for detailed information. struct NodeId : public IdBase { - // An explicitly invalid instance. + // An explicitly invalid node ID. static constexpr InvalidNodeId Invalid; using IdBase::IdBase; diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index aed657b7a1de..41700e62b36d 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -152,7 +152,7 @@ auto File::OutputYaml(bool include_builtins) const -> Yaml::OutputMapping { map.Add("functions", functions_.OutputYaml()); map.Add("classes", classes_.OutputYaml()); map.Add("generics", generics_.OutputYaml()); - map.Add("generic_instances", generic_instances_.OutputYaml()); + map.Add("specifics", specifics_.OutputYaml()); map.Add("types", types_.OutputYaml()); map.Add("type_blocks", type_blocks_.OutputYaml()); map.Add( @@ -201,8 +201,7 @@ auto File::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const mem_usage.Collect(MemUsage::ConcatLabel(label, "interfaces_"), interfaces_); mem_usage.Collect(MemUsage::ConcatLabel(label, "impls_"), impls_); mem_usage.Collect(MemUsage::ConcatLabel(label, "generics_"), generics_); - mem_usage.Collect(MemUsage::ConcatLabel(label, "generic_instances_"), - generic_instances_); + mem_usage.Collect(MemUsage::ConcatLabel(label, "specifics_"), specifics_); mem_usage.Collect(MemUsage::ConcatLabel(label, "import_irs_"), import_irs_); mem_usage.Collect(MemUsage::ConcatLabel(label, "import_ir_insts_"), import_ir_insts_); diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index d994497bcffc..d20e47879458 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -125,12 +125,8 @@ class File : public Printable { auto impls() const -> const ImplStore& { return impls_; } auto generics() -> GenericStore& { return generics_; } auto generics() const -> const GenericStore& { return generics_; } - auto generic_instances() -> GenericInstanceStore& { - return generic_instances_; - } - auto generic_instances() const -> const GenericInstanceStore& { - return generic_instances_; - } + auto specifics() -> SpecificStore& { return specifics_; } + auto specifics() const -> const SpecificStore& { return specifics_; } auto import_irs() -> ValueStore& { return import_irs_; } auto import_irs() const -> const ValueStore& { return import_irs_; @@ -215,8 +211,8 @@ class File : public Printable { // Storage for generics. GenericStore generics_; - // Storage for instances of generics. - GenericInstanceStore generic_instances_; + // Storage for specifics. + SpecificStore specifics_; // Related IRs. There are some fixed entries at the start; see ImportIRId. ValueStore import_irs_; diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index da1d5a9134ac..a158a9a1e9df 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -69,8 +69,8 @@ class FormatterImpl { FormatFunction(FunctionId(i)); } - for (int i : llvm::seq(sem_ir_.generic_instances().size())) { - FormatSpecific(GenericInstanceId(i)); + for (int i : llvm::seq(sem_ir_.specifics().size())) { + FormatSpecific(SpecificId(i)); } // End-of-file newline. @@ -370,8 +370,7 @@ class FormatterImpl { out_ << '\n'; } - auto FormatSpecificRegion(const Generic& generic, - const GenericInstance& specific, + auto FormatSpecificRegion(const Generic& generic, const Specific& specific, GenericInstIndex::Region region, llvm::StringRef region_name) -> void { if (!specific.GetValueBlock(region).is_valid()) { @@ -409,8 +408,8 @@ class FormatterImpl { } } - auto FormatSpecific(GenericInstanceId id) -> void { - const auto& specific = sem_ir_.generic_instances().Get(id); + auto FormatSpecific(SpecificId id) -> void { + const auto& specific = sem_ir_.specifics().Get(id); out_ << "\n"; @@ -764,8 +763,8 @@ class FormatterImpl { } auto FormatInstRHS(FunctionType inst) -> void { - if (inst.instance_id.is_valid()) { - FormatArgs(inst.function_id, inst.instance_id); + if (inst.specific_id.is_valid()) { + FormatArgs(inst.function_id, inst.specific_id); } else { FormatArgs(inst.function_id); } @@ -777,8 +776,8 @@ class FormatterImpl { } auto FormatInstRHS(ClassType inst) -> void { - if (inst.instance_id.is_valid()) { - FormatArgs(inst.class_id, inst.instance_id); + if (inst.specific_id.is_valid()) { + FormatArgs(inst.class_id, inst.specific_id); } else { FormatArgs(inst.class_id); } @@ -795,8 +794,8 @@ class FormatterImpl { } auto FormatInstRHS(InterfaceType inst) -> void { - if (inst.instance_id.is_valid()) { - FormatArgs(inst.interface_id, inst.instance_id); + if (inst.specific_id.is_valid()) { + FormatArgs(inst.interface_id, inst.specific_id); } else { FormatArgs(inst.interface_id); } @@ -949,7 +948,7 @@ class FormatterImpl { out_ << ')'; } - auto FormatArg(GenericInstanceId id) -> void { FormatName(id); } + auto FormatArg(SpecificId id) -> void { FormatName(id); } auto FormatArg(RealId id) -> void { // TODO: Format with a `.` when the exponent is near zero. @@ -997,8 +996,8 @@ class FormatterImpl { out_ << inst_namer_->GetNameFor(id); } - auto FormatName(GenericInstanceId id) -> void { - const auto& specific = sem_ir_.generic_instances().Get(id); + auto FormatName(SpecificId id) -> void { + const auto& specific = sem_ir_.specifics().Get(id); FormatName(specific.generic_id); FormatArg(specific.args_id); } diff --git a/toolchain/sem_ir/function.cpp b/toolchain/sem_ir/function.cpp index 2b73eed5c514..fae56107f13e 100644 --- a/toolchain/sem_ir/function.cpp +++ b/toolchain/sem_ir/function.cpp @@ -12,7 +12,7 @@ namespace Carbon::SemIR { auto GetCalleeFunction(const File& sem_ir, InstId callee_id) -> CalleeFunction { CalleeFunction result = {.function_id = FunctionId::Invalid, - .instance_id = GenericInstanceId::Invalid, + .specific_id = SpecificId::Invalid, .self_id = InstId::Invalid, .is_error = false}; @@ -38,17 +38,16 @@ auto GetCalleeFunction(const File& sem_ir, InstId callee_id) -> CalleeFunction { } result.function_id = fn_type->function_id; - result.instance_id = fn_type->instance_id; + result.specific_id = fn_type->specific_id; return result; } auto Function::GetDeclaredReturnType(const File& file, - GenericInstanceId specific_id) const - -> TypeId { + SpecificId specific_id) const -> TypeId { if (!return_storage_id.is_valid()) { return TypeId::Invalid; } - return GetTypeInInstance(file, specific_id, + return GetTypeInSpecific(file, specific_id, file.insts().Get(return_storage_id).type_id()); } diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 0e9f8e36584d..2eeb8be3011f 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -98,13 +98,13 @@ struct Function : public EntityWithParamsBase, static auto GetParamFromParamRefId(const File& sem_ir, InstId param_ref_id) -> std::pair; - // Gets the declared return type for a specific instance of this function, or + // Gets the declared return type for a specific version of this function, or // the canonical return type for the original declaration no specific is // specified. Returns `Invalid` if no return type was specified, in which // case the effective return type is an empty tuple. auto GetDeclaredReturnType(const File& file, - GenericInstanceId specific_id = - GenericInstanceId::Invalid) const -> TypeId; + SpecificId specific_id = SpecificId::Invalid) const + -> TypeId; // Returns whether the function has a return slot. Can only be called for a // function that has either been called or defined, otherwise this is not @@ -126,8 +126,8 @@ class File; struct CalleeFunction { // The function. Invalid if not a function. SemIR::FunctionId function_id; - // The generic instance that contains the function. - SemIR::GenericInstanceId instance_id; + // The specific that contains the function. + SemIR::SpecificId specific_id; // The bound `self` parameter. Invalid if not a method. SemIR::InstId self_id; // True if an error instruction was found. diff --git a/toolchain/sem_ir/generic.cpp b/toolchain/sem_ir/generic.cpp index 4dbcc10706c8..b04cea6d8cba 100644 --- a/toolchain/sem_ir/generic.cpp +++ b/toolchain/sem_ir/generic.cpp @@ -8,10 +8,9 @@ namespace Carbon::SemIR { -class GenericInstanceStore::KeyContext - : public TranslatingKeyContext { +class SpecificStore::KeyContext : public TranslatingKeyContext { public: - // A lookup key for a generic instance. + // A lookup key for a specific. struct Key { GenericId generic_id; InstBlockId args_id; @@ -19,41 +18,39 @@ class GenericInstanceStore::KeyContext friend auto operator==(const Key&, const Key&) -> bool = default; }; - explicit KeyContext(llvm::ArrayRef instances) - : instances_(instances) {} + explicit KeyContext(llvm::ArrayRef specifics) + : specifics_(specifics) {} - auto TranslateKey(GenericInstanceId id) const -> Key { - const auto& instance = instances_[id.index]; - return {.generic_id = instance.generic_id, .args_id = instance.args_id}; + auto TranslateKey(SpecificId id) const -> Key { + const auto& specific = specifics_[id.index]; + return {.generic_id = specific.generic_id, .args_id = specific.args_id}; } private: - llvm::ArrayRef instances_; + llvm::ArrayRef specifics_; }; -auto GenericInstanceStore::GetOrAdd(GenericId generic_id, InstBlockId args_id) - -> GenericInstanceId { +auto SpecificStore::GetOrAdd(GenericId generic_id, InstBlockId args_id) + -> SpecificId { return lookup_table_ .Insert( KeyContext::Key{.generic_id = generic_id, .args_id = args_id}, [&] { - return generic_instances_.Add( + return specifics_.Add( {.generic_id = generic_id, .args_id = args_id}); }, - KeyContext(generic_instances_.array_ref())) + KeyContext(specifics_.array_ref())) .key(); } -auto GenericInstanceStore::CollectMemUsage(MemUsage& mem_usage, - llvm::StringRef label) const - -> void { - mem_usage.Collect(MemUsage::ConcatLabel(label, "generic_instances_"), - generic_instances_); +auto SpecificStore::CollectMemUsage(MemUsage& mem_usage, + llvm::StringRef label) const -> void { + mem_usage.Collect(MemUsage::ConcatLabel(label, "specifics_"), specifics_); mem_usage.Add(MemUsage::ConcatLabel(label, "lookup_table_"), lookup_table_, - KeyContext(generic_instances_.array_ref())); + KeyContext(specifics_.array_ref())); } -auto GetConstantInInstance(const File& sem_ir, GenericInstanceId instance_id, +auto GetConstantInSpecific(const File& sem_ir, SpecificId specific_id, ConstantId const_id) -> ConstantId { if (!const_id.is_symbolic()) { // Type does not depend on a generic parameter. @@ -62,43 +59,43 @@ auto GetConstantInInstance(const File& sem_ir, GenericInstanceId instance_id, const auto& symbolic = sem_ir.constant_values().GetSymbolicConstant(const_id); if (!symbolic.generic_id.is_valid()) { - // Constant is an abstract symbolic constant, not an instance-specific one. + // Constant is an abstract symbolic constant, not associated with some + // particular generic. return const_id; } - if (!instance_id.is_valid()) { - // TODO: We have a generic constant but no instance. Investigate whether we + if (!specific_id.is_valid()) { + // TODO: We have a generic constant but no specific. Investigate whether we // can CHECK-fail here. For now, produce the canonical value of the // constant. return sem_ir.constant_values().Get(symbolic.inst_id); } - const auto& specific = sem_ir.generic_instances().Get(instance_id); + const auto& specific = sem_ir.specifics().Get(specific_id); if (specific.generic_id != symbolic.generic_id) { - // TODO: Given an instance for the wrong generic. If the symbolic constant + // TODO: Given an specific for the wrong generic. If the symbolic constant // is from an enclosing generic, take the value from the corresponding - // instance. Otherwise, CHECK-fail. + // specific. Otherwise, CHECK-fail. return sem_ir.constant_values().Get(symbolic.inst_id); } auto value_block_id = specific.GetValueBlock(symbolic.index.region()); CARBON_CHECK(value_block_id.is_valid()) - << "Queried region of " << instance_id << " before it was resolved."; + << "Queried region of " << specific_id << " before it was resolved."; return sem_ir.constant_values().Get( sem_ir.inst_blocks().Get(value_block_id)[symbolic.index.index()]); } -auto GetConstantValueInInstance(const File& sem_ir, - GenericInstanceId instance_id, InstId inst_id) - -> ConstantId { - return GetConstantInInstance(sem_ir, instance_id, +auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id, + InstId inst_id) -> ConstantId { + return GetConstantInSpecific(sem_ir, specific_id, sem_ir.constant_values().Get(inst_id)); } -auto GetTypeInInstance(const File& sem_ir, GenericInstanceId instance_id, +auto GetTypeInSpecific(const File& sem_ir, SpecificId specific_id, TypeId type_id) -> TypeId { - return TypeId::ForTypeConstant(GetConstantInInstance( - sem_ir, instance_id, sem_ir.types().GetConstantId(type_id))); + return TypeId::ForTypeConstant(GetConstantInSpecific( + sem_ir, specific_id, sem_ir.types().GetConstantId(type_id))); } } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/generic.h b/toolchain/sem_ir/generic.h index af57c6dac5a3..6f37d7935b22 100644 --- a/toolchain/sem_ir/generic.h +++ b/toolchain/sem_ir/generic.h @@ -37,10 +37,10 @@ struct Generic : public Printable { // The index in this block will match the `bind_index` in the name binding // instruction's `EntityName`. InstBlockId bindings_id; - // The self instance of this generic, which is an instance where every generic - // parameter's argument is that same parameter. For example, the self instance + // The self specific of this generic, which is a specific where every generic + // parameter's argument is that same parameter. For example, the self specific // of `Vector(T:! type)` is `Vector(T)`. - GenericInstanceId self_instance_id; + SpecificId self_specific_id; // The following members are set at the end of the corresponding region of the // generic. @@ -54,19 +54,18 @@ struct Generic : public Printable { // Provides storage for generics. class GenericStore : public ValueStore { public: - // Get the self-instance for a generic, or an invalid instance for an invalid + // Get the self specific for a generic, or an invalid specific for an invalid // generic ID. - auto GetSelfInstance(GenericId id) -> GenericInstanceId { - return id.is_valid() ? Get(id).self_instance_id - : GenericInstanceId::Invalid; + auto GetSelfSpecific(GenericId id) -> SpecificId { + return id.is_valid() ? Get(id).self_specific_id : SpecificId::Invalid; } }; -// An instance of a generic entity, such as an instance of a generic function. -// For each construct that depends on a compile-time parameter in the generic -// entity, this contains the corresponding non-generic value. This includes +// A specific, which is the combination of a generic and specified generic +// arguments. For each construct that depends on a compile-time parameter in the +// generic entity, this contains the corresponding specific value. This includes // values for the compile-time parameters themselves. -struct GenericInstance : Printable { +struct Specific : Printable { auto Print(llvm::raw_ostream& out) const -> void { out << "{generic: " << generic_id << ", args: " << args_id << "}"; } @@ -82,7 +81,7 @@ struct GenericInstance : Printable { : definition_block_id; } - // The generic that this is an instance of. + // The generic that this is a specific version of. GenericId generic_id; // Argument values, corresponding to the bindings in `Generic::bindings_id`. InstBlockId args_id; @@ -96,64 +95,64 @@ struct GenericInstance : Printable { InstBlockId definition_block_id = InstBlockId::Invalid; }; -// Provides storage for deduplicated instances of generics. -class GenericInstanceStore : public Yaml::Printable { +// Provides storage for deduplicated specifics, which represent generics plus +// their associated generic argument list. +class SpecificStore : public Yaml::Printable { public: - // Adds a new generic instance, or gets the existing generic instance for a - // specified generic and argument list. Returns the ID of the generic - // instance. The argument IDs must be for instructions in the constant block, - // and must be a canonical instruction block ID. - auto GetOrAdd(GenericId generic_id, InstBlockId args_id) -> GenericInstanceId; + // Adds a new specific, or gets the existing specific for a specified generic + // and argument list. Returns the ID of the specific. The argument IDs must be + // for instructions in the constant block, and must be a canonical instruction + // block ID. + auto GetOrAdd(GenericId generic_id, InstBlockId args_id) -> SpecificId; - // Gets the specified generic instance. - auto Get(GenericInstanceId instance_id) const -> const GenericInstance& { - return generic_instances_.Get(instance_id); + // Gets the specific with the given ID. + auto Get(SpecificId specific_id) const -> const Specific& { + return specifics_.Get(specific_id); } - // Gets the specified generic instance. - auto Get(GenericInstanceId instance_id) -> GenericInstance& { - return generic_instances_.Get(instance_id); + // Gets the specific with the given ID. + auto Get(SpecificId specific_id) -> Specific& { + return specifics_.Get(specific_id); } // These are to support printable structures, and are not guaranteed. auto OutputYaml() const -> Yaml::OutputMapping { - return generic_instances_.OutputYaml(); + return specifics_.OutputYaml(); } // Collects memory usage of members. auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const -> void; - auto array_ref() const -> llvm::ArrayRef { - return generic_instances_.array_ref(); + auto array_ref() const -> llvm::ArrayRef { + return specifics_.array_ref(); } - auto size() const -> size_t { return generic_instances_.size(); } + auto size() const -> size_t { return specifics_.size(); } private: // Context for hashing keys. class KeyContext; - ValueStore generic_instances_; - Carbon::Set lookup_table_; + ValueStore specifics_; + Carbon::Set lookup_table_; }; -// Gets the substituted value of a constant within a specified instance of a -// generic. Note that this does not perform substitution, and will return +// Gets the substituted value of a potentially generic constant within a +// specific. Note that this does not perform substitution, and will return // `Invalid` if the substituted constant value is not yet known. -auto GetConstantInInstance(const File& sem_ir, GenericInstanceId instance_id, +auto GetConstantInSpecific(const File& sem_ir, SpecificId specific_id, ConstantId const_id) -> ConstantId; -// Gets the substituted constant value of an instruction within a specified -// instance of a generic. Note that this does not perform substitution, and will +// Gets the substituted constant value of a potentially generic instruction +// within a specific. Note that this does not perform substitution, and will // return `Invalid` if the substituted constant value is not yet known. -auto GetConstantValueInInstance(const File& sem_ir, - GenericInstanceId instance_id, InstId inst_id) - -> ConstantId; +auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id, + InstId inst_id) -> ConstantId; -// Gets the substituted value of a type within a specified instance of a -// generic. Note that this does not perform substitution, and will return -// `Invalid` if the substituted type is not yet known. -auto GetTypeInInstance(const File& sem_ir, GenericInstanceId instance_id, +// Gets the substituted value of a potentially generic type within a specific. +// Note that this does not perform substitution, and will return `Invalid` if +// the substituted type is not yet known. +auto GetTypeInSpecific(const File& sem_ir, SpecificId specific_id, TypeId type_id) -> TypeId; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/id_kind.h b/toolchain/sem_ir/id_kind.h index bfc13d1bfb7a..ba411440563b 100644 --- a/toolchain/sem_ir/id_kind.h +++ b/toolchain/sem_ir/id_kind.h @@ -121,9 +121,9 @@ using IdKind = TypeEnum< IntId, RealId, FloatId, StringLiteralValueId, // From sem_ir/id.h. InstId, ConstantId, EntityNameId, CompileTimeBindIndex, FunctionId, ClassId, - InterfaceId, ImplId, GenericId, GenericInstanceId, ImportIRId, - ImportIRInstId, LocId, BoolValue, IntKind, NameId, NameScopeId, InstBlockId, - TypeId, TypeBlockId, ElementIndex, FloatKind>; + InterfaceId, ImplId, GenericId, SpecificId, ImportIRId, ImportIRInstId, + LocId, BoolValue, IntKind, NameId, NameScopeId, InstBlockId, TypeId, + TypeBlockId, ElementIndex, FloatKind>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index dac42ca2bdf5..4c40cf49218e 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -22,7 +22,7 @@ struct EntityName; struct Class; struct Function; struct Generic; -struct GenericInstance; +struct Specific; struct ImportIR; struct ImportIRInst; struct Interface; @@ -319,27 +319,28 @@ struct GenericId : public IdBase, public Printable { constexpr GenericId GenericId::Invalid = GenericId(InvalidIndex); -// The ID of an instance of a generic. -struct GenericInstanceId : public IdBase, public Printable { - using ValueType = GenericInstance; +// The ID of a specific, which is the result of specifying the generic arguments +// for a generic. +struct SpecificId : public IdBase, public Printable { + using ValueType = Specific; // An explicitly invalid ID. This is typically used to represent a non-generic - // instance. - static const GenericInstanceId Invalid; + // entity. + static const SpecificId Invalid; using IdBase::IdBase; auto Print(llvm::raw_ostream& out) const -> void { - out << "genericInstance"; + out << "specific"; IdBase::Print(out); } }; -constexpr GenericInstanceId GenericInstanceId::Invalid = - GenericInstanceId(InvalidIndex); +constexpr SpecificId SpecificId::Invalid = SpecificId(InvalidIndex); // The index of an instruction that depends on generic parameters within a -// generic, and the value of that instruction within the instances of that -// generic. This is a pair of a region and an index, stored in 32 bits. +// region of a generic. A corresponding specific version of the instruction can +// be found in each specific corresponding to that generic. This is a pair of a +// region and an index, stored in 32 bits. struct GenericInstIndex : public IndexBase, public Printable { // Where the value is first used within the generic. enum Region : uint8_t { diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index f0b69501c1c8..2ede4f576a82 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -450,7 +450,7 @@ struct ClassInit { InstId dest_id; }; -// The type for a class, either non-generic or parameterized generic instance. +// The type for a class, either non-generic or specific. struct ClassType { static constexpr auto Kind = InstKind::ClassType.Define( {.ir_name = "class_type", @@ -459,7 +459,7 @@ struct ClassType { TypeId type_id; ClassId class_id; - GenericInstanceId instance_id; + SpecificId specific_id; }; // Indicates `const` on a type, such as `var x: const i32`. @@ -575,7 +575,7 @@ struct FunctionType { TypeId type_id; FunctionId function_id; - GenericInstanceId instance_id; + SpecificId specific_id; }; // The type of the name of a generic class. The corresponding value is an empty @@ -690,8 +690,7 @@ struct InterfaceDecl { InstBlockId decl_block_id; }; -// The type for an interface, either non-generic or parameterized generic -// instance. +// The type for an interface, either non-generic or specific. struct InterfaceType { static constexpr auto Kind = InstKind::InterfaceType.Define( {.ir_name = "interface_type", @@ -700,7 +699,7 @@ struct InterfaceType { TypeId type_id; InterfaceId interface_id; - GenericInstanceId instance_id; + SpecificId specific_id; }; // A witness that a type implements an interface. @@ -823,7 +822,7 @@ struct ReturnExpr { }; // Given an instruction with a constant value that depends on a generic -// parameter, selects an instance of that instruction with the constant value +// parameter, selects a version of that instruction with the constant value // corresponding to a particular specific. // // TODO: We only form these as the instruction referenced by a `NameRef`. @@ -835,7 +834,7 @@ struct SpecificConstant { TypeId type_id; InstId inst_id; - GenericInstanceId instance_id; + SpecificId specific_id; }; // Splices a block into the location where this appears. This may be an diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index 2de0e54f24ec..1846d6775c9e 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -62,7 +62,7 @@ TEST(SemIRTest, YAML) { Pair("functions", Yaml::Mapping(SizeIs(1))), Pair("classes", Yaml::Mapping(SizeIs(0))), Pair("generics", Yaml::Mapping(SizeIs(0))), - Pair("generic_instances", Yaml::Mapping(SizeIs(0))), + Pair("specifics", Yaml::Mapping(SizeIs(0))), Pair("types", Yaml::Mapping(Each(type_builtin))), Pair("type_blocks", Yaml::Mapping(SizeIs(Ge(1)))), Pair("insts",