From 2e4beaf8f0261d15fbc49ccec16fac1979e881bc Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 26 May 2023 14:42:45 -0700 Subject: [PATCH] Canonicalize struct types. (#2855) This adds canonicalization of struct types based on their type fields. It obsoletes the current CanImplicitAsStruct because the type ids should now be identical when they're structurally identical; there's only a reason to implicit CanImplicitAsStruct to detect _compatible_ conversions. The type fields themselves aren't canonicalized because it would need to be done during the first parse, and could yield name conflicts being associated with the wrong location. i.e.: ``` var x: {a: i32, a: i32}; var y: {a: i32, b: i32, a: i32}; ``` This should yield two separate name conflict diagnostics pointing at the type fields for each respective line, but if struct type fields were canonicalized then both would point at the first `a: i32` field definition. This isn't expected to be an issue for types because I'm trying to print those, but we may also end up with a "first defined at" situation in some cases (still, less confusing because the type should match). Regardless, I think individual fields gets much more awkward. --- .../lowering/testdata/struct/empty.carbon | 8 +-- .../testdata/struct/member_access.carbon | 7 +- .../lowering/testdata/struct/one_entry.carbon | 8 +-- .../testdata/struct/two_entries.carbon | 10 ++- toolchain/semantics/semantics_context.cpp | 70 +++++++++---------- toolchain/semantics/semantics_context.h | 38 ++++++++-- .../semantics/semantics_handle_struct.cpp | 13 +--- .../function/call/empty_struct.carbon | 36 ++++------ .../semantics/testdata/return/struct.carbon | 9 +-- .../semantics/testdata/struct/empty.carbon | 18 ++--- .../struct/fail_member_access_type.carbon | 13 ++-- .../struct/fail_non_member_access.carbon | 11 ++- .../testdata/struct/fail_type_assign.carbon | 2 - .../testdata/struct/member_access.carbon | 15 ++-- .../testdata/struct/one_entry.carbon | 18 ++--- .../testdata/struct/two_entries.carbon | 18 ++--- 16 files changed, 133 insertions(+), 161 deletions(-) diff --git a/toolchain/lowering/testdata/struct/empty.carbon b/toolchain/lowering/testdata/struct/empty.carbon index c7a313164011..418253f5f296 100644 --- a/toolchain/lowering/testdata/struct/empty.carbon +++ b/toolchain/lowering/testdata/struct/empty.carbon @@ -7,17 +7,15 @@ // CHECK:STDOUT: source_filename = "empty.carbon" // CHECK:STDOUT: // CHECK:STDOUT: %StructLiteralType = type {} -// CHECK:STDOUT: %StructLiteralType.0 = type {} -// CHECK:STDOUT: %StructLiteralType.1 = type {} // CHECK:STDOUT: // CHECK:STDOUT: define i32 @Run() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8 // CHECK:STDOUT: %var = alloca %StructLiteralType, align 8 -// CHECK:STDOUT: %StructLiteralValue1 = alloca %StructLiteralType.0, align 8 +// CHECK:STDOUT: %StructLiteralValue1 = alloca %StructLiteralType, align 8 // CHECK:STDOUT: store ptr %StructLiteralValue1, ptr %var, align 8 -// CHECK:STDOUT: %StructLiteralValue2 = alloca %StructLiteralType.1, align 8 -// CHECK:STDOUT: %var3 = alloca %StructLiteralType.1, align 8 +// CHECK:STDOUT: %StructLiteralValue2 = alloca %StructLiteralType, align 8 +// CHECK:STDOUT: %var3 = alloca %StructLiteralType, align 8 // CHECK:STDOUT: store ptr %var, ptr %var3, align 8 // CHECK:STDOUT: ret i32 0 // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/struct/member_access.carbon b/toolchain/lowering/testdata/struct/member_access.carbon index a4935a17b68f..5527b171f45b 100644 --- a/toolchain/lowering/testdata/struct/member_access.carbon +++ b/toolchain/lowering/testdata/struct/member_access.carbon @@ -7,15 +7,14 @@ // CHECK:STDOUT: source_filename = "member_access.carbon" // CHECK:STDOUT: // CHECK:STDOUT: %StructLiteralType = type { double, i32 } -// CHECK:STDOUT: %StructLiteralType.0 = type { double, i32 } // CHECK:STDOUT: // CHECK:STDOUT: define i32 @Run() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %var = alloca %StructLiteralType, align 8 -// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType.0, align 8 -// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 0 +// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8 +// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0 // CHECK:STDOUT: store double 0.000000e+00, ptr %a, align 8 -// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 1 +// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 1 // CHECK:STDOUT: store i32 1, ptr %b, align 4 // CHECK:STDOUT: store ptr %StructLiteralValue, ptr %var, align 8 // CHECK:STDOUT: %var1 = alloca i32, align 4 diff --git a/toolchain/lowering/testdata/struct/one_entry.carbon b/toolchain/lowering/testdata/struct/one_entry.carbon index b0b8b4672a4b..a41f45e8c68c 100644 --- a/toolchain/lowering/testdata/struct/one_entry.carbon +++ b/toolchain/lowering/testdata/struct/one_entry.carbon @@ -7,17 +7,15 @@ // CHECK:STDOUT: source_filename = "one_entry.carbon" // CHECK:STDOUT: // CHECK:STDOUT: %StructLiteralType = type { i32 } -// CHECK:STDOUT: %StructLiteralType.0 = type { i32 } -// CHECK:STDOUT: %StructLiteralType.1 = type { i32 } // CHECK:STDOUT: // CHECK:STDOUT: define i32 @Run() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %var = alloca %StructLiteralType, align 8 -// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType.0, align 8 -// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 0 +// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8 +// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0 // CHECK:STDOUT: store i32 4, ptr %a, align 4 // CHECK:STDOUT: store ptr %StructLiteralValue, ptr %var, align 8 -// CHECK:STDOUT: %var1 = alloca %StructLiteralType.1, align 8 +// CHECK:STDOUT: %var1 = alloca %StructLiteralType, align 8 // CHECK:STDOUT: store ptr %var, ptr %var1, align 8 // CHECK:STDOUT: ret i32 0 // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/struct/two_entries.carbon b/toolchain/lowering/testdata/struct/two_entries.carbon index 55c311b415d3..b09214aa9d61 100644 --- a/toolchain/lowering/testdata/struct/two_entries.carbon +++ b/toolchain/lowering/testdata/struct/two_entries.carbon @@ -7,19 +7,17 @@ // CHECK:STDOUT: source_filename = "two_entries.carbon" // CHECK:STDOUT: // CHECK:STDOUT: %StructLiteralType = type { i32, i32 } -// CHECK:STDOUT: %StructLiteralType.0 = type { i32, i32 } -// CHECK:STDOUT: %StructLiteralType.1 = type { i32, i32 } // CHECK:STDOUT: // CHECK:STDOUT: define i32 @Run() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %var = alloca %StructLiteralType, align 8 -// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType.0, align 8 -// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 0 +// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8 +// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0 // CHECK:STDOUT: store i32 1, ptr %a, align 4 -// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 1 +// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 1 // CHECK:STDOUT: store i32 2, ptr %b, align 4 // CHECK:STDOUT: store ptr %StructLiteralValue, ptr %var, align 8 -// CHECK:STDOUT: %var1 = alloca %StructLiteralType.1, align 8 +// CHECK:STDOUT: %var1 = alloca %StructLiteralType, align 8 // CHECK:STDOUT: store ptr %var, ptr %var1, align 8 // CHECK:STDOUT: ret i32 0 // CHECK:STDOUT: } diff --git a/toolchain/semantics/semantics_context.cpp b/toolchain/semantics/semantics_context.cpp index 256f6e098307..f93a5453ebe7 100644 --- a/toolchain/semantics/semantics_context.cpp +++ b/toolchain/semantics/semantics_context.cpp @@ -282,19 +282,7 @@ auto SemanticsContext::ImplicitAsImpl(SemanticsNodeId value_id, } } - if (value_type_id != SemanticsTypeId::TypeType && - as_type_id != SemanticsTypeId::TypeType) { - auto value_type = semantics_->GetNode(semantics_->GetType(value_type_id)); - auto as_type = semantics_->GetNode(semantics_->GetType(as_type_id)); - if (CanImplicitAsStruct(value_type, as_type)) { - // Under the current implementation, struct types are only allowed to - // ImplicitAs when they're equivalent. What's really missing is type - // consolidation such that this would fall under the above `value_type_id - // == as_type_id` case. In the future, this will need to handle actual - // conversions. - return ImplicitAsKind::Identical; - } - } + // TODO: Handle ImplicitAs for compatible structs and tuples. if (output_value_id != nullptr) { *output_value_id = SemanticsNodeId::BuiltinInvalidType; @@ -302,30 +290,6 @@ auto SemanticsContext::ImplicitAsImpl(SemanticsNodeId value_id, return ImplicitAsKind::Incompatible; } -auto SemanticsContext::CanImplicitAsStruct(SemanticsNode value_type, - SemanticsNode as_type) -> bool { - if (value_type.kind() != SemanticsNodeKind::StructType || - as_type.kind() != SemanticsNodeKind::StructType) { - return false; - } - auto value_type_refs = semantics_->GetNodeBlock(value_type.GetAsStructType()); - auto as_type_refs = semantics_->GetNodeBlock(as_type.GetAsStructType()); - if (value_type_refs.size() != as_type_refs.size()) { - return false; - } - - for (int i = 0; i < static_cast(value_type_refs.size()); ++i) { - auto value_type_field = semantics_->GetNode(value_type_refs[i]); - auto as_type_field = semantics_->GetNode(as_type_refs[i]); - if (value_type_field.type_id() != as_type_field.type_id() || - value_type_field.GetAsStructTypeField() != - as_type_field.GetAsStructTypeField()) { - return false; - } - } - return true; -} - auto SemanticsContext::ParamOrArgStart() -> void { params_or_args_stack_.Push(); } @@ -380,6 +344,38 @@ auto SemanticsContext::CanonicalizeType(SemanticsNodeId node_id) return type_id; } +auto SemanticsContext::CanonicalizeStructType(ParseTree::Node parse_node, + SemanticsNodeBlockId refs_id) + -> SemanticsTypeId { + // Construct the field structure for lookup. + auto refs = semantics_->GetNodeBlock(refs_id); + llvm::FoldingSetNodeID canonical_id; + for (const auto& ref_id : refs) { + auto ref = semantics_->GetNode(ref_id); + canonical_id.AddInteger(ref.GetAsStructTypeField().index); + canonical_id.AddInteger(ref.type_id().index); + } + + // If a struct with matching fields was already created, reuse it. + void* insert_pos; + auto* node = + canonical_struct_types_.FindNodeOrInsertPos(canonical_id, insert_pos); + if (node != nullptr) { + return node->type_id(); + } + + // The struct doesn't already exist, so create and store it as canonical. + auto node_id = AddNode(SemanticsNode::StructType::Make( + parse_node, SemanticsTypeId::TypeType, refs_id)); + auto type_id = semantics_->AddType(node_id); + CARBON_CHECK(canonical_types_.insert({node_id, type_id}).second); + canonical_struct_types_nodes_.push_back( + std::make_unique(canonical_id, type_id)); + canonical_struct_types_.InsertNode(canonical_struct_types_nodes_.back().get(), + insert_pos); + return type_id; +} + auto SemanticsContext::PrintForStackDump(llvm::raw_ostream& output) const -> void { node_stack_.PrintForStackDump(output); diff --git a/toolchain/semantics/semantics_context.h b/toolchain/semantics/semantics_context.h index 88624b1f540d..c46ce2d51bae 100644 --- a/toolchain/semantics/semantics_context.h +++ b/toolchain/semantics/semantics_context.h @@ -7,6 +7,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "toolchain/parser/parse_tree.h" #include "toolchain/semantics/semantics_ir.h" @@ -97,6 +98,16 @@ class SemanticsContext { // TODO: This should eventually return a type ID. auto CanonicalizeType(SemanticsNodeId node_id) -> SemanticsTypeId; + // Handles canonicalization of struct types. This may create a new struct type + // when it has a new structure, or reference an existing struct type when it + // duplicates a prior type. + // + // Individual struct type fields aren't canonicalized because they may have + // name conflicts or other diagnostics during creation, which can use the + // parse node. + auto CanonicalizeStructType(ParseTree::Node parse_node, + SemanticsNodeBlockId refs_id) -> SemanticsTypeId; + // Converts an expression for use as a type. // TODO: This should eventually return a type ID. auto ExpressionAsType(ParseTree::Node parse_node, SemanticsNodeId value_id) @@ -161,6 +172,19 @@ class SemanticsContext { Compatible, }; + // A FoldingSet node for a struct type. + class StructTypeNode : public llvm::FastFoldingSetNode { + public: + explicit StructTypeNode(const llvm::FoldingSetNodeID& node_id, + SemanticsTypeId type_id) + : llvm::FastFoldingSetNode(node_id), type_id_(type_id) {} + + auto type_id() -> SemanticsTypeId { return type_id_; } + + private: + SemanticsTypeId type_id_; + }; + // An entry in scope_stack_. struct ScopeStackEntry { // Names which are registered with name_lookup_, and will need to be @@ -185,11 +209,6 @@ class SemanticsContext { auto ImplicitAsImpl(SemanticsNodeId value_id, SemanticsTypeId as_type_id, SemanticsNodeId* output_value_id) -> ImplicitAsKind; - // Returns true if the ImplicitAs can use struct conversion. - // TODO: This currently only supports struct types that precisely match. - auto CanImplicitAsStruct(SemanticsNode value_type, SemanticsNode as_type) - -> bool; - auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); } // Tokens for getting data on literals. @@ -244,6 +263,15 @@ class SemanticsContext { // Tracks types which have been used, so that they aren't repeatedly added to // SemanticsIR. llvm::DenseMap canonical_types_; + + // Tracks struct type literals which have been defined, so that they aren't + // repeatedly redefined. + llvm::FoldingSet canonical_struct_types_; + + // Storage for the nodes in canonical_struct_types_. This stores in pointers + // so that canonical_struct_types_ can have stable pointers. + llvm::SmallVector> + canonical_struct_types_nodes_; }; // Parse node handlers. Returns false for unrecoverable errors. diff --git a/toolchain/semantics/semantics_handle_struct.cpp b/toolchain/semantics/semantics_handle_struct.cpp index 00165e9fba9b..177d57ec31a9 100644 --- a/toolchain/semantics/semantics_handle_struct.cpp +++ b/toolchain/semantics/semantics_handle_struct.cpp @@ -74,13 +74,7 @@ auto SemanticsHandleStructLiteral(SemanticsContext& context, ParseNodeKind::StructLiteralOrStructTypeLiteralStart); auto type_block_id = context.args_type_info_stack().Pop(); - // Construct a type for the literal. - // TODO: This should try to canonicalize the struct form before adding the - // node. - auto refs = context.semantics().GetNodeBlock(refs_id); - auto type_id = - context.CanonicalizeType(context.AddNode(SemanticsNode::StructType::Make( - parse_node, SemanticsTypeId::TypeType, type_block_id))); + auto type_id = context.CanonicalizeStructType(parse_node, type_block_id); auto value_id = context.AddNode( SemanticsNode::StructValue::Make(parse_node, type_id, refs_id)); @@ -114,9 +108,8 @@ auto SemanticsHandleStructTypeLiteral(SemanticsContext& context, CARBON_CHECK(refs_id != SemanticsNodeBlockId::Empty) << "{} is handled by StructLiteral."; - auto type_id = context.AddNode(SemanticsNode::StructType::Make( - parse_node, SemanticsTypeId::TypeType, refs_id)); - context.node_stack().Push(parse_node, type_id); + auto type_id = context.CanonicalizeStructType(parse_node, refs_id); + context.node_stack().Push(parse_node, context.semantics().GetType(type_id)); return true; } diff --git a/toolchain/semantics/testdata/function/call/empty_struct.carbon b/toolchain/semantics/testdata/function/call/empty_struct.carbon index 8cadd80ceb56..b6266c2c9bb8 100644 --- a/toolchain/semantics/testdata/function/call/empty_struct.carbon +++ b/toolchain/semantics/testdata/function/call/empty_struct.carbon @@ -5,7 +5,7 @@ // AUTOUPDATE // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: callables: [ -// CHECK:STDOUT: {param_refs: block2, return_type: type1}, +// CHECK:STDOUT: {param_refs: block2, return_type: type0}, // CHECK:STDOUT: {param_refs: block0}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ @@ -19,26 +19,22 @@ // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+4, // CHECK:STDOUT: nodeEmptyTupleType, -// CHECK:STDOUT: node+10, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: VarStorage, type: type0}, // CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node+2, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type1}, +// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: str1, arg1: callable0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2, type: type0}, -// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node+6, arg1: block4}, +// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node+5, arg1: block4}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: str2, arg1: callable1}, -// CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type3}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+11, type: type3}, -// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: callable0, type: type1}, -// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node+9, arg1: block5}, +// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+9, type: type0}, +// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: callable0, type: type0}, +// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node+8, arg1: block5}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -55,22 +51,20 @@ // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+14, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+10, -// CHECK:STDOUT: node+11, -// CHECK:STDOUT: node+12, -// CHECK:STDOUT: node+13, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: ] diff --git a/toolchain/semantics/testdata/return/struct.carbon b/toolchain/semantics/testdata/return/struct.carbon index 66e309301662..795e7006b466 100644 --- a/toolchain/semantics/testdata/return/struct.carbon +++ b/toolchain/semantics/testdata/return/struct.carbon @@ -19,7 +19,6 @@ // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+6, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, @@ -28,9 +27,8 @@ // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+3, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block4, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block5, type: type2}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7, type: type2}, +// CHECK:STDOUT: {kind: StructValue, arg0: block5, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6, type: type1}, // CHECK:STDOUT: {kind: FunctionDefinition, arg0: node+2, arg1: block3}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -40,7 +38,7 @@ // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -50,7 +48,6 @@ // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, -// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, diff --git a/toolchain/semantics/testdata/struct/empty.carbon b/toolchain/semantics/testdata/struct/empty.carbon index 9d8b6614c362..da7036b28a7d 100644 --- a/toolchain/semantics/testdata/struct/empty.carbon +++ b/toolchain/semantics/testdata/struct/empty.carbon @@ -16,22 +16,18 @@ // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+7, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: VarStorage, type: type0}, // CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node+2, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+5, type: type1}, -// CHECK:STDOUT: {kind: StructType, arg0: block0, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type2}, -// CHECK:STDOUT: {kind: VarStorage, type: type2}, -// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+9, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+9, arg1: node+2, type: type0}, +// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+4, type: type0}, +// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, type: type0}, +// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+7, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+7, arg1: node+2, type: type0}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -47,8 +43,6 @@ // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+10, -// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: ] diff --git a/toolchain/semantics/testdata/struct/fail_member_access_type.carbon b/toolchain/semantics/testdata/struct/fail_member_access_type.carbon index 4ad7e5983cb5..4b5366d6ec92 100644 --- a/toolchain/semantics/testdata/struct/fail_member_access_type.carbon +++ b/toolchain/semantics/testdata/struct/fail_member_access_type.carbon @@ -20,7 +20,6 @@ // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeFloatingPointType, // CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+7, // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ @@ -31,12 +30,11 @@ // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+8, type: type2}, -// CHECK:STDOUT: {kind: VarStorage, type: type3}, -// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+10, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+10, arg1: nodeInvalidType, type: typeInvalidType}, +// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+7, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, type: type2}, +// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+9, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+9, arg1: nodeInvalidType, type: typeInvalidType}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -53,7 +51,6 @@ // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, -// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, diff --git a/toolchain/semantics/testdata/struct/fail_non_member_access.carbon b/toolchain/semantics/testdata/struct/fail_non_member_access.carbon index 6451270e46c3..22f0fa2fad46 100644 --- a/toolchain/semantics/testdata/struct/fail_non_member_access.carbon +++ b/toolchain/semantics/testdata/struct/fail_non_member_access.carbon @@ -20,7 +20,6 @@ // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+7, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, @@ -30,12 +29,11 @@ // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+8, type: type2}, +// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+7, type: type1}, // CHECK:STDOUT: {kind: VarStorage, type: type0}, -// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+10, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+10, arg1: nodeInvalidType, type: typeInvalidType}, +// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+9, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+9, arg1: nodeInvalidType, type: typeInvalidType}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -52,7 +50,6 @@ // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, -// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, diff --git a/toolchain/semantics/testdata/struct/fail_type_assign.carbon b/toolchain/semantics/testdata/struct/fail_type_assign.carbon index 161b2b3cac85..a5ef2c2974b5 100644 --- a/toolchain/semantics/testdata/struct/fail_type_assign.carbon +++ b/toolchain/semantics/testdata/struct/fail_type_assign.carbon @@ -24,7 +24,6 @@ // CHECK:STDOUT: {kind: VarStorage, type: type1}, // CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+2, type: type1}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, // CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: nodeInvalidType, type: typeInvalidType}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -37,7 +36,6 @@ // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, -// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, diff --git a/toolchain/semantics/testdata/struct/member_access.carbon b/toolchain/semantics/testdata/struct/member_access.carbon index 2eb687d557f4..6c34b16c14a1 100644 --- a/toolchain/semantics/testdata/struct/member_access.carbon +++ b/toolchain/semantics/testdata/struct/member_access.carbon @@ -23,7 +23,6 @@ // CHECK:STDOUT: nodeFloatingPointType, // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+11, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, @@ -37,16 +36,15 @@ // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, type: type1}, // CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type1}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+12, type: type3}, +// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+11, type: type2}, // CHECK:STDOUT: {kind: VarStorage, type: type1}, -// CHECK:STDOUT: {kind: BindName, arg0: str3, arg1: node+14, type: type1}, +// CHECK:STDOUT: {kind: BindName, arg0: str3, arg1: node+13, type: type1}, // CHECK:STDOUT: {kind: StructMemberAccess, arg0: node+3, arg1: member1, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+16, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+13, arg1: node+15, type: type1}, // CHECK:STDOUT: {kind: VarStorage, type: type1}, -// CHECK:STDOUT: {kind: BindName, arg0: str4, arg1: node+18, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+18, arg1: node+14, type: type1}, +// CHECK:STDOUT: {kind: BindName, arg0: str4, arg1: node+17, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+17, arg1: node+13, type: type1}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -70,7 +68,6 @@ // CHECK:STDOUT: node+17, // CHECK:STDOUT: node+18, // CHECK:STDOUT: node+19, -// CHECK:STDOUT: node+20, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, diff --git a/toolchain/semantics/testdata/struct/one_entry.carbon b/toolchain/semantics/testdata/struct/one_entry.carbon index 213916d83d62..3a21a6e270e0 100644 --- a/toolchain/semantics/testdata/struct/one_entry.carbon +++ b/toolchain/semantics/testdata/struct/one_entry.carbon @@ -19,8 +19,6 @@ // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+7, -// CHECK:STDOUT: node+11, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, @@ -30,14 +28,12 @@ // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+8, type: type2}, +// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+7, type: type1}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block5, type: typeTypeType}, -// CHECK:STDOUT: {kind: VarStorage, type: type3}, -// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+12, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+12, arg1: node+2, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, type: type1}, +// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+10, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+10, arg1: node+2, type: type1}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -55,8 +51,6 @@ // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, -// CHECK:STDOUT: node+13, -// CHECK:STDOUT: node+14, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -68,7 +62,7 @@ // CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: ] diff --git a/toolchain/semantics/testdata/struct/two_entries.carbon b/toolchain/semantics/testdata/struct/two_entries.carbon index 01f45c1ef640..42098be6e5d1 100644 --- a/toolchain/semantics/testdata/struct/two_entries.carbon +++ b/toolchain/semantics/testdata/struct/two_entries.carbon @@ -21,8 +21,6 @@ // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+11, -// CHECK:STDOUT: node+16, // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, @@ -36,15 +34,13 @@ // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+12, type: type2}, +// CHECK:STDOUT: {kind: StructValue, arg0: block4, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+11, type: type1}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block5, type: typeTypeType}, -// CHECK:STDOUT: {kind: VarStorage, type: type3}, -// CHECK:STDOUT: {kind: BindName, arg0: str3, arg1: node+17, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+17, arg1: node+3, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, type: type1}, +// CHECK:STDOUT: {kind: BindName, arg0: str3, arg1: node+15, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+3, type: type1}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -66,8 +62,6 @@ // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, // CHECK:STDOUT: node+17, -// CHECK:STDOUT: node+18, -// CHECK:STDOUT: node+19, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -82,8 +76,8 @@ // CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, -// CHECK:STDOUT: node+15, // CHECK:STDOUT: ], // CHECK:STDOUT: ]