From be56ff87c659b080b43c710667c2d6cb6917e105 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 6 Nov 2024 13:38:27 -0800 Subject: [PATCH] Convert StructTypeField to a specific type. (#4492) This converts `StructTypeField` from an instruction to a dedicated type, with its own store. This had originated from discussing how `.GetAs` was more prevalent than for other instructions, but is probably more interesting for the storage savings (16 bytes StructTypeField + 4 byte LocId + 4 byte InstId -> 8 byte StructTypeField). Due to the different structure, these now have their own stack during construction, reducing (but not eliminating) `args_type_info_stack_` use-cases. The test changes of different InstIds is expected because structs and classes generate fewer instructions now. Other than that, results should remain the same. I'm generally trying to avoid unrelated cleanup here due to the PR size, though I did scrutinize the `VerifyOnFinish` calls, adding one and commenting others (putting them in member order because that's how I was checking what was verified and what wasn't). --- common/array_stack.h | 3 + toolchain/check/context.cpp | 45 +++--- toolchain/check/context.h | 16 +- toolchain/check/convert.cpp | 29 ++-- toolchain/check/eval.cpp | 33 ++++- toolchain/check/handle_binding_pattern.cpp | 11 +- toolchain/check/handle_class.cpp | 46 +++--- toolchain/check/handle_struct.cpp | 138 +++++++++++------- toolchain/check/import_ref.cpp | 29 ++-- toolchain/check/inst_block_stack.h | 7 - toolchain/check/member_access.cpp | 7 +- toolchain/check/node_stack.h | 2 +- toolchain/check/subst.cpp | 19 +++ .../alias/no_prelude/import_order.carbon | 8 +- .../testdata/basics/builtin_insts.carbon | 1 + .../multifile_raw_and_textual_ir.carbon | 2 + .../basics/no_prelude/multifile_raw_ir.carbon | 2 + .../no_prelude/raw_and_textual_ir.carbon | 1 + .../testdata/basics/no_prelude/raw_ir.carbon | 1 + .../testdata/class/generic/import.carbon | 14 +- toolchain/check/testdata/class/import.carbon | 18 +-- .../check/testdata/class/import_base.carbon | 8 +- .../testdata/class/import_struct_cyle.carbon | 4 +- .../function/declaration/import.carbon | 68 ++++----- .../function/definition/import.carbon | 12 +- .../interface/no_prelude/import.carbon | 2 +- .../packages/fail_import_type_error.carbon | 6 +- .../no_prelude/cross_package_export.carbon | 36 ++--- .../packages/no_prelude/export_import.carbon | 2 +- .../packages/no_prelude/export_mixed.carbon | 46 +++--- .../packages/no_prelude/export_name.carbon | 102 ++++++------- .../no_prelude/import_convert_function.carbon | 52 +++---- toolchain/check/testdata/struct/import.carbon | 30 ++-- toolchain/lower/constant.cpp | 7 - toolchain/lower/file_context.cpp | 8 +- toolchain/lower/handle_aggregates.cpp | 18 +-- toolchain/sem_ir/BUILD | 1 + toolchain/sem_ir/copy_on_write_block.h | 2 + toolchain/sem_ir/file.cpp | 4 +- toolchain/sem_ir/file.h | 10 ++ toolchain/sem_ir/formatter.cpp | 16 +- toolchain/sem_ir/id_kind.h | 5 +- toolchain/sem_ir/ids.h | 20 +++ toolchain/sem_ir/inst_kind.def | 1 - toolchain/sem_ir/stringify_type.cpp | 22 ++- toolchain/sem_ir/struct_type_field.h | 39 +++++ toolchain/sem_ir/typed_insts.h | 17 +-- toolchain/sem_ir/yaml_test.cpp | 1 + 48 files changed, 535 insertions(+), 436 deletions(-) create mode 100644 toolchain/sem_ir/struct_type_field.h diff --git a/common/array_stack.h b/common/array_stack.h index 4aee5ec8a88f..9021c8a4bdb5 100644 --- a/common/array_stack.h +++ b/common/array_stack.h @@ -84,6 +84,9 @@ class ArrayStack { // Returns the current number of values in all arrays. auto all_values_size() const -> size_t { return values_.size(); } + // Returns true if the stack has no arrays pushed. + auto empty() const -> bool { return array_offsets_.empty(); } + private: // For each pushed array, the start index in elements_. llvm::SmallVector array_offsets_; diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index e4d4a4b600b7..219ed62b1e59 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -82,10 +82,15 @@ auto Context::VerifyOnFinish() -> void { // various pieces of context go out of scope. At this point, nothing should // remain. // node_stack_ will still contain top-level entities. - scope_stack_.VerifyOnFinish(); inst_block_stack_.VerifyOnFinish(); pattern_block_stack_.VerifyOnFinish(); param_and_arg_refs_stack_.VerifyOnFinish(); + args_type_info_stack_.VerifyOnFinish(); + CARBON_CHECK(struct_type_fields_stack_.empty()); + // TODO: Add verification for decl_name_stack_ and + // decl_introducer_state_stack_. + scope_stack_.VerifyOnFinish(); + // TODO: Add verification for generic_region_stack_. } auto Context::GetOrAddInst(SemIR::LocIdAndInst loc_id_and_inst) @@ -847,10 +852,8 @@ class TypeCompleter { break; } case CARBON_KIND(SemIR::StructType inst): { - for (auto field_id : context_.inst_blocks().Get(inst.fields_id)) { - Push(context_.insts() - .GetAs(field_id) - .field_type_id); + for (auto field : context_.struct_type_fields().Get(inst.fields_id)) { + Push(field.type_id); } break; } @@ -981,33 +984,30 @@ class TypeCompleter { auto BuildValueReprForInst(SemIR::TypeId type_id, SemIR::StructType struct_type) const -> SemIR::ValueRepr { - // TODO: Share more code with tuples. - auto fields = context_.inst_blocks().Get(struct_type.fields_id); + auto fields = context_.struct_type_fields().Get(struct_type.fields_id); if (fields.empty()) { return MakeEmptyValueRepr(); } // Find the value representation for each field, and construct a struct // of value representations. - llvm::SmallVector value_rep_fields; + llvm::SmallVector value_rep_fields; value_rep_fields.reserve(fields.size()); bool same_as_object_rep = true; - for (auto field_id : fields) { - auto field = context_.insts().GetAs(field_id); - auto field_value_rep = GetNestedValueRepr(field.field_type_id); - if (field_value_rep.type_id != field.field_type_id) { + for (auto field : fields) { + auto field_value_rep = GetNestedValueRepr(field.type_id); + if (field_value_rep.type_id != field.type_id) { same_as_object_rep = false; - field.field_type_id = field_value_rep.type_id; - field_id = context_.constant_values().GetInstId( - TryEvalInst(context_, SemIR::InstId::Invalid, field)); + field.type_id = field_value_rep.type_id; } - value_rep_fields.push_back(field_id); + value_rep_fields.push_back(field); } - auto value_rep = same_as_object_rep - ? type_id - : context_.GetStructType( - context_.inst_blocks().Add(value_rep_fields)); + auto value_rep = + same_as_object_rep + ? type_id + : context_.GetStructType( + context_.struct_type_fields().AddCanonical(value_rep_fields)); return BuildStructOrTupleValueRepr(fields.size(), value_rep, same_as_object_rep); } @@ -1243,8 +1243,9 @@ static auto GetCompleteTypeImpl(Context& context, EachArgT... each_arg) return type_id; } -auto Context::GetStructType(SemIR::InstBlockId refs_id) -> SemIR::TypeId { - return GetTypeImpl(*this, refs_id); +auto Context::GetStructType(SemIR::StructTypeFieldsId fields_id) + -> SemIR::TypeId { + return GetTypeImpl(*this, fields_id); } auto Context::GetTupleType(llvm::ArrayRef type_ids) diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 07bd650ec952..917f48cd24c6 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -394,9 +394,8 @@ class Context { // Returns a pointer type whose pointee type is `pointee_type_id`. auto GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId; - // Returns a struct type with the given fields, which should be a block of - // `StructTypeField`s. - auto GetStructType(SemIR::InstBlockId refs_id) -> SemIR::TypeId; + // Returns a struct type with the given fields. + auto GetStructType(SemIR::StructTypeFieldsId fields_id) -> SemIR::TypeId; // Returns a tuple type with the given element types. auto GetTupleType(llvm::ArrayRef type_ids) -> SemIR::TypeId; @@ -467,6 +466,10 @@ class Context { return args_type_info_stack_; } + auto struct_type_fields_stack() -> ArrayStack& { + return struct_type_fields_stack_; + } + auto decl_name_stack() -> DeclNameStack& { return decl_name_stack_; } auto decl_introducer_state_stack() -> DeclIntroducerStateStack& { @@ -527,6 +530,9 @@ class Context { auto name_scopes() -> SemIR::NameScopeStore& { return sem_ir().name_scopes(); } + auto struct_type_fields() -> SemIR::StructTypeFieldsStore& { + return sem_ir().struct_type_fields(); + } auto types() -> SemIR::TypeStore& { return sem_ir().types(); } auto type_blocks() -> SemIR::BlockValueStore& { return sem_ir().type_blocks(); @@ -613,6 +619,10 @@ class Context { // arguments. InstBlockStack args_type_info_stack_; + // The stack of StructTypeFields for in-progress StructTypeLiterals and Class + // object representations. + ArrayStack struct_type_fields_stack_; + // The stack used for qualified declaration name construction. DeclNameStack decl_name_stack_; diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 64386c37b7e5..0772a39af09f 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -390,13 +390,10 @@ static auto ConvertStructToStructOrClass(Context& context, std::is_same_v; auto& sem_ir = context.sem_ir(); - auto src_elem_fields = sem_ir.inst_blocks().Get(src_type.fields_id); - auto dest_elem_fields = sem_ir.inst_blocks().Get(dest_type.fields_id); - bool dest_has_vptr = - !dest_elem_fields.empty() && - sem_ir.insts() - .GetAs(dest_elem_fields.front()) - .name_id == SemIR::NameId::Vptr; + auto src_elem_fields = sem_ir.struct_type_fields().Get(src_type.fields_id); + auto dest_elem_fields = sem_ir.struct_type_fields().Get(dest_type.fields_id); + bool dest_has_vptr = !dest_elem_fields.empty() && + dest_elem_fields.front().name_id == SemIR::NameId::Vptr; auto dest_elem_fields_size = dest_elem_fields.size() - dest_has_vptr; auto value = sem_ir.insts().Get(value_id); @@ -432,9 +429,8 @@ static auto ConvertStructToStructOrClass(Context& context, // Prepare to look up fields in the source by index. Map src_field_indexes; if (src_type.fields_id != dest_type.fields_id) { - for (auto [i, field_id] : llvm::enumerate(src_elem_fields)) { - auto result = src_field_indexes.Insert( - context.insts().GetAs(field_id).name_id, i); + for (auto [i, field] : llvm::enumerate(src_elem_fields)) { + auto result = src_field_indexes.Insert(field.name_id, i); CARBON_CHECK(result.is_inserted(), "Duplicate field in source structure"); } } @@ -460,9 +456,7 @@ static auto ConvertStructToStructOrClass(Context& context, : SemIR::CopyOnWriteInstBlock( sem_ir, SemIR::CopyOnWriteInstBlock::UninitializedBlock{ dest_elem_fields.size()}); - for (auto [i, dest_field_id] : llvm::enumerate(dest_elem_fields)) { - auto dest_field = - sem_ir.insts().GetAs(dest_field_id); + for (auto [i, dest_field] : llvm::enumerate(dest_elem_fields)) { if (dest_field.name_id == SemIR::NameId::Vptr) { // TODO: Initialize the vptr to point to a vtable. new_block.Set(i, SemIR::InstId::BuiltinError); @@ -494,16 +488,15 @@ static auto ConvertStructToStructOrClass(Context& context, return SemIR::InstId::BuiltinError; } } - auto src_field = sem_ir.insts().GetAs( - src_elem_fields[src_field_index]); + auto src_field = src_elem_fields[src_field_index]; // TODO: This call recurses back into conversion. Switch to an iterative // approach. auto init_id = ConvertAggregateElement( - context, value_loc_id, value_id, src_field.field_type_id, - literal_elems, inner_kind, target.init_id, dest_field.field_type_id, - target.init_block, src_field_index); + context, value_loc_id, value_id, src_field.type_id, literal_elems, + inner_kind, target.init_id, dest_field.type_id, target.init_block, + src_field_index); if (init_id == SemIR::InstId::BuiltinError) { return SemIR::InstId::BuiltinError; } diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 9fb9d902789d..7cfcf592ed06 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -310,6 +310,36 @@ static auto GetConstantValue(EvalContext& eval_context, return eval_context.inst_blocks().AddCanonical(const_insts); } +// Compute the constant value of a type block. This may be different from the +// input type block if we have known generic arguments. +static auto GetConstantValue(EvalContext& eval_context, + SemIR::StructTypeFieldsId fields_id, Phase* phase) + -> SemIR::StructTypeFieldsId { + if (!fields_id.is_valid()) { + return SemIR::StructTypeFieldsId::Invalid; + } + auto fields = eval_context.context().struct_type_fields().Get(fields_id); + llvm::SmallVector new_fields; + for (auto field : fields) { + auto new_type_id = GetConstantValue(eval_context, field.type_id, phase); + if (!new_type_id.is_valid()) { + return SemIR::StructTypeFieldsId::Invalid; + } + + // Once we leave the small buffer, we know the first few elements are all + // constant, so it's likely that the entire block is constant. Resize to the + // target size given that we're going to allocate memory now anyway. + if (new_fields.size() == new_fields.capacity()) { + new_fields.reserve(fields.size()); + } + + new_fields.push_back({.name_id = field.name_id, .type_id = new_type_id}); + } + // TODO: If the new block is identical to the original block, and we know the + // old ID was canonical, return the original ID. + return eval_context.context().struct_type_fields().AddCanonical(new_fields); +} + // Compute the constant value of a type block. This may be different from the // input type block if we have known generic arguments. static auto GetConstantValue(EvalContext& eval_context, @@ -1235,9 +1265,6 @@ static auto TryEvalInstInContext(EvalContext& eval_context, case SemIR::StructType::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, &SemIR::StructType::fields_id); - case SemIR::StructTypeField::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::StructTypeField::field_type_id); case SemIR::StructValue::Kind: return RebuildIfFieldsAreConstant(eval_context, inst, &SemIR::StructValue::type_id, diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index c1e9715b7d96..90885e1b026d 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -131,15 +131,12 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, binding_id, {.type_id = field_type_id, .name_id = name_id, - .index = SemIR::ElementIndex(context.args_type_info_stack() - .PeekCurrentBlockContents() - .size())}); + .index = SemIR::ElementIndex( + context.struct_type_fields_stack().PeekArray().size())}); // Add a corresponding field to the object representation of the class. - context.args_type_info_stack().AddInstId( - context.AddInstInNoBlock( - binding_id, - {.name_id = name_id, .field_type_id = cast_type_id})); + context.struct_type_fields_stack().AppendToTop( + {.name_id = name_id, .type_id = cast_type_id}); context.node_stack().Push(node_id, field_id); break; } diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index fd68f2efd27a..f0ef56f0f9a5 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -295,7 +295,7 @@ auto HandleParseNode(Context& context, Parse::ClassDefinitionStartId node_id) context.inst_block_stack().Push(); context.node_stack().Push(node_id, class_id); - context.args_type_info_stack().Push(); + context.struct_type_fields_stack().PushArray(); // TODO: Handle the case where there's control flow in the class body. For // example: @@ -533,11 +533,10 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { auto field_type_id = context.GetUnboundElementType(class_info.self_type_id, base_info.type_id); class_info.base_id = context.AddInst( - node_id, - {.type_id = field_type_id, - .base_type_id = base_info.type_id, - .index = SemIR::ElementIndex( - context.args_type_info_stack().PeekCurrentBlockContents().size())}); + node_id, {.type_id = field_type_id, + .base_type_id = base_info.type_id, + .index = SemIR::ElementIndex( + context.struct_type_fields_stack().PeekArray().size())}); if (base_info.type_id != SemIR::TypeId::Error) { auto base_class_info = context.classes().Get( @@ -548,10 +547,8 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { // Add a corresponding field to the object representation of the class. // TODO: Consider whether we want to use `partial T` here. // TODO: Should we diagnose if there are already any fields? - context.args_type_info_stack().AddInstId( - context.AddInstInNoBlock( - node_id, {.name_id = SemIR::NameId::Base, - .field_type_id = base_info.type_id})); + context.struct_type_fields_stack().AppendToTop( + {.name_id = SemIR::NameId::Base, .type_id = base_info.type_id}); // Bind the name `base` in the class to the base field. context.decl_name_stack().AddNameOrDiagnoseDuplicate( @@ -576,7 +573,7 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool { static auto CheckCompleteAdapterClassType(Context& context, Parse::NodeId node_id, SemIR::ClassId class_id, - SemIR::InstBlockId fields_id) + SemIR::StructTypeFieldsId fields_id) -> SemIR::InstId { const auto& class_info = context.classes().Get(class_id); if (class_info.base_id.is_valid()) { @@ -589,14 +586,17 @@ static auto CheckCompleteAdapterClassType(Context& context, return SemIR::InstId::BuiltinError; } - if (!context.inst_blocks().Get(fields_id).empty()) { - auto first_field_id = context.inst_blocks().Get(fields_id).front(); + if (auto fields = context.struct_type_fields().Get(fields_id); + !fields.empty()) { + auto [first_field_inst_id, _] = context.LookupNameInExactScope( + node_id, fields.front().name_id, class_info.scope_id, + context.name_scopes().Get(class_info.scope_id)); CARBON_DIAGNOSTIC(AdaptWithFields, Error, "adapter with fields"); CARBON_DIAGNOSTIC(AdaptWithFieldHere, Note, "first field declaration is here"); context.emitter() .Build(class_info.adapt_id, AdaptWithFields) - .Note(first_field_id, AdaptWithFieldHere) + .Note(first_field_inst_id, AdaptWithFieldHere) .Emit(); return SemIR::InstId::BuiltinError; } @@ -649,7 +649,9 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, SemIR::ClassId class_id) -> SemIR::InstId { auto& class_info = context.classes().Get(class_id); if (class_info.adapt_id.is_valid()) { - auto fields_id = context.args_type_info_stack().Pop(); + auto fields_id = context.struct_type_fields().AddCanonical( + context.struct_type_fields_stack().PeekArray()); + context.struct_type_fields_stack().PopArray(); return CheckCompleteAdapterClassType(context, node_id, class_id, fields_id); } @@ -666,15 +668,15 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, } if (defining_vtable_ptr) { - context.args_type_info_stack().AddFrontInstId( - context.AddInstInNoBlock( - Parse::NodeId::Invalid, - {.name_id = SemIR::NameId::Vptr, - .field_type_id = context.GetPointerType( - context.GetBuiltinType(SemIR::BuiltinInstKind::VtableType))})); + context.struct_type_fields_stack().PrependToTop( + {.name_id = SemIR::NameId::Vptr, + .type_id = context.GetPointerType( + context.GetBuiltinType(SemIR::BuiltinInstKind::VtableType))}); } - auto fields_id = context.args_type_info_stack().Pop(); + auto fields_id = context.struct_type_fields().AddCanonical( + context.struct_type_fields_stack().PeekArray()); + context.struct_type_fields_stack().PopArray(); return context.AddInst( node_id, diff --git a/toolchain/check/handle_struct.cpp b/toolchain/check/handle_struct.cpp index 657068319de9..6579d06680cd 100644 --- a/toolchain/check/handle_struct.cpp +++ b/toolchain/check/handle_struct.cpp @@ -10,23 +10,23 @@ namespace Carbon::Check { -auto HandleParseNode(Context& context, Parse::StructTypeLiteralStartId node_id) - -> bool { - context.scope_stack().Push(); - context.node_stack().Push(node_id); - context.param_and_arg_refs_stack().Push(); - return true; -} - auto HandleParseNode(Context& context, Parse::StructLiteralStartId node_id) -> bool { context.scope_stack().Push(); context.node_stack().Push(node_id); - context.args_type_info_stack().Push(); + context.struct_type_fields_stack().PushArray(); context.param_and_arg_refs_stack().Push(); return true; } +auto HandleParseNode(Context& context, Parse::StructTypeLiteralStartId node_id) + -> bool { + context.scope_stack().Push(); + context.node_stack().Push(node_id); + context.struct_type_fields_stack().PushArray(); + return true; +} + auto HandleParseNode(Context& context, Parse::StructFieldDesignatorId /*node_id*/) -> bool { // This leaves the designated name on top because the `.` isn't interesting. @@ -40,52 +40,47 @@ auto HandleParseNode(Context& context, Parse::StructLiteralCommaId /*node_id*/) return true; } -auto HandleParseNode(Context& context, +auto HandleParseNode(Context& /*context*/, Parse::StructTypeLiteralCommaId /*node_id*/) -> bool { - context.param_and_arg_refs_stack().ApplyComma(); return true; } auto HandleParseNode(Context& context, Parse::StructLiteralFieldId node_id) -> bool { auto value_inst_id = context.node_stack().PopExpr(); - auto [name_node, name_id] = context.node_stack().PopNameWithNodeId(); + // Get the name while leaving it on the stack. + auto name_id = context.node_stack().Peek(); // Store the name for the type. - context.args_type_info_stack().AddInstId( - context.AddInstInNoBlock( - name_node, - {.name_id = name_id, - .field_type_id = context.insts().Get(value_inst_id).type_id()})); + auto value_type_id = context.insts().Get(value_inst_id).type_id(); + context.struct_type_fields_stack().AppendToTop( + {.name_id = name_id, .type_id = value_type_id}); // Push the value back on the stack as an argument. context.node_stack().Push(node_id, value_inst_id); return true; } -auto HandleParseNode(Context& context, Parse::StructTypeLiteralFieldId node_id) - -> bool { +auto HandleParseNode(Context& context, + Parse::StructTypeLiteralFieldId /*node_id*/) -> bool { auto [type_node, type_id] = context.node_stack().PopExprWithNodeId(); SemIR::TypeId cast_type_id = ExprAsType(context, type_node, type_id).type_id; + // Get the name while leaving it on the stack. + auto name_id = context.node_stack().Peek(); - auto [name_node, name_id] = context.node_stack().PopNameWithNodeId(); - - auto inst_id = context.AddInst( - name_node, {.name_id = name_id, .field_type_id = cast_type_id}); - context.node_stack().Push(node_id, inst_id); + context.struct_type_fields_stack().AppendToTop( + {.name_id = name_id, .type_id = cast_type_id}); return true; } -static auto DiagnoseDuplicateNames(Context& context, - SemIR::InstBlockId type_block_id, - bool is_struct_type_literal) -> bool { - auto& sem_ir = context.sem_ir(); - auto fields = sem_ir.inst_blocks().Get(type_block_id); - Map names; - auto& insts = sem_ir.insts(); - for (SemIR::InstId field_inst_id : fields) { - auto field_inst = insts.GetAs(field_inst_id); - auto result = names.Insert(field_inst.name_id, field_inst_id); +// Diagnoses and returns true if there's a duplicate name. +static auto DiagnoseDuplicateNames( + Context& context, llvm::ArrayRef field_name_nodes, + llvm::ArrayRef fields, bool is_struct_type_literal) + -> bool { + Map names; + for (auto [field_name_node, field] : llvm::zip(field_name_nodes, fields)) { + auto result = names.Insert(field.name_id, field_name_node); if (!result.is_inserted()) { CARBON_DIAGNOSTIC(StructNameDuplicate, Error, "duplicated field name `{1}` in " @@ -94,9 +89,9 @@ static auto DiagnoseDuplicateNames(Context& context, CARBON_DIAGNOSTIC(StructNamePrevious, Note, "field with the same name here"); context.emitter() - .Build(field_inst_id, StructNameDuplicate, is_struct_type_literal, - field_inst.name_id) - .Note(result.value(), StructNamePrevious) + .Build(result.value(), StructNameDuplicate, is_struct_type_literal, + field.name_id) + .Note(field_name_node, StructNamePrevious) .Emit(); return true; } @@ -104,47 +99,80 @@ static auto DiagnoseDuplicateNames(Context& context, return false; } +// Pops the names of each field from the stack. These will have been left while +// handling struct fields. +static auto PopFieldNameNodes(Context& context, size_t field_count) + -> llvm::SmallVector { + llvm::SmallVector nodes; + nodes.reserve(field_count); + while (true) { + auto [name_node, _] = + context.node_stack().PopWithNodeIdIf(); + if (name_node.is_valid()) { + nodes.push_back(name_node); + } else { + break; + } + } + CARBON_CHECK(nodes.size() == field_count, "Found {0} names, expected {1}", + nodes.size(), field_count); + return nodes; +} + auto HandleParseNode(Context& context, Parse::StructLiteralId node_id) -> bool { - auto refs_id = context.param_and_arg_refs_stack().EndAndPop( + if (!context.node_stack().PeekIs(Parse::NodeCategory::MemberName)) { + // Remove the last parameter from the node stack before collecting names. + context.param_and_arg_refs_stack().EndNoPop( + Parse::NodeKind::StructLiteralStart); + } + + auto fields = context.struct_type_fields_stack().PeekArray(); + llvm::SmallVector field_name_nodes = + PopFieldNameNodes(context, fields.size()); + + auto elements_id = context.param_and_arg_refs_stack().EndAndPop( Parse::NodeKind::StructLiteralStart); context.scope_stack().Pop(); context.node_stack() .PopAndDiscardSoloNodeId(); - auto type_block_id = context.args_type_info_stack().Pop(); - if (DiagnoseDuplicateNames(context, type_block_id, + + if (DiagnoseDuplicateNames(context, field_name_nodes, fields, /*is_struct_type_literal=*/false)) { context.node_stack().Push(node_id, SemIR::InstId::BuiltinError); - return true; + } else { + auto type_id = context.GetStructType( + context.struct_type_fields().AddCanonical(fields)); + + auto value_id = context.AddInst( + node_id, {.type_id = type_id, .elements_id = elements_id}); + context.node_stack().Push(node_id, value_id); } - auto type_id = context.GetStructType(type_block_id); - - auto value_id = context.AddInst( - node_id, {.type_id = type_id, .elements_id = refs_id}); - context.node_stack().Push(node_id, value_id); + context.struct_type_fields_stack().PopArray(); return true; } auto HandleParseNode(Context& context, Parse::StructTypeLiteralId node_id) -> bool { - auto refs_id = context.param_and_arg_refs_stack().EndAndPop( - Parse::NodeKind::StructTypeLiteralStart); + auto fields = context.struct_type_fields_stack().PeekArray(); + llvm::SmallVector field_name_nodes = + PopFieldNameNodes(context, fields.size()); context.scope_stack().Pop(); context.node_stack() .PopAndDiscardSoloNodeId(); - CARBON_CHECK(refs_id != SemIR::InstBlockId::Empty, - "{{}} is handled by StructLiteral."); - - if (DiagnoseDuplicateNames(context, refs_id, + if (DiagnoseDuplicateNames(context, field_name_nodes, fields, /*is_struct_type_literal=*/true)) { context.node_stack().Push(node_id, SemIR::InstId::BuiltinError); - return true; + } else { + auto fields_id = context.struct_type_fields().AddCanonical(fields); + context.AddInstAndPush( + node_id, {.type_id = SemIR::TypeId::TypeType, .fields_id = fields_id}); } - context.AddInstAndPush( - node_id, {.type_id = SemIR::TypeId::TypeType, .fields_id = refs_id}); + + context.struct_type_fields_stack().PopArray(); return true; } diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index eb44bf103078..13830e9ce604 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -1233,7 +1233,7 @@ class ImportRefResolver { return TryResolveTypedInst(inst); } case CARBON_KIND(SemIR::StructType inst): { - return TryResolveTypedInst(inst, inst_id); + return TryResolveTypedInst(inst); } case CARBON_KIND(SemIR::StructValue inst): { return TryResolveTypedInst(inst); @@ -2147,38 +2147,31 @@ class ImportRefResolver { .specific_id = specific_id}); } - auto TryResolveTypedInst(SemIR::StructType inst, SemIR::InstId import_inst_id) - -> ResolveResult { + auto TryResolveTypedInst(SemIR::StructType inst) -> ResolveResult { CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType); - auto orig_fields = import_ir_.inst_blocks().Get(inst.fields_id); + auto orig_fields = import_ir_.struct_type_fields().Get(inst.fields_id); llvm::SmallVector field_const_ids; field_const_ids.reserve(orig_fields.size()); - for (auto field_id : orig_fields) { - auto field = import_ir_.insts().GetAs(field_id); - field_const_ids.push_back(GetLocalConstantId(field.field_type_id)); + for (auto field : orig_fields) { + field_const_ids.push_back(GetLocalConstantId(field.type_id)); } if (HasNewWork()) { return Retry(); } // Prepare a vector of fields for GetStructType. - // TODO: Should we have field constants so that we can deduplicate fields - // without creating instructions here? - llvm::SmallVector fields; - fields.reserve(orig_fields.size()); - for (auto [field_id, field_const_id] : + llvm::SmallVector new_fields; + new_fields.reserve(orig_fields.size()); + for (auto [orig_field, field_const_id] : llvm::zip(orig_fields, field_const_ids)) { - auto field = import_ir_.insts().GetAs(field_id); - auto name_id = GetLocalNameId(field.name_id); + auto name_id = GetLocalNameId(orig_field.name_id); auto field_type_id = context_.GetTypeIdForTypeConstant(field_const_id); - fields.push_back(context_.AddInstInNoBlock( - AddImportIRInst(import_inst_id), - {.name_id = name_id, .field_type_id = field_type_id})); + new_fields.push_back({.name_id = name_id, .type_id = field_type_id}); } return ResolveAs( {.type_id = SemIR::TypeId::TypeType, - .fields_id = context_.inst_blocks().AddCanonical(fields)}); + .fields_id = context_.struct_type_fields().AddCanonical(new_fields)}); } auto TryResolveTypedInst(SemIR::StructValue inst) -> ResolveResult { diff --git a/toolchain/check/inst_block_stack.h b/toolchain/check/inst_block_stack.h index fab55c51e4e6..df718a099a92 100644 --- a/toolchain/check/inst_block_stack.h +++ b/toolchain/check/inst_block_stack.h @@ -58,13 +58,6 @@ class InstBlockStack { insts_stack_.AppendToTop(inst_id); } - // Adds the given instruction ID to the front of the block at the top of the - // stack. - auto AddFrontInstId(SemIR::InstId inst_id) -> void { - CARBON_CHECK(!empty(), "no current block"); - insts_stack_.PrependToTop(inst_id); - } - // Returns whether the current block is statically reachable. auto is_current_block_reachable() -> bool { return id_stack_.back() != SemIR::InstBlockId::Unreachable; diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 4f1879d71631..d0f1fba34dca 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -405,14 +405,13 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, if (auto struct_type = context.insts().TryGetAs( context.constant_values().GetInstId(base_type_const_id))) { // TODO: Do we need to optimize this with a lookup table for O(1)? - for (auto [i, ref_id] : - llvm::enumerate(context.inst_blocks().Get(struct_type->fields_id))) { - auto field = context.insts().GetAs(ref_id); + for (auto [i, field] : llvm::enumerate( + context.struct_type_fields().Get(struct_type->fields_id))) { if (name_id == field.name_id) { // TODO: Model this as producing a lookup result, and do instance // binding separately. Perhaps a struct type should be a name scope. return context.GetOrAddInst( - loc_id, {.type_id = field.field_type_id, + loc_id, {.type_id = field.type_id, .struct_id = base_id, .index = SemIR::ElementIndex(i)}); } diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 6a5642925d60..86aae588c8ea 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -424,7 +424,6 @@ class NodeStack { case Parse::NodeKind::ShortCircuitOperandAnd: case Parse::NodeKind::ShortCircuitOperandOr: case Parse::NodeKind::StructLiteralField: - case Parse::NodeKind::StructTypeLiteralField: case Parse::NodeKind::WhereOperand: return Id::KindFor(); case Parse::NodeKind::IfCondition: @@ -465,6 +464,7 @@ class NodeStack { case Parse::NodeKind::ReturnStatementStart: case Parse::NodeKind::ReturnVarModifier: case Parse::NodeKind::StructLiteralStart: + case Parse::NodeKind::StructTypeLiteralField: case Parse::NodeKind::StructTypeLiteralStart: case Parse::NodeKind::TupleLiteralStart: case Parse::NodeKind::TuplePatternStart: diff --git a/toolchain/check/subst.cpp b/toolchain/check/subst.cpp index ecb3555352bf..d33439c63ebd 100644 --- a/toolchain/check/subst.cpp +++ b/toolchain/check/subst.cpp @@ -77,6 +77,13 @@ static auto PushOperand(Context& context, Worklist& worklist, worklist.Push(inst_id); } break; + case SemIR::IdKind::For: { + for (auto field : + context.struct_type_fields().Get(SemIR::StructTypeFieldsId(arg))) { + worklist.Push(context.types().GetInstId(field.type_id)); + } + break; + } case SemIR::IdKind::For: for (auto type_id : context.type_blocks().Get(SemIR::TypeBlockId(arg))) { worklist.Push(context.types().GetInstId(type_id)); @@ -134,6 +141,18 @@ static auto PopOperand(Context& context, Worklist& worklist, SemIR::IdKind kind, } return new_inst_block.GetCanonical().index; } + case SemIR::IdKind::For: { + SemIR::StructTypeFieldsId old_fields_id(arg); + auto old_fields = context.struct_type_fields().Get(old_fields_id); + SemIR::CopyOnWriteStructTypeFieldsBlock new_fields(context.sem_ir(), + old_fields_id); + for (auto i : llvm::reverse(llvm::seq(old_fields.size()))) { + new_fields.Set( + i, {.name_id = old_fields[i].name_id, + .type_id = context.GetTypeIdForTypeInst(worklist.Pop())}); + } + return new_fields.GetCanonical().index; + } case SemIR::IdKind::For: { SemIR::TypeBlockId old_type_block_id(arg); auto size = context.type_blocks().Get(old_type_block_id).size(); diff --git a/toolchain/check/testdata/alias/no_prelude/import_order.carbon b/toolchain/check/testdata/alias/no_prelude/import_order.carbon index e35dacc3a446..d27b79c95d6b 100644 --- a/toolchain/check/testdata/alias/no_prelude/import_order.carbon +++ b/toolchain/check/testdata/alias/no_prelude/import_order.carbon @@ -85,10 +85,10 @@ var a_val: a = {.v = b_val.v}; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//a, inst+1, unloaded -// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+14, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+16, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+18, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.5: type = import_ref Main//a, inst+20, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+12, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+14, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+16, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.5: type = import_ref Main//a, inst+18, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.6 = import_ref Main//a, inst+2, unloaded // CHECK:STDOUT: %import_ref.7: %.5 = import_ref Main//a, inst+7, loaded [template = %.1] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/basics/builtin_insts.carbon b/toolchain/check/testdata/basics/builtin_insts.carbon index 31311bdef1da..fe8ca5f9c39d 100644 --- a/toolchain/check/testdata/basics/builtin_insts.carbon +++ b/toolchain/check/testdata/basics/builtin_insts.carbon @@ -23,6 +23,7 @@ // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // 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 c303f2064eb9..197d9f648c00 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 @@ -40,6 +40,7 @@ fn B() { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -115,6 +116,7 @@ fn B() { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // 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_ir.carbon b/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon index e616c9bffae6..1205d7423a62 100644 --- a/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon @@ -40,6 +40,7 @@ fn B() { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} @@ -94,6 +95,7 @@ fn B() { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // 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/raw_and_textual_ir.carbon b/toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon index a05b64bc3be0..21cf677df4e2 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 @@ -31,6 +31,7 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: classes: {} // CHECK:STDOUT: generics: {} // CHECK:STDOUT: specifics: {} +// CHECK:STDOUT: struct_type_fields: {} // 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/raw_ir.carbon b/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon index 8e73cc822a33..b08453e7564a 100644 --- a/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon +++ b/toolchain/check/testdata/basics/no_prelude/raw_ir.carbon @@ -34,6 +34,7 @@ fn Foo[T:! type](n: T) -> (T, ()) { // CHECK:STDOUT: generic0: {decl: inst+24, bindings: block11} // CHECK:STDOUT: specifics: // CHECK:STDOUT: specific0: {generic: generic0, args: block13} +// CHECK:STDOUT: struct_type_fields: {} // CHECK:STDOUT: types: // CHECK:STDOUT: typeTypeType: {kind: copy, type: typeTypeType} // CHECK:STDOUT: typeError: {kind: copy, type: typeError} diff --git a/toolchain/check/testdata/class/generic/import.carbon b/toolchain/check/testdata/class/generic/import.carbon index 32e71a761bd8..488daf48cbf1 100644 --- a/toolchain/check/testdata/class/generic/import.carbon +++ b/toolchain/check/testdata/class/generic/import.carbon @@ -275,7 +275,7 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %Class.type = import_ref Main//foo, inst+9, loaded [template = constants.%Class.1] // CHECK:STDOUT: %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+21, loaded [template = constants.%CompleteClass.1] -// CHECK:STDOUT: %import_ref.3: %F.type.2 = import_ref Main//foo, inst+71, loaded [template = constants.%F.2] +// CHECK:STDOUT: %import_ref.3: %F.type.2 = import_ref Main//foo, inst+69, loaded [template = constants.%F.2] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.7 // CHECK:STDOUT: import Core//prelude @@ -283,7 +283,7 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.4 = import_ref Main//foo, inst+26, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//foo, inst+38, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//foo, inst+48, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//foo, inst+46, unloaded // CHECK:STDOUT: %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int32] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -448,7 +448,7 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//foo, inst+9, unloaded // CHECK:STDOUT: %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+21, loaded [template = constants.%CompleteClass.1] -// CHECK:STDOUT: %import_ref.3: %F.type.3 = import_ref Main//foo, inst+71, loaded [template = constants.%F.3] +// CHECK:STDOUT: %import_ref.3: %F.type.3 = import_ref Main//foo, inst+69, loaded [template = constants.%F.3] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.4 // CHECK:STDOUT: import Core//prelude @@ -457,7 +457,7 @@ class Class(U:! type) { // CHECK:STDOUT: %import_ref.4: %Int32.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int32] // CHECK:STDOUT: %import_ref.5 = import_ref Main//foo, inst+26, unloaded // CHECK:STDOUT: %import_ref.6: @CompleteClass.%.1 (%.4) = import_ref Main//foo, inst+38, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.7: @CompleteClass.%F.type (%F.type.1) = import_ref Main//foo, inst+48, loaded [symbolic = @CompleteClass.%F (constants.%F.1)] +// CHECK:STDOUT: %import_ref.7: @CompleteClass.%F.type (%F.type.1) = import_ref Main//foo, inst+46, loaded [symbolic = @CompleteClass.%F (constants.%F.1)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -649,7 +649,7 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//foo, inst+9, unloaded // CHECK:STDOUT: %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+21, loaded [template = constants.%CompleteClass.1] -// CHECK:STDOUT: %import_ref.3: %F.type.3 = import_ref Main//foo, inst+71, loaded [template = constants.%F.3] +// CHECK:STDOUT: %import_ref.3: %F.type.3 = import_ref Main//foo, inst+69, loaded [template = constants.%F.3] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.7 // CHECK:STDOUT: .ImplicitAs = %import_ref.8 @@ -658,7 +658,7 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.4 = import_ref Main//foo, inst+26, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//foo, inst+38, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//foo, inst+48, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//foo, inst+46, unloaded // CHECK:STDOUT: %import_ref.7: %Int32.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int32] // CHECK:STDOUT: %import_ref.8: %ImplicitAs.type.1 = import_ref Core//prelude/operators/as, inst+49, loaded [template = constants.%ImplicitAs] // CHECK:STDOUT: %import_ref.9 = import_ref Core//prelude/operators/as, inst+55, unloaded @@ -849,7 +849,7 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %Class.type = import_ref Main//foo, inst+9, loaded [template = constants.%Class.1] // CHECK:STDOUT: %import_ref.2 = import_ref Main//foo, inst+21, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//foo, inst+71, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//foo, inst+69, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index a81fbf68f09e..aa31749ffdc6 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -184,8 +184,8 @@ fn Run() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//a, inst+3, loaded [template = constants.%Empty] // CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+8, loaded [template = constants.%Field] -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+28, loaded [template = constants.%ForwardDeclared.1] -// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+51, loaded [template = constants.%Incomplete] +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+26, loaded [template = constants.%ForwardDeclared.1] +// CHECK:STDOUT: %import_ref.4: type = import_ref Main//a, inst+49, loaded [template = constants.%Incomplete] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... @@ -193,12 +193,12 @@ fn Run() { // CHECK:STDOUT: %import_ref.5 = import_ref Main//a, inst+4, unloaded // CHECK:STDOUT: %import_ref.6 = import_ref Main//a, inst+9, unloaded // CHECK:STDOUT: %import_ref.7: %.9 = import_ref Main//a, inst+22, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+29, unloaded -// CHECK:STDOUT: %import_ref.9: %F.type = import_ref Main//a, inst+36, loaded [template = constants.%F] -// CHECK:STDOUT: %import_ref.10: %G.type = import_ref Main//a, inst+47, loaded [template = constants.%G] -// CHECK:STDOUT: %import_ref.11 = import_ref Main//a, inst+29, unloaded -// CHECK:STDOUT: %import_ref.12 = import_ref Main//a, inst+36, unloaded -// CHECK:STDOUT: %import_ref.13 = import_ref Main//a, inst+47, unloaded +// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+27, unloaded +// CHECK:STDOUT: %import_ref.9: %F.type = import_ref Main//a, inst+34, loaded [template = constants.%F] +// CHECK:STDOUT: %import_ref.10: %G.type = import_ref Main//a, inst+45, loaded [template = constants.%G] +// CHECK:STDOUT: %import_ref.11 = import_ref Main//a, inst+27, unloaded +// CHECK:STDOUT: %import_ref.12 = import_ref Main//a, inst+34, unloaded +// CHECK:STDOUT: %import_ref.13 = import_ref Main//a, inst+45, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -299,5 +299,5 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @F[%self.param_patt: %ForwardDeclared.1](); // CHECK:STDOUT: -// CHECK:STDOUT: fn @G[addr .inst+94: %.11](); +// CHECK:STDOUT: fn @G[addr .inst+91: %.11](); // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import_base.carbon b/toolchain/check/testdata/class/import_base.carbon index d2fe55cbdf32..b918a44e2c12 100644 --- a/toolchain/check/testdata/class/import_base.carbon +++ b/toolchain/check/testdata/class/import_base.carbon @@ -158,7 +158,7 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//a, inst+3, unloaded -// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+45, loaded [template = constants.%Child] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+41, loaded [template = constants.%Child] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... @@ -167,9 +167,9 @@ fn Run() { // CHECK:STDOUT: %import_ref.4: %F.type = import_ref Main//a, inst+10, loaded [template = constants.%F] // CHECK:STDOUT: %import_ref.5 = import_ref Main//a, inst+19, unloaded // CHECK:STDOUT: %import_ref.6: %.13 = import_ref Main//a, inst+33, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.7 = import_ref Main//a, inst+39, unloaded -// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+46, unloaded -// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+50, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//a, inst+37, unloaded +// CHECK:STDOUT: %import_ref.8 = import_ref Main//a, inst+42, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref Main//a, inst+46, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/class/import_struct_cyle.carbon b/toolchain/check/testdata/class/import_struct_cyle.carbon index da470ef18209..fe2d248b9acf 100644 --- a/toolchain/check/testdata/class/import_struct_cyle.carbon +++ b/toolchain/check/testdata/class/import_struct_cyle.carbon @@ -94,13 +94,13 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//a, inst+3, unloaded -// CHECK:STDOUT: %import_ref.2: ref %.3 = import_ref Main//a, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: ref %.3 = import_ref Main//a, inst+11, loaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.3 = import_ref Main//a, inst+4, unloaded -// CHECK:STDOUT: %import_ref.4: %.7 = import_ref Main//a, inst+20, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.4: %.7 = import_ref Main//a, inst+17, loaded [template = %.1] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/function/declaration/import.carbon b/toolchain/check/testdata/function/declaration/import.carbon index aefad2d73674..560059ad57b7 100644 --- a/toolchain/check/testdata/function/declaration/import.carbon +++ b/toolchain/check/testdata/function/declaration/import.carbon @@ -474,13 +474,13 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//api, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//api, inst+28, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+53, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+56, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+51, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+54, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = %import_ref.6 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+60, loaded [template = constants.%E] +// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+58, loaded [template = constants.%E] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.7 // CHECK:STDOUT: import Core//prelude @@ -594,13 +594,13 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//api, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//api, inst+28, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+53, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+56, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+51, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+54, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = file.%E.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+60, loaded [template = constants.%E] +// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+58, loaded [template = constants.%E] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.7 // CHECK:STDOUT: import Core//prelude @@ -744,13 +744,13 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//extern_api, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//extern_api, inst+28, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//extern_api, inst+53, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//extern_api, inst+56, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//extern_api, inst+51, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//extern_api, inst+54, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = file.%E.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//extern_api, inst+60, loaded [template = constants.%E] +// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//extern_api, inst+58, loaded [template = constants.%E] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.7 // CHECK:STDOUT: import Core//prelude @@ -893,18 +893,18 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//api, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//api, inst+28, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+53, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+56, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//api, inst+51, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//api, inst+54, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = %import_ref.6 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+60, loaded [template = constants.%E] +// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//api, inst+58, loaded [template = constants.%E] // CHECK:STDOUT: %import_ref.7 = import_ref Main//extern_api, inst+3, unloaded // CHECK:STDOUT: %import_ref.8 = import_ref Main//extern_api, inst+28, unloaded -// CHECK:STDOUT: %import_ref.9 = import_ref Main//extern_api, inst+53, unloaded -// CHECK:STDOUT: %import_ref.10 = import_ref Main//extern_api, inst+56, unloaded -// CHECK:STDOUT: %import_ref.11 = import_ref Main//extern_api, inst+60, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref Main//extern_api, inst+51, unloaded +// CHECK:STDOUT: %import_ref.10 = import_ref Main//extern_api, inst+54, unloaded +// CHECK:STDOUT: %import_ref.11 = import_ref Main//extern_api, inst+58, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.12 // CHECK:STDOUT: import Core//prelude @@ -1017,18 +1017,18 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//extern_api, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//extern_api, inst+28, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//extern_api, inst+53, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//extern_api, inst+56, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//extern_api, inst+51, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//extern_api, inst+54, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = %import_ref.6 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//extern_api, inst+60, loaded [template = constants.%E] +// CHECK:STDOUT: %import_ref.6: %E.type = import_ref Main//extern_api, inst+58, loaded [template = constants.%E] // CHECK:STDOUT: %import_ref.7 = import_ref Main//api, inst+3, unloaded // CHECK:STDOUT: %import_ref.8 = import_ref Main//api, inst+28, unloaded -// CHECK:STDOUT: %import_ref.9 = import_ref Main//api, inst+53, unloaded -// CHECK:STDOUT: %import_ref.10 = import_ref Main//api, inst+56, unloaded -// CHECK:STDOUT: %import_ref.11 = import_ref Main//api, inst+60, unloaded +// CHECK:STDOUT: %import_ref.9 = import_ref Main//api, inst+51, unloaded +// CHECK:STDOUT: %import_ref.10 = import_ref Main//api, inst+54, unloaded +// CHECK:STDOUT: %import_ref.11 = import_ref Main//api, inst+58, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.12 // CHECK:STDOUT: import Core//prelude @@ -1121,13 +1121,13 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//api, inst+3, unloaded // CHECK:STDOUT: %import_ref.2 = import_ref Main//api, inst+28, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//api, inst+53, unloaded -// CHECK:STDOUT: %import_ref.4 = import_ref Main//api, inst+56, unloaded -// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//api, inst+51, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref Main//api, inst+54, unloaded +// CHECK:STDOUT: %import_ref.5: = import_ref Main//api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = %import_ref.6 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6 = import_ref Main//api, inst+60, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//api, inst+58, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... @@ -1152,13 +1152,13 @@ import library "extern_api"; // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//extern_api, inst+3, unloaded // CHECK:STDOUT: %import_ref.2 = import_ref Main//extern_api, inst+28, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//extern_api, inst+53, unloaded -// CHECK:STDOUT: %import_ref.4 = import_ref Main//extern_api, inst+56, unloaded -// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+59, loaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//extern_api, inst+51, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref Main//extern_api, inst+54, unloaded +// CHECK:STDOUT: %import_ref.5: = import_ref Main//extern_api, inst+57, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.5, [template] { // CHECK:STDOUT: .E = %import_ref.6 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.6 = import_ref Main//extern_api, inst+60, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//extern_api, inst+58, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... diff --git a/toolchain/check/testdata/function/definition/import.carbon b/toolchain/check/testdata/function/definition/import.carbon index 529dc9b60982..2b9935231612 100644 --- a/toolchain/check/testdata/function/definition/import.carbon +++ b/toolchain/check/testdata/function/definition/import.carbon @@ -261,8 +261,8 @@ fn D() {} // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//fns, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//fns, inst+29, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//fns, inst+56, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//fns, inst+68, unloaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Main//fns, inst+54, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//fns, inst+65, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.5 // CHECK:STDOUT: import Core//prelude @@ -343,8 +343,8 @@ fn D() {} // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: %A.type = import_ref Main//fns, inst+3, loaded [template = constants.%A] // CHECK:STDOUT: %import_ref.2: %B.type = import_ref Main//fns, inst+29, loaded [template = constants.%B] -// CHECK:STDOUT: %import_ref.3 = import_ref Main//fns, inst+56, unloaded -// CHECK:STDOUT: %import_ref.4 = import_ref Main//fns, inst+68, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//fns, inst+54, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref Main//fns, inst+65, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.5 // CHECK:STDOUT: import Core//prelude @@ -430,8 +430,8 @@ fn D() {} // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//fns, inst+3, unloaded // CHECK:STDOUT: %import_ref.2 = import_ref Main//fns, inst+29, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//fns, inst+56, unloaded -// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//fns, inst+68, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//fns, inst+54, unloaded +// CHECK:STDOUT: %import_ref.4: %D.type = import_ref Main//fns, inst+65, loaded [template = constants.%D] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... diff --git a/toolchain/check/testdata/interface/no_prelude/import.carbon b/toolchain/check/testdata/interface/no_prelude/import.carbon index ae2866b6e36b..75e78c9f6a2b 100644 --- a/toolchain/check/testdata/interface/no_prelude/import.carbon +++ b/toolchain/check/testdata/interface/no_prelude/import.carbon @@ -177,7 +177,7 @@ var f: ForwardDeclared* = &f_ref.f; // CHECK:STDOUT: %import_ref.1: type = import_ref Main//a, inst+1, loaded [template = constants.%Empty.type] // CHECK:STDOUT: %import_ref.2: type = import_ref Main//a, inst+5, loaded [template = constants.%Basic.type] // CHECK:STDOUT: %import_ref.3: type = import_ref Main//a, inst+20, loaded [template = constants.%ForwardDeclared.type] -// CHECK:STDOUT: %import_ref.4: ref %.11 = import_ref Main//a, inst+42, loaded +// CHECK:STDOUT: %import_ref.4: ref %.11 = import_ref Main//a, inst+39, loaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//a, inst+3, unloaded // CHECK:STDOUT: %import_ref.6 = import_ref Main//a, inst+7, unloaded // CHECK:STDOUT: %import_ref.7: %.2 = import_ref Main//a, inst+11, loaded [template = constants.%.3] diff --git a/toolchain/check/testdata/packages/fail_import_type_error.carbon b/toolchain/check/testdata/packages/fail_import_type_error.carbon index f20fd8ae818e..3281fc5aa63c 100644 --- a/toolchain/check/testdata/packages/fail_import_type_error.carbon +++ b/toolchain/check/testdata/packages/fail_import_type_error.carbon @@ -88,9 +88,9 @@ var d: i32 = d_ref; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: ref = import_ref Implicit//default, inst+5, loaded -// CHECK:STDOUT: %import_ref.2: ref = import_ref Implicit//default, inst+10, loaded -// CHECK:STDOUT: %import_ref.3: ref = import_ref Implicit//default, inst+14, loaded -// CHECK:STDOUT: %import_ref.4: ref = import_ref Implicit//default, inst+18, loaded +// CHECK:STDOUT: %import_ref.2: ref = import_ref Implicit//default, inst+9, loaded +// CHECK:STDOUT: %import_ref.3: ref = import_ref Implicit//default, inst+13, loaded +// CHECK:STDOUT: %import_ref.4: ref = import_ref Implicit//default, inst+17, loaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.5 // CHECK:STDOUT: import Core//prelude diff --git a/toolchain/check/testdata/packages/no_prelude/cross_package_export.carbon b/toolchain/check/testdata/packages/no_prelude/cross_package_export.carbon index c5407fe2b18a..eb6dc751ede3 100644 --- a/toolchain/check/testdata/packages/no_prelude/cross_package_export.carbon +++ b/toolchain/check/testdata/packages/no_prelude/cross_package_export.carbon @@ -346,9 +346,9 @@ alias C = Other.C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+9, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -546,9 +546,9 @@ alias C = Other.C; // CHECK:STDOUT: .C = %import_ref.1 // CHECK:STDOUT: import Other//export_name // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+9, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -600,9 +600,9 @@ alias C = Other.C; // CHECK:STDOUT: import Other//export_name // CHECK:STDOUT: import Other//export_name_copy // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+9, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -653,9 +653,9 @@ alias C = Other.C; // CHECK:STDOUT: .C = %import_ref.1 // CHECK:STDOUT: import Other//export_name_indirect // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name_indirect, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name_indirect, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name_indirect, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name_indirect, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name_indirect, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name_indirect, inst+9, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -712,9 +712,9 @@ alias C = Other.C; // CHECK:STDOUT: import Other//export_name_indirect // CHECK:STDOUT: import Other//base // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+9, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -828,9 +828,9 @@ alias C = Other.C; // CHECK:STDOUT: import Other//export_name // CHECK:STDOUT: import Other//conflict // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+12, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+10, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+11, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Other//export_name, inst+10, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Other//export_name, inst+8, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Other//export_name, inst+9, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Other//conflict, inst+1, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/export_import.carbon b/toolchain/check/testdata/packages/no_prelude/export_import.carbon index 70de99dec0d4..0f10901030de 100644 --- a/toolchain/check/testdata/packages/no_prelude/export_import.carbon +++ b/toolchain/check/testdata/packages/no_prelude/export_import.carbon @@ -771,7 +771,7 @@ var indirect_c: C = {.x = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Main//use_non_export_then_base, inst+15, unloaded +// CHECK:STDOUT: %import_ref.1 = import_ref Main//use_non_export_then_base, inst+13, unloaded // CHECK:STDOUT: %import_ref.2: type = import_ref Main//base, inst+1, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+7, unloaded diff --git a/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon b/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon index 0383ef14e90c..77eaab8c104c 100644 --- a/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon +++ b/toolchain/check/testdata/packages/no_prelude/export_mixed.carbon @@ -162,7 +162,7 @@ var d: D = {.y = ()}; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//base, inst+1, unloaded -// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+13, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+11, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -184,7 +184,7 @@ var d: D = {.y = ()}; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+13, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+11, unloaded // CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+7, unloaded // CHECK:STDOUT: } @@ -215,7 +215,7 @@ var d: D = {.y = ()}; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+13, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref Main//base, inst+11, unloaded // CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+7, unloaded // CHECK:STDOUT: } @@ -238,7 +238,7 @@ var d: D = {.y = ()}; // CHECK:STDOUT: --- export_name_then_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref = import_ref Main//export_name, inst+13, unloaded +// CHECK:STDOUT: %import_ref = import_ref Main//export_name, inst+11, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -261,9 +261,9 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+13, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+11, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+12, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+9, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+10, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -309,9 +309,9 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_name, inst+13, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_name, inst+11, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_name, inst+12, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_name, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_name, inst+9, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_name, inst+10, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -357,9 +357,9 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+13, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+11, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+12, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+9, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+10, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -400,7 +400,7 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref = import_ref Main//export_import_then_name, inst+13, unloaded +// CHECK:STDOUT: %import_ref = import_ref Main//export_import_then_name, inst+11, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -435,9 +435,9 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+13, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+11, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+12, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//export_import_then_name, inst+9, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+10, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -488,12 +488,12 @@ var d: D = {.y = ()}; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+13, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: type = import_ref Main//base, inst+13, loaded [template = constants.%D] -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+11, unloaded -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_import_then_name, inst+12, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+18, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_import_then_name, inst+11, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//base, inst+11, loaded [template = constants.%D] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export_import_then_name, inst+9, unloaded +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_import_then_name, inst+10, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+16, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/packages/no_prelude/export_name.carbon b/toolchain/check/testdata/packages/no_prelude/export_name.carbon index 698f16a2bd26..f4c3e765c8c4 100644 --- a/toolchain/check/testdata/packages/no_prelude/export_name.carbon +++ b/toolchain/check/testdata/packages/no_prelude/export_name.carbon @@ -262,15 +262,15 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = file.%NSC // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//base, inst+14, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//base, inst+12, loaded [template = constants.%NSC] // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+7, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+15, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//base, inst+19, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+13, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//base, inst+17, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -298,12 +298,12 @@ private export C; // CHECK:STDOUT: --- not_reexporting.carbon // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Main//export, inst+15, unloaded +// CHECK:STDOUT: %import_ref.1 = import_ref Main//export, inst+13, unloaded // CHECK:STDOUT: %import_ref.2: = import_ref Main//export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//export, inst+24, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//export, inst+20, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -327,16 +327,16 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+15, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+13, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref Main//export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = file.%NSC // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+24, loaded [template = constants.%NSC] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+22, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+23, unloaded +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+20, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+18, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+19, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -385,16 +385,16 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+15, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+13, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref Main//export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+24, loaded [template = constants.%NSC] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+22, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+23, unloaded +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+20, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+18, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+19, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -465,16 +465,16 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_export, inst+15, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_export, inst+13, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref Main//export_export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export_export, inst+24, loaded [template = constants.%NSC] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//export_export, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//export_export, inst+22, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//export_export, inst+23, unloaded +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export_export, inst+20, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//export_export, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//export_export, inst+18, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//export_export, inst+19, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -546,16 +546,16 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_export, inst+15, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export_export, inst+13, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref Main//export_export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export_export, inst+24, loaded [template = constants.%NSC] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//export_export, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//export_export, inst+22, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//export_export, inst+23, unloaded +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export_export, inst+20, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export_export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//export_export, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//export_export, inst+18, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//export_export, inst+19, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -612,11 +612,11 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1 = import_ref Main//base, inst+1, unloaded -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+14, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+12, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -660,11 +660,11 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+14, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+12, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+7, unloaded // CHECK:STDOUT: } @@ -702,15 +702,15 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//base, inst+14, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//base, inst+12, loaded [template = constants.%NSC] // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+7, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+15, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//base, inst+19, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//base, inst+13, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//base, inst+17, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -781,16 +781,16 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+15, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//export, inst+13, loaded [template = constants.%C] // CHECK:STDOUT: %import_ref.2: = import_ref Main//export, inst+4, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+24, loaded [template = constants.%NSC] -// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+14, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+22, unloaded -// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+23, unloaded +// CHECK:STDOUT: %import_ref.3: type = import_ref Main//export, inst+20, loaded [template = constants.%NSC] +// CHECK:STDOUT: %import_ref.4 = import_ref Main//export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Main//export, inst+12, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Main//export, inst+18, unloaded +// CHECK:STDOUT: %import_ref.7 = import_ref Main//export, inst+19, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -868,11 +868,11 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+14, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+12, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+7, unloaded // CHECK:STDOUT: } @@ -905,9 +905,9 @@ private export C; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: type = import_ref Main//repeat_export, inst+15, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2 = import_ref Main//repeat_export, inst+13, unloaded -// CHECK:STDOUT: %import_ref.3 = import_ref Main//repeat_export, inst+14, unloaded +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//repeat_export, inst+13, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2 = import_ref Main//repeat_export, inst+11, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//repeat_export, inst+12, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -951,11 +951,11 @@ private export C; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %import_ref.1: type = import_ref Main//base, inst+1, loaded [template = constants.%C] -// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+13, loaded +// CHECK:STDOUT: %import_ref.2: = import_ref Main//base, inst+11, loaded // CHECK:STDOUT: %NS: = namespace %import_ref.2, [template] { // CHECK:STDOUT: .NSC = %import_ref.3 // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+14, unloaded +// CHECK:STDOUT: %import_ref.3 = import_ref Main//base, inst+12, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//base, inst+2, unloaded // CHECK:STDOUT: %import_ref.5 = import_ref Main//base, inst+7, unloaded // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon b/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon index deb587a029e5..0cd6f599dcb4 100644 --- a/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon +++ b/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon @@ -917,7 +917,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %import_ref.2: type = import_ref P//library, inst+29, loaded [template = constants.%D] // CHECK:STDOUT: %import_ref.3 = import_ref P//library, inst+30, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref P//library, inst+35, unloaded -// CHECK:STDOUT: %import_ref.5 = import_ref P//library, inst+41, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref P//library, inst+39, unloaded // CHECK:STDOUT: %import_ref.6: %C.type = import_ref P//library, inst+20, loaded [template = constants.%C.1] // CHECK:STDOUT: %import_ref.7 = import_ref P//library, inst+25, unloaded // CHECK:STDOUT: %import_ref.8: %ImplicitAs.type.1 = import_ref Core//default, inst+15, loaded [template = constants.%ImplicitAs] @@ -926,31 +926,31 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %import_ref.11 = import_ref Core//default, inst+36, unloaded // CHECK:STDOUT: %import_ref.12 = import_ref Core//default, inst+36, unloaded // CHECK:STDOUT: %import_ref.13 = import_ref Core//default, inst+36, unloaded -// CHECK:STDOUT: %import_ref.14: type = import_ref P//library, inst+72, loaded [template = constants.%C.3] -// CHECK:STDOUT: %import_ref.15: type = import_ref P//library, inst+117, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.16: = import_ref P//library, inst+137, loaded [template = constants.%.22] -// CHECK:STDOUT: %import_ref.17: type = import_ref P//library, inst+147, loaded [template = constants.%C.4] -// CHECK:STDOUT: %import_ref.18: type = import_ref P//library, inst+152, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.19: = import_ref P//library, inst+167, loaded [template = constants.%.23] -// CHECK:STDOUT: %import_ref.20: type = import_ref P//library, inst+176, loaded [template = constants.%C.5] -// CHECK:STDOUT: %import_ref.21: type = import_ref P//library, inst+181, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.22: = import_ref P//library, inst+196, loaded [template = constants.%.24] -// CHECK:STDOUT: %import_ref.23: type = import_ref P//library, inst+205, loaded [template = constants.%C.6] -// CHECK:STDOUT: %import_ref.24: type = import_ref P//library, inst+210, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.25: = import_ref P//library, inst+225, loaded [template = constants.%.25] -// CHECK:STDOUT: %import_ref.26: type = import_ref P//library, inst+234, loaded [template = constants.%C.7] -// CHECK:STDOUT: %import_ref.27: type = import_ref P//library, inst+239, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.28: = import_ref P//library, inst+254, loaded [template = constants.%.26] -// CHECK:STDOUT: %import_ref.29: type = import_ref P//library, inst+263, loaded [template = constants.%C.8] -// CHECK:STDOUT: %import_ref.30: type = import_ref P//library, inst+268, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.31: = import_ref P//library, inst+283, loaded [template = constants.%.27] -// CHECK:STDOUT: %import_ref.32: type = import_ref P//library, inst+292, loaded [template = constants.%C.9] -// CHECK:STDOUT: %import_ref.33: type = import_ref P//library, inst+297, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.34: = import_ref P//library, inst+312, loaded [template = constants.%.28] -// CHECK:STDOUT: %import_ref.35: type = import_ref P//library, inst+321, loaded [template = constants.%C.10] -// CHECK:STDOUT: %import_ref.36: type = import_ref P//library, inst+326, loaded [template = constants.%ImplicitAs.type.3] -// CHECK:STDOUT: %import_ref.37: = import_ref P//library, inst+341, loaded [template = constants.%.29] -// CHECK:STDOUT: %import_ref.38: %Make.type = import_ref P//library, inst+52, loaded [template = constants.%Make] +// CHECK:STDOUT: %import_ref.14: type = import_ref P//library, inst+66, loaded [template = constants.%C.3] +// CHECK:STDOUT: %import_ref.15: type = import_ref P//library, inst+111, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.16: = import_ref P//library, inst+131, loaded [template = constants.%.22] +// CHECK:STDOUT: %import_ref.17: type = import_ref P//library, inst+141, loaded [template = constants.%C.4] +// CHECK:STDOUT: %import_ref.18: type = import_ref P//library, inst+146, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.19: = import_ref P//library, inst+161, loaded [template = constants.%.23] +// CHECK:STDOUT: %import_ref.20: type = import_ref P//library, inst+170, loaded [template = constants.%C.5] +// CHECK:STDOUT: %import_ref.21: type = import_ref P//library, inst+175, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.22: = import_ref P//library, inst+190, loaded [template = constants.%.24] +// CHECK:STDOUT: %import_ref.23: type = import_ref P//library, inst+199, loaded [template = constants.%C.6] +// CHECK:STDOUT: %import_ref.24: type = import_ref P//library, inst+204, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.25: = import_ref P//library, inst+219, loaded [template = constants.%.25] +// CHECK:STDOUT: %import_ref.26: type = import_ref P//library, inst+228, loaded [template = constants.%C.7] +// CHECK:STDOUT: %import_ref.27: type = import_ref P//library, inst+233, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.28: = import_ref P//library, inst+248, loaded [template = constants.%.26] +// CHECK:STDOUT: %import_ref.29: type = import_ref P//library, inst+257, loaded [template = constants.%C.8] +// CHECK:STDOUT: %import_ref.30: type = import_ref P//library, inst+262, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.31: = import_ref P//library, inst+277, loaded [template = constants.%.27] +// CHECK:STDOUT: %import_ref.32: type = import_ref P//library, inst+286, loaded [template = constants.%C.9] +// CHECK:STDOUT: %import_ref.33: type = import_ref P//library, inst+291, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.34: = import_ref P//library, inst+306, loaded [template = constants.%.28] +// CHECK:STDOUT: %import_ref.35: type = import_ref P//library, inst+315, loaded [template = constants.%C.10] +// CHECK:STDOUT: %import_ref.36: type = import_ref P//library, inst+320, loaded [template = constants.%ImplicitAs.type.3] +// CHECK:STDOUT: %import_ref.37: = import_ref P//library, inst+335, loaded [template = constants.%.29] +// CHECK:STDOUT: %import_ref.38: %Make.type = import_ref P//library, inst+48, loaded [template = constants.%Make] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index 0891a5dc73f2..b75fb2f7d9eb 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -247,17 +247,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1: ref %.2 = import_ref Implicit//default, inst+19, loaded -// CHECK:STDOUT: %import_ref.2: ref %.6 = import_ref Implicit//default, inst+59, loaded -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1] -// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+131, loaded [template = constants.%F] +// CHECK:STDOUT: %import_ref.1: ref %.2 = import_ref Implicit//default, inst+17, loaded +// CHECK:STDOUT: %import_ref.2: ref %.6 = import_ref Implicit//default, inst+47, loaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+86, loaded [template = constants.%C.1] +// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+111, loaded [template = constants.%F] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .Int32 = %import_ref.5 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.5: %Int32.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int32] -// CHECK:STDOUT: %import_ref.6 = import_ref Implicit//default, inst+109, unloaded +// CHECK:STDOUT: %import_ref.6 = import_ref Implicit//default, inst+91, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -396,15 +396,15 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Implicit//default, inst+19, unloaded -// CHECK:STDOUT: %import_ref.2 = import_ref Implicit//default, inst+59, unloaded -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1] -// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+131, loaded [template = constants.%F] +// CHECK:STDOUT: %import_ref.1 = import_ref Implicit//default, inst+17, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref Implicit//default, inst+47, unloaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+86, loaded [template = constants.%C.1] +// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+111, loaded [template = constants.%F] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.5 = import_ref Implicit//default, inst+109, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Implicit//default, inst+91, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -506,16 +506,16 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Implicit//default, inst+19, unloaded -// CHECK:STDOUT: %import_ref.2 = import_ref Implicit//default, inst+59, unloaded -// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+104, loaded [template = constants.%C.1] -// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+131, loaded [template = constants.%F] +// CHECK:STDOUT: %import_ref.1 = import_ref Implicit//default, inst+17, unloaded +// CHECK:STDOUT: %import_ref.2 = import_ref Implicit//default, inst+47, unloaded +// CHECK:STDOUT: %import_ref.3: %C.type = import_ref Implicit//default, inst+86, loaded [template = constants.%C.1] +// CHECK:STDOUT: %import_ref.4: %F.type = import_ref Implicit//default, inst+111, loaded [template = constants.%F] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { // CHECK:STDOUT: .ImplicitAs = %import_ref.6 // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.5 = import_ref Implicit//default, inst+109, unloaded +// CHECK:STDOUT: %import_ref.5 = import_ref Implicit//default, inst+91, unloaded // CHECK:STDOUT: %import_ref.6: %ImplicitAs.type.1 = import_ref Core//prelude/operators/as, inst+49, loaded [template = constants.%ImplicitAs] // CHECK:STDOUT: %import_ref.7 = import_ref Core//prelude/operators/as, inst+55, unloaded // CHECK:STDOUT: %import_ref.8: @ImplicitAs.%.1 (%.11) = import_ref Core//prelude/operators/as, inst+77, loaded [symbolic = @ImplicitAs.%.2 (constants.%.15)] diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index 528ea882f54b..6fdaa614ba41 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -234,13 +234,6 @@ static auto EmitAsConstant(ConstantContext& /*context*/, CARBON_FATAL("TODO: Add support: {0}", inst); } -static auto EmitAsConstant(ConstantContext& /*context*/, - SemIR::StructTypeField /*inst*/) -> llvm::Constant* { - // A StructTypeField isn't a value, so this constant value won't ever be used. - // It also doesn't even have a type, so we can't use GetUnusedConstant. - return nullptr; -} - auto LowerConstants(FileContext& file_context, llvm::MutableArrayRef constants) -> void { ConstantContext context(file_context, constants); diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index f32dc6a3f901..63a990954505 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -548,13 +548,11 @@ static auto BuildTypeForInst(FileContext& context, SemIR::PointerType /*inst*/) static auto BuildTypeForInst(FileContext& context, SemIR::StructType inst) -> llvm::Type* { - auto fields = context.sem_ir().inst_blocks().Get(inst.fields_id); + auto fields = context.sem_ir().struct_type_fields().Get(inst.fields_id); llvm::SmallVector subtypes; subtypes.reserve(fields.size()); - for (auto field_id : fields) { - auto field = - context.sem_ir().insts().GetAs(field_id); - subtypes.push_back(context.GetType(field.field_type_id)); + for (auto field : fields) { + subtypes.push_back(context.GetType(field.type_id)); } return llvm::StructType::get(context.llvm_context(), subtypes); } diff --git a/toolchain/lower/handle_aggregates.cpp b/toolchain/lower/handle_aggregates.cpp index 3765849a4b52..45d710cf984c 100644 --- a/toolchain/lower/handle_aggregates.cpp +++ b/toolchain/lower/handle_aggregates.cpp @@ -91,14 +91,11 @@ static auto GetAggregateElement(FunctionContext& context, static auto GetStructFieldName(FunctionContext& context, SemIR::TypeId struct_type_id, SemIR::ElementIndex index) -> llvm::StringRef { - auto fields = context.sem_ir().inst_blocks().Get( - context.sem_ir() - .types() - .GetAs(struct_type_id) - .fields_id); - auto field = context.sem_ir().insts().GetAs( - fields[index.index]); - return context.sem_ir().names().GetIRBaseName(field.name_id); + auto struct_type = + context.sem_ir().types().GetAs(struct_type_id); + auto fields = + context.sem_ir().struct_type_fields().Get(struct_type.fields_id); + return context.sem_ir().names().GetIRBaseName(fields[index.index].name_id); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, @@ -237,11 +234,6 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, inst_id, EmitAggregateValueRepr(context, inst.type_id, inst.elements_id)); } -auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, - SemIR::StructTypeField /*inst*/) -> void { - // No action to take. -} - auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::TupleAccess inst) -> void { context.SetLocal(inst_id, diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 6b135c50fe36..7996b9e1cb1d 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -110,6 +110,7 @@ cc_library( "interface.h", "name.h", "name_scope.h", + "struct_type_field.h", "type.h", "type_info.h", ], diff --git a/toolchain/sem_ir/copy_on_write_block.h b/toolchain/sem_ir/copy_on_write_block.h index 676ccf2f9116..7fc279c3745d 100644 --- a/toolchain/sem_ir/copy_on_write_block.h +++ b/toolchain/sem_ir/copy_on_write_block.h @@ -68,6 +68,8 @@ class CopyOnWriteBlock { }; using CopyOnWriteInstBlock = CopyOnWriteBlock; +using CopyOnWriteStructTypeFieldsBlock = + CopyOnWriteBlock; using CopyOnWriteTypeBlock = CopyOnWriteBlock; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 4531ba0e9ceb..7461f552612c 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -111,6 +111,7 @@ auto File::OutputYaml(bool include_builtins) const -> Yaml::OutputMapping { map.Add("classes", classes_.OutputYaml()); map.Add("generics", generics_.OutputYaml()); map.Add("specifics", specifics_.OutputYaml()); + map.Add("struct_type_fields", struct_type_fields_.OutputYaml()); map.Add("types", types_.OutputYaml()); map.Add("type_blocks", type_blocks_.OutputYaml()); map.Add( @@ -163,6 +164,8 @@ auto File::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const mem_usage.Collect(MemUsage::ConcatLabel(label, "import_irs_"), import_irs_); mem_usage.Collect(MemUsage::ConcatLabel(label, "import_ir_insts_"), import_ir_insts_); + mem_usage.Collect(MemUsage::ConcatLabel(label, "struct_type_fields_"), + struct_type_fields_); mem_usage.Collect(MemUsage::ConcatLabel(label, "type_blocks_"), type_blocks_); mem_usage.Collect(MemUsage::ConcatLabel(label, "insts_"), insts_); mem_usage.Collect(MemUsage::ConcatLabel(label, "name_scopes_"), name_scopes_); @@ -202,7 +205,6 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory { case Return::Kind: case ReturnSlotPattern::Kind: case ReturnExpr::Kind: - case StructTypeField::Kind: return ExprCategory::NotExpr; case ImportRefUnloaded::Kind: diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index fe871f497754..355c2f856ad4 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -26,6 +26,7 @@ #include "toolchain/sem_ir/interface.h" #include "toolchain/sem_ir/name.h" #include "toolchain/sem_ir/name_scope.h" +#include "toolchain/sem_ir/struct_type_field.h" #include "toolchain/sem_ir/type.h" #include "toolchain/sem_ir/type_info.h" @@ -142,6 +143,12 @@ class File : public Printable { } auto name_scopes() -> NameScopeStore& { return name_scopes_; } auto name_scopes() const -> const NameScopeStore& { return name_scopes_; } + auto struct_type_fields() -> StructTypeFieldsStore& { + return struct_type_fields_; + } + auto struct_type_fields() const -> const StructTypeFieldsStore& { + return struct_type_fields_; + } auto types() -> TypeStore& { return types_; } auto types() const -> const TypeStore& { return types_; } auto type_blocks() -> BlockValueStore& { return type_blocks_; } @@ -256,6 +263,9 @@ class File : public Printable { // types. ConstantStore constants_; + // Storage for StructTypeField lists. + StructTypeFieldsStore struct_type_fields_ = StructTypeFieldsStore(allocator_); + // Descriptions of types used in this file. TypeStore types_ = TypeStore(&insts_, &constant_values_); }; diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 5fcbc7f4b161..02f8a68beb4e 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -342,14 +342,6 @@ class FormatterImpl { sem_ir_.inst_blocks().GetOrEmpty(generic.GetEvalBlock(region)), sem_ir_.inst_blocks().GetOrEmpty( specific.GetValueBlock(region)))) { - if (generic_inst_id && specific_inst_id && - sem_ir_.insts().Is(*generic_inst_id) && - sem_ir_.insts().Is(*specific_inst_id)) { - // Skip printing struct type fields to match the way we print the - // generic. - continue; - } - Indent(); if (generic_inst_id) { FormatName(*generic_inst_id); @@ -899,18 +891,14 @@ class FormatterImpl { FormatTrailingBlock(inst.requirements_id); } - // StructTypeFields are formatted as part of their StructType. - auto FormatInst(InstId /*inst_id*/, StructTypeField /*inst*/) -> void {} - auto FormatInstRHS(StructType inst) -> void { out_ << " {"; llvm::ListSeparator sep; - for (auto field_id : sem_ir_.inst_blocks().Get(inst.fields_id)) { + for (auto field : sem_ir_.struct_type_fields().Get(inst.fields_id)) { out_ << sep << "."; - auto field = sem_ir_.insts().GetAs(field_id); FormatName(field.name_id); out_ << ": "; - FormatType(field.field_type_id); + FormatType(field.type_id); } out_ << "}"; } diff --git a/toolchain/sem_ir/id_kind.h b/toolchain/sem_ir/id_kind.h index 50540481e9bc..376a7fbdf436 100644 --- a/toolchain/sem_ir/id_kind.h +++ b/toolchain/sem_ir/id_kind.h @@ -123,8 +123,9 @@ using IdKind = TypeEnum< InstId, AbsoluteInstId, MatchingInstId, ConstantId, EntityNameId, CompileTimeBindIndex, RuntimeParamIndex, FacetTypeId, FunctionId, ClassId, InterfaceId, ImplId, GenericId, SpecificId, ImportIRId, ImportIRInstId, - LocId, BoolValue, IntKind, NameId, NameScopeId, InstBlockId, TypeId, - TypeBlockId, ElementIndex, LibraryNameId, FloatKind>; + LocId, BoolValue, IntKind, NameId, NameScopeId, InstBlockId, + StructTypeFieldsId, TypeId, TypeBlockId, ElementIndex, LibraryNameId, + FloatKind>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index c52e66cbe8dd..fbd95f0e784d 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -29,6 +29,7 @@ struct ImportIRInst; struct Impl; struct Interface; struct NameScope; +struct StructTypeField; struct TypeInfo; // The ID of an instruction. @@ -722,6 +723,25 @@ constexpr InstBlockId InstBlockId::GlobalInit = InstBlockId(3); constexpr InstBlockId InstBlockId::Invalid = InstBlockId(InvalidIndex); constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(InvalidIndex - 1); +// The ID of a type block. +struct StructTypeFieldsId : public IdBase, + public Printable { + using ElementType = StructTypeField; + using ValueType = llvm::MutableArrayRef; + + // An explicitly invalid ID. + static const StructTypeFieldsId Invalid; + + using IdBase::IdBase; + auto Print(llvm::raw_ostream& out) const -> void { + out << "type_block"; + IdBase::Print(out); + } +}; + +constexpr StructTypeFieldsId StructTypeFieldsId::Invalid = + StructTypeFieldsId(InvalidIndex); + // The ID of a type. struct TypeId : public IdBase, public Printable { // `StringifyTypeExpr` is used for diagnostics. However, where possible, an diff --git a/toolchain/sem_ir/inst_kind.def b/toolchain/sem_ir/inst_kind.def index 5120c02fcb72..37109a278928 100644 --- a/toolchain/sem_ir/inst_kind.def +++ b/toolchain/sem_ir/inst_kind.def @@ -91,7 +91,6 @@ CARBON_SEM_IR_INST_KIND(StructAccess) CARBON_SEM_IR_INST_KIND(StructInit) CARBON_SEM_IR_INST_KIND(StructLiteral) CARBON_SEM_IR_INST_KIND(StructType) -CARBON_SEM_IR_INST_KIND(StructTypeField) CARBON_SEM_IR_INST_KIND(StructValue) CARBON_SEM_IR_INST_KIND(SymbolicBindingPattern) CARBON_SEM_IR_INST_KIND(TemporaryStorage) diff --git a/toolchain/sem_ir/stringify_type.cpp b/toolchain/sem_ir/stringify_type.cpp index c47ef4ef6d50..34daa24261ff 100644 --- a/toolchain/sem_ir/stringify_type.cpp +++ b/toolchain/sem_ir/stringify_type.cpp @@ -206,26 +206,22 @@ auto StringifyTypeExpr(const SemIR::File& outer_sem_ir, InstId outer_inst_id) break; } case CARBON_KIND(StructType inst): { - auto refs = sem_ir.inst_blocks().Get(inst.fields_id); - if (refs.empty()) { + auto fields = sem_ir.struct_type_fields().Get(inst.fields_id); + if (fields.empty()) { out << "{}"; break; - } else if (step.index == 0) { - out << "{"; - } else if (step.index < static_cast(refs.size())) { - out << ", "; - } else { + } + + if (step.index >= static_cast(fields.size())) { out << "}"; break; } + const auto& field = fields[step.index]; + out << (step.index == 0 ? "{" : ", ") << "." + << sem_ir.names().GetFormatted(field.name_id) << ": "; steps.push_back(step.Next()); - push_inst_id(refs[step.index]); - break; - } - case CARBON_KIND(StructTypeField inst): { - out << "." << sem_ir.names().GetFormatted(inst.name_id) << ": "; - push_inst_id(sem_ir.types().GetInstId(inst.field_type_id)); + push_inst_id(sem_ir.types().GetInstId(field.type_id)); break; } case CARBON_KIND(TupleType inst): { diff --git a/toolchain/sem_ir/struct_type_field.h b/toolchain/sem_ir/struct_type_field.h new file mode 100644 index 000000000000..83720fbda6e9 --- /dev/null +++ b/toolchain/sem_ir/struct_type_field.h @@ -0,0 +1,39 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_SEM_IR_STRUCT_TYPE_FIELD_H_ +#define CARBON_TOOLCHAIN_SEM_IR_STRUCT_TYPE_FIELD_H_ + +#include "toolchain/sem_ir/block_value_store.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::SemIR { + +// A field in a struct's type, such as `.a: i32` in `{.a: i32}`. +struct StructTypeField : Printable { + auto Print(llvm::raw_ostream& out) const -> void { + out << "{name_id: " << name_id << ", type_id: " << type_id << "}"; + } + + friend auto operator==(StructTypeField lhs, StructTypeField rhs) -> bool { + return std::memcmp(&lhs, &rhs, sizeof(StructTypeField)) == 0; + } + + NameId name_id; + TypeId type_id; +}; + +using StructTypeFieldsStore = BlockValueStore; + +// See common/hashing.h. Supports canonicalization of fields. +inline auto CarbonHashValue(const StructTypeField& value, uint64_t seed) + -> HashCode { + Hasher hasher(seed); + hasher.HashRaw(value); + return static_cast(hasher); +} + +} // namespace Carbon::SemIR + +#endif // CARBON_TOOLCHAIN_SEM_IR_STRUCT_TYPE_FIELD_H_ diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 4b42a0253be1..d4b03133c816 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -1117,22 +1117,7 @@ struct StructType { .constant_kind = InstConstantKind::Conditional}); TypeId type_id; - InstBlockId fields_id; -}; - -// A field in a struct's type, such as `.a: i32` in `{.a: i32}`. -// -// This instruction is an implementation detail of `StructType`, and doesn't -// produce a value. As a consequence, although there's a type for the field, the -// instruction has no type. -struct StructTypeField { - // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = InstKind::StructTypeField.Define( - {.ir_name = "struct_type_field", - .constant_kind = InstConstantKind::Conditional}); - - NameId name_id; - TypeId field_type_id; + StructTypeFieldsId fields_id; }; // A struct value. diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index 34456d1c4eb7..6d9126542be9 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -63,6 +63,7 @@ TEST(SemIRTest, YAML) { Pair("classes", Yaml::Mapping(SizeIs(0))), Pair("generics", Yaml::Mapping(SizeIs(0))), Pair("specifics", Yaml::Mapping(SizeIs(0))), + Pair("struct_type_fields", Yaml::Mapping(SizeIs(0))), Pair("types", Yaml::Mapping(Each(type_builtin))), Pair("type_blocks", Yaml::Mapping(SizeIs(Ge(1)))), Pair("insts",