From 9cb6b7190f0b85966679eb946d733927599bf57e Mon Sep 17 00:00:00 2001 From: Geoff Romer Date: Thu, 20 Feb 2025 13:05:56 -0800 Subject: [PATCH 01/56] Configure lldb to support /proc/self/cwd paths (#4992) On my machine, the LLVM debug information seems to use source file paths relative to `/proc/self/cwd`, which is the current working directory of whatever process refers to it. Consequently, VSCode can't find those files, because it has a different current working directory. This change enables VSCode to rewrite those paths to a usable form. --- .vscode/lldb_launch.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/lldb_launch.json b/.vscode/lldb_launch.json index 4838129d513cc..007c16662665f 100644 --- a/.vscode/lldb_launch.json +++ b/.vscode/lldb_launch.json @@ -12,7 +12,10 @@ "command script import external/+llvm_project+llvm-project/llvm/utils/lldbDataFormatters.py", "settings set target.source-map \".\" \"${workspaceFolder}\"" ], - "env": { "TEST_TMPDIR": "/tmp" } + "env": { "TEST_TMPDIR": "/tmp" }, + "sourceMap": { + "/proc/self/cwd/": "${workspaceFolder}" + } }, { "type": "lldb-dap", From c2bc3c1719eddd30dfab791d07b2c7fdeabc8982 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 20 Feb 2025 13:06:18 -0800 Subject: [PATCH 02/56] Find the exe prior to busybox resolution (#4993) This is required to make $PATH entries work. --- toolchain/install/busybox_main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/toolchain/install/busybox_main.cpp b/toolchain/install/busybox_main.cpp index 9dbca3336f74e..c4a87635a839b 100644 --- a/toolchain/install/busybox_main.cpp +++ b/toolchain/install/busybox_main.cpp @@ -25,12 +25,13 @@ static auto Main(int argc, char** argv) -> ErrorOr { InitLLVM init_llvm(argc, argv); // Start by resolving any symlinks. - CARBON_ASSIGN_OR_RETURN(auto busybox_info, GetBusyboxInfo(argv[0])); + CARBON_ASSIGN_OR_RETURN(auto busybox_info, + GetBusyboxInfo(FindExecutablePath(argv[0]))); auto fs = llvm::vfs::getRealFileSystem(); // Resolve paths before calling SetWorkingDirForBazel. - std::string exe_path = FindExecutablePath(busybox_info.bin_path.string()); + std::string exe_path = busybox_info.bin_path.string(); const auto install_paths = InstallPaths::MakeExeRelative(exe_path); if (install_paths.error()) { return Error(*install_paths.error()); From fc7b0016cec091c426c6fd456e30ca43e9e979e1 Mon Sep 17 00:00:00 2001 From: josh11b <15258583+josh11b@users.noreply.github.com> Date: Thu, 20 Feb 2025 14:26:10 -0800 Subject: [PATCH 03/56] Tuples and structs with abstract types are abstract (#4986) Expands the CompleteTypeInfo to include information about abstract classes and computes that information as part of completing the type. --------- Co-authored-by: Josh L Co-authored-by: Richard Smith Co-authored-by: Dana Jansens --- .../testdata/basics/builtin_insts.carbon | 9 +- ....carbon => fail_abstract_in_struct.carbon} | 147 +++++++---- ...e.carbon => fail_abstract_in_tuple.carbon} | 167 +++++++----- toolchain/check/type_completion.cpp | 248 ++++++++++-------- .../multifile_raw_and_textual_ir.carbon | 33 ++- .../testdata/compile/multifile_raw_ir.carbon | 33 ++- .../compile/raw_and_textual_ir.carbon | 21 +- .../driver/testdata/compile/raw_ir.carbon | 33 ++- toolchain/sem_ir/file.cpp | 14 +- toolchain/sem_ir/type.h | 30 ++- toolchain/sem_ir/type_info.h | 3 + 11 files changed, 450 insertions(+), 288 deletions(-) rename toolchain/check/testdata/class/no_prelude/{todo_fail_abstract_in_struct.carbon => fail_abstract_in_struct.carbon} (72%) rename toolchain/check/testdata/class/no_prelude/{todo_fail_abstract_in_tuple.carbon => fail_abstract_in_tuple.carbon} (68%) diff --git a/toolchain/check/testdata/basics/builtin_insts.carbon b/toolchain/check/testdata/basics/builtin_insts.carbon index 2bd2b79b660a6..c4aea2c280aed 100644 --- a/toolchain/check/testdata/basics/builtin_insts.carbon +++ b/toolchain/check/testdata/basics/builtin_insts.carbon @@ -26,9 +26,12 @@ // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: insts: diff --git a/toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_struct.carbon b/toolchain/check/testdata/class/no_prelude/fail_abstract_in_struct.carbon similarity index 72% rename from toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_struct.carbon rename to toolchain/check/testdata/class/no_prelude/fail_abstract_in_struct.carbon index f67e8b1c2f1a2..8d124990feee6 100644 --- a/toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_struct.carbon +++ b/toolchain/check/testdata/class/no_prelude/fail_abstract_in_struct.carbon @@ -4,25 +4,39 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_struct.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/fail_abstract_in_struct.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_struct.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/fail_abstract_in_struct.carbon -// --- todo_fail_abstract_field.carbon +// --- fail_abstract_field.carbon library "[[@TEST_NAME]]"; abstract class Abstract1 {} class Contains { + // CHECK:STDERR: fail_abstract_field.carbon:[[@LINE+7]]:10: error: field has abstract type `{.m1: Abstract1}` [AbstractTypeInFieldDecl] + // CHECK:STDERR: var a: {.m1: Abstract1}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_field.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract1 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var a: {.m1: Abstract1}; } -// --- todo_fail_abstract_var.carbon +// --- fail_abstract_var.carbon library "[[@TEST_NAME]]"; abstract class Abstract2 {} fn Var() { + // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:10: error: binding pattern has abstract type `{.m2: Abstract2}` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v: {.m2: Abstract2}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract2 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v: {.m2: Abstract2}; } @@ -36,31 +50,52 @@ fn F(a: Abstract3) { let l: {.m3: Abstract3} = {.m3 = a}; } -// --- todo_fail_abstract_twice.carbon +// --- fail_abstract_twice.carbon library "[[@TEST_NAME]]"; abstract class Abstract4 {} abstract class Abstract5 {} fn Var2() { + // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `{.m4: Abstract4, .m5: Abstract5}` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v2: {.m4: Abstract4, .m5: Abstract5}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE-7]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract4 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v2: {.m4: Abstract4, .m5: Abstract5}; } -// --- todo_fail_abstract_first.carbon +// --- fail_abstract_first.carbon library "[[@TEST_NAME]]"; abstract class Abstract6 {} fn Var3() { + // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `{.m6: Abstract6, .c1: ()}` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v3: {.m6: Abstract6, .c1: ()}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract6 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v3: {.m6: Abstract6, .c1: ()}; } -// --- todo_fail_abstract_second.carbon +// --- fail_abstract_second.carbon library "[[@TEST_NAME]]"; abstract class Abstract7 {} fn Var4() { + // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `{.c2: (), .m7: Abstract7}` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v4: {.c2: (), .m7: Abstract7}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract7 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v4: {.c2: (), .m7: Abstract7}; } @@ -69,26 +104,30 @@ library "[[@TEST_NAME]]"; abstract class Abstract {} -// --- todo_fail_import.carbon +// --- fail_import.carbon library "[[@TEST_NAME]]"; import library "lib"; fn Var5() { + // CHECK:STDERR: fail_import.carbon:[[@LINE+8]]:11: error: binding pattern has abstract type `{.m: Abstract}` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v5: {.m: Abstract}; + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: fail_import.carbon:[[@LINE-6]]:1: in import [InImport] + // CHECK:STDERR: lib.carbon:3:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v5: {.m: Abstract}; } -// CHECK:STDOUT: --- todo_fail_abstract_field.carbon +// CHECK:STDOUT: --- fail_abstract_field.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract1: type = class_type @Abstract1 [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Contains: type = class_type @Contains [concrete] -// CHECK:STDOUT: %struct_type.m1.198: type = struct_type {.m1: %Abstract1} [concrete] -// CHECK:STDOUT: %Contains.elem: type = unbound_element_type %Contains, %struct_type.m1.198 [concrete] -// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %struct_type.m1.198} [concrete] -// CHECK:STDOUT: %complete_type.be2: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -101,7 +140,7 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Abstract1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -109,21 +148,21 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Contains { -// CHECK:STDOUT: %.loc6_8: %Contains.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %.loc13_8: = field_decl a, element0 [concrete] // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc6_3: %Contains.elem = var_pattern %.loc6_8 +// CHECK:STDOUT: %.loc13_3: = var_pattern %.loc13_8 // CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %Contains.elem = var -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.be2] +// CHECK:STDOUT: %.var: ref = var +// CHECK:STDOUT: %complete_type: = complete_type_witness [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%Contains // CHECK:STDOUT: .Abstract1 = -// CHECK:STDOUT: .a = %.loc6_8 +// CHECK:STDOUT: .a = %.loc13_8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_var.carbon +// CHECK:STDOUT: --- fail_abstract_var.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract2: type = class_type @Abstract2 [concrete] @@ -154,15 +193,15 @@ fn Var5() { // CHECK:STDOUT: fn @Var() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v.patt: %struct_type.m2.155 = binding_pattern v -// CHECK:STDOUT: %.loc6_3: %struct_type.m2.155 = var_pattern %v.patt +// CHECK:STDOUT: %v.patt: = binding_pattern v +// CHECK:STDOUT: %.loc13_3: = var_pattern %v.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v.var: ref %struct_type.m2.155 = var v -// CHECK:STDOUT: %.loc6_25: type = splice_block %struct_type.m2 [concrete = constants.%struct_type.m2.155] { +// CHECK:STDOUT: %v.var: ref = var v +// CHECK:STDOUT: %.loc13_25: type = splice_block %struct_type.m2 [concrete = constants.%struct_type.m2.155] { // CHECK:STDOUT: %Abstract2.ref: type = name_ref Abstract2, file.%Abstract2.decl [concrete = constants.%Abstract2] // CHECK:STDOUT: %struct_type.m2: type = struct_type {.m2: %Abstract2} [concrete = constants.%struct_type.m2.155] // CHECK:STDOUT: } -// CHECK:STDOUT: %v: ref %struct_type.m2.155 = bind_name v, %v.var +// CHECK:STDOUT: %v: = bind_name v, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -216,7 +255,7 @@ fn Var5() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_twice.carbon +// CHECK:STDOUT: --- fail_abstract_twice.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract4: type = class_type @Abstract4 [concrete] @@ -258,20 +297,20 @@ fn Var5() { // CHECK:STDOUT: fn @Var2() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v2.patt: %struct_type.m4.m5.c86 = binding_pattern v2 -// CHECK:STDOUT: %.loc7_3: %struct_type.m4.m5.c86 = var_pattern %v2.patt +// CHECK:STDOUT: %v2.patt: = binding_pattern v2 +// CHECK:STDOUT: %.loc14_3: = var_pattern %v2.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v2.var: ref %struct_type.m4.m5.c86 = var v2 -// CHECK:STDOUT: %.loc7_42: type = splice_block %struct_type.m4.m5 [concrete = constants.%struct_type.m4.m5.c86] { +// CHECK:STDOUT: %v2.var: ref = var v2 +// CHECK:STDOUT: %.loc14_42: type = splice_block %struct_type.m4.m5 [concrete = constants.%struct_type.m4.m5.c86] { // CHECK:STDOUT: %Abstract4.ref: type = name_ref Abstract4, file.%Abstract4.decl [concrete = constants.%Abstract4] // CHECK:STDOUT: %Abstract5.ref: type = name_ref Abstract5, file.%Abstract5.decl [concrete = constants.%Abstract5] // CHECK:STDOUT: %struct_type.m4.m5: type = struct_type {.m4: %Abstract4, .m5: %Abstract5} [concrete = constants.%struct_type.m4.m5.c86] // CHECK:STDOUT: } -// CHECK:STDOUT: %v2: ref %struct_type.m4.m5.c86 = bind_name v2, %v2.var +// CHECK:STDOUT: %v2: = bind_name v2, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_first.carbon +// CHECK:STDOUT: --- fail_abstract_first.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract6: type = class_type @Abstract6 [concrete] @@ -303,21 +342,21 @@ fn Var5() { // CHECK:STDOUT: fn @Var3() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v3.patt: %struct_type.m6.c1.489 = binding_pattern v3 -// CHECK:STDOUT: %.loc6_3: %struct_type.m6.c1.489 = var_pattern %v3.patt +// CHECK:STDOUT: %v3.patt: = binding_pattern v3 +// CHECK:STDOUT: %.loc13_3: = var_pattern %v3.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v3.var: ref %struct_type.m6.c1.489 = var v3 -// CHECK:STDOUT: %.loc6_35: type = splice_block %struct_type.m6.c1 [concrete = constants.%struct_type.m6.c1.489] { +// CHECK:STDOUT: %v3.var: ref = var v3 +// CHECK:STDOUT: %.loc13_35: type = splice_block %struct_type.m6.c1 [concrete = constants.%struct_type.m6.c1.489] { // CHECK:STDOUT: %Abstract6.ref: type = name_ref Abstract6, file.%Abstract6.decl [concrete = constants.%Abstract6] -// CHECK:STDOUT: %.loc6_34.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc6_34.2: type = converted %.loc6_34.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc13_34.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_34.2: type = converted %.loc13_34.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %struct_type.m6.c1: type = struct_type {.m6: %Abstract6, .c1: %empty_tuple.type} [concrete = constants.%struct_type.m6.c1.489] // CHECK:STDOUT: } -// CHECK:STDOUT: %v3: ref %struct_type.m6.c1.489 = bind_name v3, %v3.var +// CHECK:STDOUT: %v3: = bind_name v3, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_second.carbon +// CHECK:STDOUT: --- fail_abstract_second.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract7: type = class_type @Abstract7 [concrete] @@ -349,17 +388,17 @@ fn Var5() { // CHECK:STDOUT: fn @Var4() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v4.patt: %struct_type.c2.m7.4a7 = binding_pattern v4 -// CHECK:STDOUT: %.loc6_3: %struct_type.c2.m7.4a7 = var_pattern %v4.patt +// CHECK:STDOUT: %v4.patt: = binding_pattern v4 +// CHECK:STDOUT: %.loc13_3: = var_pattern %v4.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v4.var: ref %struct_type.c2.m7.4a7 = var v4 -// CHECK:STDOUT: %.loc6_35: type = splice_block %struct_type.c2.m7 [concrete = constants.%struct_type.c2.m7.4a7] { -// CHECK:STDOUT: %.loc6_18.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc6_18.2: type = converted %.loc6_18.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %v4.var: ref = var v4 +// CHECK:STDOUT: %.loc13_35: type = splice_block %struct_type.c2.m7 [concrete = constants.%struct_type.c2.m7.4a7] { +// CHECK:STDOUT: %.loc13_18.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_18.2: type = converted %.loc13_18.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %Abstract7.ref: type = name_ref Abstract7, file.%Abstract7.decl [concrete = constants.%Abstract7] // CHECK:STDOUT: %struct_type.c2.m7: type = struct_type {.c2: %empty_tuple.type, .m7: %Abstract7} [concrete = constants.%struct_type.c2.m7.4a7] // CHECK:STDOUT: } -// CHECK:STDOUT: %v4: ref %struct_type.c2.m7.4a7 = bind_name v4, %v4.var +// CHECK:STDOUT: %v4: = bind_name v4, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -386,7 +425,7 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_import.carbon +// CHECK:STDOUT: --- fail_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Var5.type: type = fn_type @Var5 [concrete] @@ -422,15 +461,15 @@ fn Var5() { // CHECK:STDOUT: fn @Var5() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v5.patt: %struct_type.m.50b = binding_pattern v5 -// CHECK:STDOUT: %.loc6_3: %struct_type.m.50b = var_pattern %v5.patt +// CHECK:STDOUT: %v5.patt: = binding_pattern v5 +// CHECK:STDOUT: %.loc14_3: = var_pattern %v5.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v5.var: ref %struct_type.m.50b = var v5 -// CHECK:STDOUT: %.loc6_24: type = splice_block %struct_type.m [concrete = constants.%struct_type.m.50b] { +// CHECK:STDOUT: %v5.var: ref = var v5 +// CHECK:STDOUT: %.loc14_24: type = splice_block %struct_type.m [concrete = constants.%struct_type.m.50b] { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, imports.%Main.Abstract [concrete = constants.%Abstract] // CHECK:STDOUT: %struct_type.m: type = struct_type {.m: %Abstract} [concrete = constants.%struct_type.m.50b] // CHECK:STDOUT: } -// CHECK:STDOUT: %v5: ref %struct_type.m.50b = bind_name v5, %v5.var +// CHECK:STDOUT: %v5: = bind_name v5, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_tuple.carbon b/toolchain/check/testdata/class/no_prelude/fail_abstract_in_tuple.carbon similarity index 68% rename from toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_tuple.carbon rename to toolchain/check/testdata/class/no_prelude/fail_abstract_in_tuple.carbon index ac468bc1c87a8..f95e5469b1997 100644 --- a/toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_tuple.carbon +++ b/toolchain/check/testdata/class/no_prelude/fail_abstract_in_tuple.carbon @@ -4,25 +4,39 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_tuple.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/fail_abstract_in_tuple.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/todo_fail_abstract_in_tuple.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/fail_abstract_in_tuple.carbon -// --- todo_fail_abstract_field.carbon +// --- fail_abstract_field.carbon library "[[@TEST_NAME]]"; abstract class Abstract1 {} class Contains { + // CHECK:STDERR: fail_abstract_field.carbon:[[@LINE+7]]:10: error: field has abstract type `(Abstract1,)` [AbstractTypeInFieldDecl] + // CHECK:STDERR: var a: (Abstract1,); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_field.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract1 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var a: (Abstract1,); } -// --- todo_fail_abstract_var.carbon +// --- fail_abstract_var.carbon library "[[@TEST_NAME]]"; abstract class Abstract2 {} fn Var() { + // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE+7]]:10: error: binding pattern has abstract type `(Abstract2,)` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v: (Abstract2,); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_var.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract2 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v: (Abstract2,); } @@ -36,31 +50,52 @@ fn F(a: Abstract3) { let l: (Abstract3,) = (a,); } -// --- todo_fail_abstract_twice.carbon +// --- fail_abstract_twice.carbon library "[[@TEST_NAME]]"; abstract class Abstract4 {} abstract class Abstract5 {} fn Var2() { + // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `(Abstract4, Abstract5)` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v2: (Abstract4, Abstract5); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_twice.carbon:[[@LINE-7]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract4 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v2: (Abstract4, Abstract5); } -// --- todo_fail_abstract_first.carbon +// --- fail_abstract_first.carbon library "[[@TEST_NAME]]"; abstract class Abstract6 {} fn Var3() { + // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `(Abstract6, {})` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v3: (Abstract6, {}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_first.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract6 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v3: (Abstract6, {}); } -// --- todo_fail_abstract_second.carbon +// --- fail_abstract_second.carbon library "[[@TEST_NAME]]"; abstract class Abstract7 {} fn Var4() { + // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE+7]]:11: error: binding pattern has abstract type `({}, Abstract7)` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v4: ({}, Abstract7); + // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_abstract_second.carbon:[[@LINE-6]]:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract7 {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v4: ({}, Abstract7); } @@ -69,26 +104,30 @@ library "[[@TEST_NAME]]"; abstract class Abstract {} -// --- todo_fail_import.carbon +// --- fail_import.carbon library "[[@TEST_NAME]]"; import library "lib"; fn Var5() { + // CHECK:STDERR: fail_import.carbon:[[@LINE+8]]:11: error: binding pattern has abstract type `(Abstract,)` in `var` pattern [AbstractTypeInVarPattern] + // CHECK:STDERR: var v5: (Abstract,); + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: fail_import.carbon:[[@LINE-6]]:1: in import [InImport] + // CHECK:STDERR: lib.carbon:3:1: note: uses class that was declared abstract here [ClassAbstractHere] + // CHECK:STDERR: abstract class Abstract {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: var v5: (Abstract,); } -// CHECK:STDOUT: --- todo_fail_abstract_field.carbon +// CHECK:STDOUT: --- fail_abstract_field.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract1: type = class_type @Abstract1 [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Contains: type = class_type @Contains [concrete] -// CHECK:STDOUT: %tuple.type.f19: type = tuple_type (%Abstract1) [concrete] -// CHECK:STDOUT: %Contains.elem: type = unbound_element_type %Contains, %tuple.type.f19 [concrete] -// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %tuple.type.f19} [concrete] -// CHECK:STDOUT: %complete_type.90b: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -101,7 +140,7 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Abstract1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -109,21 +148,21 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Contains { -// CHECK:STDOUT: %.loc6_8: %Contains.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %.loc13_8: = field_decl a, element0 [concrete] // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc6_3: %Contains.elem = var_pattern %.loc6_8 +// CHECK:STDOUT: %.loc13_3: = var_pattern %.loc13_8 // CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %Contains.elem = var -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.90b] +// CHECK:STDOUT: %.var: ref = var +// CHECK:STDOUT: %complete_type: = complete_type_witness [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%Contains // CHECK:STDOUT: .Abstract1 = -// CHECK:STDOUT: .a = %.loc6_8 +// CHECK:STDOUT: .a = %.loc13_8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_var.carbon +// CHECK:STDOUT: --- fail_abstract_var.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract2: type = class_type @Abstract2 [concrete] @@ -155,16 +194,16 @@ fn Var5() { // CHECK:STDOUT: fn @Var() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v.patt: %tuple.type.ac6 = binding_pattern v -// CHECK:STDOUT: %.loc6_3: %tuple.type.ac6 = var_pattern %v.patt +// CHECK:STDOUT: %v.patt: = binding_pattern v +// CHECK:STDOUT: %.loc13_3: = var_pattern %v.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v.var: ref %tuple.type.ac6 = var v -// CHECK:STDOUT: %.loc6_21.1: type = splice_block %.loc6_21.3 [concrete = constants.%tuple.type.ac6] { +// CHECK:STDOUT: %v.var: ref = var v +// CHECK:STDOUT: %.loc13_21.1: type = splice_block %.loc13_21.3 [concrete = constants.%tuple.type.ac6] { // CHECK:STDOUT: %Abstract2.ref: type = name_ref Abstract2, file.%Abstract2.decl [concrete = constants.%Abstract2] -// CHECK:STDOUT: %.loc6_21.2: %tuple.type.85c = tuple_literal (%Abstract2.ref) -// CHECK:STDOUT: %.loc6_21.3: type = converted %.loc6_21.2, constants.%tuple.type.ac6 [concrete = constants.%tuple.type.ac6] +// CHECK:STDOUT: %.loc13_21.2: %tuple.type.85c = tuple_literal (%Abstract2.ref) +// CHECK:STDOUT: %.loc13_21.3: type = converted %.loc13_21.2, constants.%tuple.type.ac6 [concrete = constants.%tuple.type.ac6] // CHECK:STDOUT: } -// CHECK:STDOUT: %v: ref %tuple.type.ac6 = bind_name v, %v.var +// CHECK:STDOUT: %v: = bind_name v, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -220,7 +259,7 @@ fn Var5() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_twice.carbon +// CHECK:STDOUT: --- fail_abstract_twice.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract4: type = class_type @Abstract4 [concrete] @@ -263,21 +302,21 @@ fn Var5() { // CHECK:STDOUT: fn @Var2() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v2.patt: %tuple.type.e3e = binding_pattern v2 -// CHECK:STDOUT: %.loc7_3: %tuple.type.e3e = var_pattern %v2.patt +// CHECK:STDOUT: %v2.patt: = binding_pattern v2 +// CHECK:STDOUT: %.loc14_3: = var_pattern %v2.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v2.var: ref %tuple.type.e3e = var v2 -// CHECK:STDOUT: %.loc7_32.1: type = splice_block %.loc7_32.3 [concrete = constants.%tuple.type.e3e] { +// CHECK:STDOUT: %v2.var: ref = var v2 +// CHECK:STDOUT: %.loc14_32.1: type = splice_block %.loc14_32.3 [concrete = constants.%tuple.type.e3e] { // CHECK:STDOUT: %Abstract4.ref: type = name_ref Abstract4, file.%Abstract4.decl [concrete = constants.%Abstract4] // CHECK:STDOUT: %Abstract5.ref: type = name_ref Abstract5, file.%Abstract5.decl [concrete = constants.%Abstract5] -// CHECK:STDOUT: %.loc7_32.2: %tuple.type.24b = tuple_literal (%Abstract4.ref, %Abstract5.ref) -// CHECK:STDOUT: %.loc7_32.3: type = converted %.loc7_32.2, constants.%tuple.type.e3e [concrete = constants.%tuple.type.e3e] +// CHECK:STDOUT: %.loc14_32.2: %tuple.type.24b = tuple_literal (%Abstract4.ref, %Abstract5.ref) +// CHECK:STDOUT: %.loc14_32.3: type = converted %.loc14_32.2, constants.%tuple.type.e3e [concrete = constants.%tuple.type.e3e] // CHECK:STDOUT: } -// CHECK:STDOUT: %v2: ref %tuple.type.e3e = bind_name v2, %v2.var +// CHECK:STDOUT: %v2: = bind_name v2, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_first.carbon +// CHECK:STDOUT: --- fail_abstract_first.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract6: type = class_type @Abstract6 [concrete] @@ -309,22 +348,22 @@ fn Var5() { // CHECK:STDOUT: fn @Var3() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v3.patt: %tuple.type.d93 = binding_pattern v3 -// CHECK:STDOUT: %.loc6_3: %tuple.type.d93 = var_pattern %v3.patt +// CHECK:STDOUT: %v3.patt: = binding_pattern v3 +// CHECK:STDOUT: %.loc13_3: = var_pattern %v3.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v3.var: ref %tuple.type.d93 = var v3 -// CHECK:STDOUT: %.loc6_25.1: type = splice_block %.loc6_25.4 [concrete = constants.%tuple.type.d93] { +// CHECK:STDOUT: %v3.var: ref = var v3 +// CHECK:STDOUT: %.loc13_25.1: type = splice_block %.loc13_25.4 [concrete = constants.%tuple.type.d93] { // CHECK:STDOUT: %Abstract6.ref: type = name_ref Abstract6, file.%Abstract6.decl [concrete = constants.%Abstract6] -// CHECK:STDOUT: %.loc6_24: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc6_25.2: %tuple.type.159 = tuple_literal (%Abstract6.ref, %.loc6_24) -// CHECK:STDOUT: %.loc6_25.3: type = converted %.loc6_24, constants.%empty_struct_type [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc6_25.4: type = converted %.loc6_25.2, constants.%tuple.type.d93 [concrete = constants.%tuple.type.d93] +// CHECK:STDOUT: %.loc13_24: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc13_25.2: %tuple.type.159 = tuple_literal (%Abstract6.ref, %.loc13_24) +// CHECK:STDOUT: %.loc13_25.3: type = converted %.loc13_24, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc13_25.4: type = converted %.loc13_25.2, constants.%tuple.type.d93 [concrete = constants.%tuple.type.d93] // CHECK:STDOUT: } -// CHECK:STDOUT: %v3: ref %tuple.type.d93 = bind_name v3, %v3.var +// CHECK:STDOUT: %v3: = bind_name v3, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_abstract_second.carbon +// CHECK:STDOUT: --- fail_abstract_second.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract7: type = class_type @Abstract7 [concrete] @@ -356,18 +395,18 @@ fn Var5() { // CHECK:STDOUT: fn @Var4() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v4.patt: %tuple.type.919 = binding_pattern v4 -// CHECK:STDOUT: %.loc6_3: %tuple.type.919 = var_pattern %v4.patt +// CHECK:STDOUT: %v4.patt: = binding_pattern v4 +// CHECK:STDOUT: %.loc13_3: = var_pattern %v4.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v4.var: ref %tuple.type.919 = var v4 -// CHECK:STDOUT: %.loc6_25.1: type = splice_block %.loc6_25.4 [concrete = constants.%tuple.type.919] { -// CHECK:STDOUT: %.loc6_13: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %v4.var: ref = var v4 +// CHECK:STDOUT: %.loc13_25.1: type = splice_block %.loc13_25.4 [concrete = constants.%tuple.type.919] { +// CHECK:STDOUT: %.loc13_13: %empty_struct_type = struct_literal () // CHECK:STDOUT: %Abstract7.ref: type = name_ref Abstract7, file.%Abstract7.decl [concrete = constants.%Abstract7] -// CHECK:STDOUT: %.loc6_25.2: %tuple.type.c8c = tuple_literal (%.loc6_13, %Abstract7.ref) -// CHECK:STDOUT: %.loc6_25.3: type = converted %.loc6_13, constants.%empty_struct_type [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc6_25.4: type = converted %.loc6_25.2, constants.%tuple.type.919 [concrete = constants.%tuple.type.919] +// CHECK:STDOUT: %.loc13_25.2: %tuple.type.c8c = tuple_literal (%.loc13_13, %Abstract7.ref) +// CHECK:STDOUT: %.loc13_25.3: type = converted %.loc13_13, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc13_25.4: type = converted %.loc13_25.2, constants.%tuple.type.919 [concrete = constants.%tuple.type.919] // CHECK:STDOUT: } -// CHECK:STDOUT: %v4: ref %tuple.type.919 = bind_name v4, %v4.var +// CHECK:STDOUT: %v4: = bind_name v4, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -394,7 +433,7 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- todo_fail_import.carbon +// CHECK:STDOUT: --- fail_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Var5.type: type = fn_type @Var5 [concrete] @@ -431,16 +470,16 @@ fn Var5() { // CHECK:STDOUT: fn @Var5() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v5.patt: %tuple.type.555 = binding_pattern v5 -// CHECK:STDOUT: %.loc6_3: %tuple.type.555 = var_pattern %v5.patt +// CHECK:STDOUT: %v5.patt: = binding_pattern v5 +// CHECK:STDOUT: %.loc14_3: = var_pattern %v5.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %v5.var: ref %tuple.type.555 = var v5 -// CHECK:STDOUT: %.loc6_21.1: type = splice_block %.loc6_21.3 [concrete = constants.%tuple.type.555] { +// CHECK:STDOUT: %v5.var: ref = var v5 +// CHECK:STDOUT: %.loc14_21.1: type = splice_block %.loc14_21.3 [concrete = constants.%tuple.type.555] { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, imports.%Main.Abstract [concrete = constants.%Abstract] -// CHECK:STDOUT: %.loc6_21.2: %tuple.type.85c = tuple_literal (%Abstract.ref) -// CHECK:STDOUT: %.loc6_21.3: type = converted %.loc6_21.2, constants.%tuple.type.555 [concrete = constants.%tuple.type.555] +// CHECK:STDOUT: %.loc14_21.2: %tuple.type.85c = tuple_literal (%Abstract.ref) +// CHECK:STDOUT: %.loc14_21.3: type = converted %.loc14_21.2, constants.%tuple.type.555 [concrete = constants.%tuple.type.555] // CHECK:STDOUT: } -// CHECK:STDOUT: %v5: ref %tuple.type.555 = bind_name v5, %v5.var +// CHECK:STDOUT: %v5: = bind_name v5, // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 3892cac8131b8..cafddded2018a 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -23,12 +23,8 @@ namespace { // // - An `AddNestedIncompleteTypes` step adds a task for all incomplete types // nested within a type to the work list. -// - A `BuildValueRepr` step computes the value representation for a -// type, once all of its nested types are complete, and marks the type as -// complete. -// -// TODO: Extend this to support computing other properties of types, like -// being concrete. +// - A `BuildInfo` step computes the `CompleteTypeInfo` for a type, once all of +// its nested types are complete, and marks the type as complete. class TypeCompleter { public: TypeCompleter(Context& context, SemIRLoc loc, @@ -43,8 +39,8 @@ class TypeCompleter { enum class Phase : int8_t { // The next step is to add nested types to the list of types to complete. AddNestedIncompleteTypes, - // The next step is to build the value representation for the type. - BuildValueRepr, + // The next step is to build the `CompleteTypeInfo` for the type. + BuildInfo, }; struct WorkItem { @@ -82,8 +78,8 @@ class TypeCompleter { // Gets the value representation of a nested type, which should already be // complete. - auto GetNestedValueRepr(SemIR::TypeId nested_type_id) const - -> SemIR::ValueRepr; + auto GetNestedInfo(SemIR::TypeId nested_type_id) const + -> SemIR::CompleteTypeInfo; template requires( @@ -93,34 +89,32 @@ class TypeCompleter { SemIR::IntLiteralType, SemIR::LegacyFloatType, SemIR::NamespaceType, SemIR::PointerType, SemIR::SpecificFunctionType, SemIR::TypeType, SemIR::VtableType, SemIR::WitnessType>()) - auto BuildValueReprForInst(SemIR::TypeId type_id, InstT /*inst*/) const - -> SemIR::ValueRepr { - return MakeCopyValueRepr(type_id); + auto BuildInfoForInst(SemIR::TypeId type_id, InstT /*inst*/) const + -> SemIR::CompleteTypeInfo { + return {.value_repr = MakeCopyValueRepr(type_id)}; } - auto BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::StringType /*inst*/) const - -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId type_id, SemIR::StringType /*inst*/) const + -> SemIR::CompleteTypeInfo; auto BuildStructOrTupleValueRepr(size_t num_elements, SemIR::TypeId elementwise_rep, bool same_as_object_rep) const -> SemIR::ValueRepr; - auto BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::StructType struct_type) const - -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId type_id, + SemIR::StructType struct_type) const + -> SemIR::CompleteTypeInfo; - auto BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::TupleType tuple_type) const - -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId type_id, + SemIR::TupleType tuple_type) const + -> SemIR::CompleteTypeInfo; - auto BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::ArrayType /*inst*/) const - -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId type_id, SemIR::ArrayType /*inst*/) const + -> SemIR::CompleteTypeInfo; - auto BuildValueReprForInst(SemIR::TypeId /*type_id*/, - SemIR::ClassType inst) const -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId /*type_id*/, SemIR::ClassType inst) const + -> SemIR::CompleteTypeInfo; template requires(InstT::Kind.template IsAnyOf< @@ -128,8 +122,8 @@ class TypeCompleter { SemIR::FunctionTypeWithSelfType, SemIR::GenericClassType, SemIR::GenericInterfaceType, SemIR::UnboundElementType, SemIR::WhereExpr>()) - auto BuildValueReprForInst(SemIR::TypeId /*type_id*/, InstT /*inst*/) const - -> SemIR::ValueRepr { + auto BuildInfoForInst(SemIR::TypeId /*type_id*/, InstT /*inst*/) const + -> SemIR::CompleteTypeInfo { // These types have no runtime operations, so we use an empty value // representation. // @@ -137,30 +131,30 @@ class TypeCompleter { // - For an interface, we could use a witness. // - For an associated entity, we could use an index into the witness. // - For an unbound element, we could use an index or offset. - return MakeEmptyValueRepr(); + return {.value_repr = MakeEmptyValueRepr()}; } - auto BuildValueReprForInst(SemIR::TypeId /*type_id*/, - SemIR::ConstType inst) const -> SemIR::ValueRepr; + auto BuildInfoForInst(SemIR::TypeId /*type_id*/, SemIR::ConstType inst) const + -> SemIR::CompleteTypeInfo; template requires(InstT::Kind.constant_kind() == SemIR::InstConstantKind::SymbolicOnly || InstT::Kind.is_type() == SemIR::InstIsType::Never) - auto BuildValueReprForInst(SemIR::TypeId type_id, InstT inst) const - -> SemIR::ValueRepr { + auto BuildInfoForInst(SemIR::TypeId type_id, InstT inst) const + -> SemIR::CompleteTypeInfo { if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Never) { CARBON_FATAL("Type refers to non-type inst {0}", inst); } else { // For symbolic types, we arbitrarily pick a copy representation. - return MakeCopyValueRepr(type_id); + return {.value_repr = MakeCopyValueRepr(type_id)}; } } - // Builds and returns the value representation for the given type. All nested + // Builds and returns the `CompleteTypeInfo` for the given type. All nested // types, as found by AddNestedIncompleteTypes, are known to be complete. - auto BuildValueRepr(SemIR::TypeId type_id, SemIR::Inst inst) const - -> SemIR::ValueRepr; + auto BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const + -> SemIR::CompleteTypeInfo; Context& context_; llvm::SmallVector work_list_; @@ -207,33 +201,33 @@ auto TypeCompleter::ProcessStep() -> bool { } CARBON_CHECK(work_list_.size() >= old_work_list_size, "AddNestedIncompleteTypes should not remove work items"); - work_list_[old_work_list_size - 1].phase = Phase::BuildValueRepr; + work_list_[old_work_list_size - 1].phase = Phase::BuildInfo; break; - case Phase::BuildValueRepr: { - auto value_rep = BuildValueRepr(type_id, inst); - context_.types().SetValueRepr(type_id, value_rep); + case Phase::BuildInfo: { + auto info = BuildInfo(type_id, inst); + context_.types().SetComplete(type_id, info); CARBON_CHECK(old_work_list_size == work_list_.size(), - "BuildValueRepr should not change work items"); + "BuildInfo should not change work items"); work_list_.pop_back(); // Also complete the value representation type, if necessary. This // should never fail: the value representation shouldn't require any // additional nested types to be complete. - if (!context_.types().IsComplete(value_rep.type_id)) { + if (!context_.types().IsComplete(info.value_repr.type_id)) { work_list_.push_back( - {.type_id = value_rep.type_id, .phase = Phase::BuildValueRepr}); + {.type_id = info.value_repr.type_id, .phase = Phase::BuildInfo}); } // For a pointer representation, the pointee also needs to be complete. - if (value_rep.kind == SemIR::ValueRepr::Pointer) { - if (value_rep.type_id == SemIR::ErrorInst::SingletonTypeId) { + if (info.value_repr.kind == SemIR::ValueRepr::Pointer) { + if (info.value_repr.type_id == SemIR::ErrorInst::SingletonTypeId) { break; } auto pointee_type_id = - context_.sem_ir().GetPointeeType(value_rep.type_id); + context_.sem_ir().GetPointeeType(info.value_repr.type_id); if (!context_.types().IsComplete(pointee_type_id)) { work_list_.push_back( - {.type_id = pointee_type_id, .phase = Phase::BuildValueRepr}); + {.type_id = pointee_type_id, .phase = Phase::BuildInfo}); } } break; @@ -317,23 +311,23 @@ auto TypeCompleter::MakePointerValueRepr( .type_id = GetPointerType(context_, pointee_id)}; } -auto TypeCompleter::GetNestedValueRepr(SemIR::TypeId nested_type_id) const - -> SemIR::ValueRepr { +auto TypeCompleter::GetNestedInfo(SemIR::TypeId nested_type_id) const + -> SemIR::CompleteTypeInfo { CARBON_CHECK(context_.types().IsComplete(nested_type_id), "Nested type should already be complete"); - auto value_rep = context_.types().GetValueRepr(nested_type_id); - CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown, + auto info = context_.types().GetCompleteTypeInfo(nested_type_id); + CARBON_CHECK(info.value_repr.kind != SemIR::ValueRepr::Unknown, "Complete type should have a value representation"); - return value_rep; + return info; } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::StringType /*inst*/) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id, + SemIR::StringType /*inst*/) const + -> SemIR::CompleteTypeInfo { // TODO: Decide on string value semantics. This should probably be a // custom value representation carrying a pointer and size or // similar. - return MakePointerValueRepr(type_id); + return {.value_repr = MakePointerValueRepr(type_id)}; } auto TypeCompleter::BuildStructOrTupleValueRepr(size_t num_elements, @@ -357,12 +351,12 @@ auto TypeCompleter::BuildStructOrTupleValueRepr(size_t num_elements, return MakePointerValueRepr(elementwise_rep, aggregate_kind); } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::StructType struct_type) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id, + SemIR::StructType struct_type) const + -> SemIR::CompleteTypeInfo { auto fields = context_.struct_type_fields().Get(struct_type.fields_id); if (fields.empty()) { - return MakeEmptyValueRepr(); + return {.value_repr = MakeEmptyValueRepr()}; } // Find the value representation for each field, and construct a struct @@ -370,13 +364,20 @@ auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, llvm::SmallVector value_rep_fields; value_rep_fields.reserve(fields.size()); bool same_as_object_rep = true; + SemIR::ClassId abstract_class_id = SemIR::ClassId::None; for (auto field : fields) { - auto field_value_rep = GetNestedValueRepr(field.type_id); - if (!field_value_rep.IsCopyOfObjectRepr(context_.sem_ir(), field.type_id)) { + auto field_info = GetNestedInfo(field.type_id); + if (!field_info.value_repr.IsCopyOfObjectRepr(context_.sem_ir(), + field.type_id)) { same_as_object_rep = false; - field.type_id = field_value_rep.type_id; + field.type_id = field_info.value_repr.type_id; } value_rep_fields.push_back(field); + // Take the first non-None abstract_class_id, if any. + if (field_info.abstract_class_id.has_value() && + !abstract_class_id.has_value()) { + abstract_class_id = field_info.abstract_class_id; + } } auto value_rep = @@ -384,17 +385,18 @@ auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, ? type_id : GetStructType(context_, context_.struct_type_fields().AddCanonical( value_rep_fields)); - return BuildStructOrTupleValueRepr(fields.size(), value_rep, - same_as_object_rep); + return {.value_repr = BuildStructOrTupleValueRepr(fields.size(), value_rep, + same_as_object_rep), + .abstract_class_id = abstract_class_id}; } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::TupleType tuple_type) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id, + SemIR::TupleType tuple_type) const + -> SemIR::CompleteTypeInfo { // TODO: Share more code with structs. auto elements = context_.type_blocks().Get(tuple_type.elements_id); if (elements.empty()) { - return MakeEmptyValueRepr(); + return {.value_repr = MakeEmptyValueRepr()}; } // Find the value representation for each element, and construct a tuple @@ -402,68 +404,84 @@ auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, llvm::SmallVector value_rep_elements; value_rep_elements.reserve(elements.size()); bool same_as_object_rep = true; + SemIR::ClassId abstract_class_id = SemIR::ClassId::None; for (auto element_type_id : elements) { - auto element_value_rep = GetNestedValueRepr(element_type_id); - if (!element_value_rep.IsCopyOfObjectRepr(context_.sem_ir(), - element_type_id)) { + auto element_info = GetNestedInfo(element_type_id); + if (!element_info.value_repr.IsCopyOfObjectRepr(context_.sem_ir(), + element_type_id)) { same_as_object_rep = false; } - value_rep_elements.push_back(element_value_rep.type_id); + value_rep_elements.push_back(element_info.value_repr.type_id); + // Take the first non-None abstract_class_id, if any. + if (element_info.abstract_class_id.has_value() && + !abstract_class_id.has_value()) { + abstract_class_id = element_info.abstract_class_id; + } } auto value_rep = same_as_object_rep ? type_id : GetTupleType(context_, value_rep_elements); - return BuildStructOrTupleValueRepr(elements.size(), value_rep, - same_as_object_rep); + return {.value_repr = BuildStructOrTupleValueRepr(elements.size(), value_rep, + same_as_object_rep), + .abstract_class_id = abstract_class_id}; } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId type_id, - SemIR::ArrayType /*inst*/) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id, + SemIR::ArrayType /*inst*/) const + -> SemIR::CompleteTypeInfo { // For arrays, it's convenient to always use a pointer representation, // even when the array has zero or one element, in order to support // indexing. - return MakePointerValueRepr(type_id, SemIR::ValueRepr::ObjectAggregate); + return {.value_repr = + MakePointerValueRepr(type_id, SemIR::ValueRepr::ObjectAggregate)}; } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId /*type_id*/, - SemIR::ClassType inst) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/, + SemIR::ClassType inst) const + -> SemIR::CompleteTypeInfo { auto& class_info = context_.classes().Get(inst.class_id); + auto abstract_class_id = + class_info.inheritance_kind == SemIR::Class::InheritanceKind::Abstract + ? inst.class_id + : SemIR::ClassId::None; + // The value representation of an adapter is the value representation of // its adapted type. if (auto adapted_type_id = class_info.GetAdaptedType(context_.sem_ir(), inst.specific_id); adapted_type_id.has_value()) { - return GetNestedValueRepr(adapted_type_id); + auto info = GetNestedInfo(adapted_type_id); + info.abstract_class_id = abstract_class_id; + return info; } // Otherwise, the value representation for a class is a pointer to the // object representation. // TODO: Support customized value representations for classes. // TODO: Pick a better value representation when possible. - return MakePointerValueRepr( - class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id), - SemIR::ValueRepr::ObjectAggregate); + return {.value_repr = MakePointerValueRepr( + class_info.GetObjectRepr(context_.sem_ir(), inst.specific_id), + SemIR::ValueRepr::ObjectAggregate), + .abstract_class_id = abstract_class_id}; } -auto TypeCompleter::BuildValueReprForInst(SemIR::TypeId /*type_id*/, - SemIR::ConstType inst) const - -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/, + SemIR::ConstType inst) const + -> SemIR::CompleteTypeInfo { // The value representation of `const T` is the same as that of `T`. // Objects are not modifiable through their value representations. - return GetNestedValueRepr(inst.inner_id); + return GetNestedInfo(inst.inner_id); } // Builds and returns the value representation for the given type. All nested // types, as found by AddNestedIncompleteTypes, are known to be complete. -auto TypeCompleter::BuildValueRepr(SemIR::TypeId type_id, - SemIR::Inst inst) const -> SemIR::ValueRepr { +auto TypeCompleter::BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const + -> SemIR::CompleteTypeInfo { // Use overload resolution to select the implementation, producing compile - // errors when BuildValueReprForInst isn't defined for a given instruction. + // errors when BuildInfoForInst isn't defined for a given instruction. CARBON_KIND_SWITCH(inst) { -#define CARBON_SEM_IR_INST_KIND(Name) \ - case CARBON_KIND(SemIR::Name typed_inst): { \ - return BuildValueReprForInst(type_id, typed_inst); \ +#define CARBON_SEM_IR_INST_KIND(Name) \ + case CARBON_KIND(SemIR::Name typed_inst): { \ + return BuildInfoForInst(type_id, typed_inst); \ } #include "toolchain/sem_ir/inst_kind.def" } @@ -508,14 +526,18 @@ auto RequireCompleteType(Context& context, SemIR::TypeId type_id, // Adds a note to a diagnostic explaining that a class is abstract. static auto NoteAbstractClass(Context& context, SemIR::ClassId class_id, + bool direct_use, Context::DiagnosticBuilder& builder) -> void { const auto& class_info = context.classes().Get(class_id); CARBON_CHECK( class_info.inheritance_kind == SemIR::Class::InheritanceKind::Abstract, "Class is not abstract"); - CARBON_DIAGNOSTIC(ClassAbstractHere, Note, - "class was declared abstract here"); - builder.Note(class_info.definition_id, ClassAbstractHere); + CARBON_DIAGNOSTIC( + ClassAbstractHere, Note, + "{0:=0:uses class that|=1:class} was declared abstract here", + IntAsSelect); + builder.Note(class_info.definition_id, ClassAbstractHere, + static_cast(direct_use)); } auto RequireConcreteType(Context& context, SemIR::TypeId type_id, @@ -531,20 +553,20 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, return false; } - // TODO: This doesn't properly handle tuples and structs. - if (auto class_type = context.types().TryGetAs(type_id)) { - auto& class_info = context.classes().Get(class_type->class_id); - if (class_info.inheritance_kind != - SemIR::Class::InheritanceKind::Abstract) { - return true; - } - + auto complete_info = context.types().GetCompleteTypeInfo(type_id); + if (complete_info.abstract_class_id.has_value()) { auto builder = abstract_diagnoser(); - if (!builder) { - return false; + if (builder) { + bool direct_use = false; + if (auto inst = context.types().TryGetAs(type_id)) { + if (inst->class_id == complete_info.abstract_class_id) { + direct_use = true; + } + } + NoteAbstractClass(context, complete_info.abstract_class_id, direct_use, + builder); + builder.Emit(); } - NoteAbstractClass(context, class_type->class_id, builder); - builder.Emit(); return false; } diff --git a/toolchain/driver/testdata/compile/multifile_raw_and_textual_ir.carbon b/toolchain/driver/testdata/compile/multifile_raw_and_textual_ir.carbon index 06a1e5aa57184..e390d3df58b67 100644 --- a/toolchain/driver/testdata/compile/multifile_raw_and_textual_ir.carbon +++ b/toolchain/driver/testdata/compile/multifile_raw_and_textual_ir.carbon @@ -43,11 +43,16 @@ fn B() { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst14)': {kind: none, type: type(inst15)} -// CHECK:STDOUT: 'type(inst15)': {kind: none, type: type(inst15)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst14)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst15)} +// CHECK:STDOUT: 'type(inst15)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst15)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: insts: @@ -120,12 +125,18 @@ fn B() { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst16)': {kind: none, type: type(inst17)} -// CHECK:STDOUT: 'type(inst17)': {kind: none, type: type(inst17)} -// CHECK:STDOUT: 'type(inst22)': {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst16)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(inst17)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(inst22)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: insts: diff --git a/toolchain/driver/testdata/compile/multifile_raw_ir.carbon b/toolchain/driver/testdata/compile/multifile_raw_ir.carbon index 97a9ade3cdcd0..8b74020f139af 100644 --- a/toolchain/driver/testdata/compile/multifile_raw_ir.carbon +++ b/toolchain/driver/testdata/compile/multifile_raw_ir.carbon @@ -43,11 +43,16 @@ fn B() { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst14)': {kind: none, type: type(inst15)} -// CHECK:STDOUT: 'type(inst15)': {kind: none, type: type(inst15)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst14)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst15)} +// CHECK:STDOUT: 'type(inst15)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst15)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: insts: @@ -100,12 +105,18 @@ fn B() { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst16)': {kind: none, type: type(inst17)} -// CHECK:STDOUT: 'type(inst17)': {kind: none, type: type(inst17)} -// CHECK:STDOUT: 'type(inst22)': {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst16)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(inst17)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} +// CHECK:STDOUT: 'type(inst22)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst17)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: insts: diff --git a/toolchain/driver/testdata/compile/raw_and_textual_ir.carbon b/toolchain/driver/testdata/compile/raw_and_textual_ir.carbon index 03174560eecf2..a3e234b0223cb 100644 --- a/toolchain/driver/testdata/compile/raw_and_textual_ir.carbon +++ b/toolchain/driver/testdata/compile/raw_and_textual_ir.carbon @@ -34,13 +34,20 @@ fn Foo(n: ()) -> ((), ()) { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst33)': {kind: none, type: type(inst13)} -// CHECK:STDOUT: 'type(inst13)': {kind: none, type: type(inst13)} -// CHECK:STDOUT: 'type(inst21)': {kind: pointer, type: type(inst35)} -// CHECK:STDOUT: 'type(inst35)': {kind: copy, type: type(inst35)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst33)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst13)} +// CHECK:STDOUT: 'type(inst13)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst13)} +// CHECK:STDOUT: 'type(inst21)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst35)} +// CHECK:STDOUT: 'type(inst35)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst35)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: type_block1: diff --git a/toolchain/driver/testdata/compile/raw_ir.carbon b/toolchain/driver/testdata/compile/raw_ir.carbon index 37969bf20e66d..58b9f33113ddc 100644 --- a/toolchain/driver/testdata/compile/raw_ir.carbon +++ b/toolchain/driver/testdata/compile/raw_ir.carbon @@ -37,17 +37,28 @@ fn Foo[T:! type](n: T) -> (T, ()) { // CHECK:STDOUT: struct_type_fields: // CHECK:STDOUT: struct_type_fields0: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: 'type(TypeType)': {kind: copy, type: type(TypeType)} -// CHECK:STDOUT: 'type(Error)': {kind: copy, type: type(Error)} -// CHECK:STDOUT: 'type(inst(NamespaceType))': {kind: copy, type: type(inst(NamespaceType))} -// CHECK:STDOUT: 'type(inst40)': {kind: none, type: type(inst23)} -// CHECK:STDOUT: 'type(inst23)': {kind: none, type: type(inst23)} -// CHECK:STDOUT: 'type(symbolic_constant0)': {kind: copy, type: type(symbolic_constant0)} -// CHECK:STDOUT: 'type(symbolic_constant2)': {kind: pointer, type: type(symbolic_constant6)} -// CHECK:STDOUT: 'type(symbolic_constant6)': {kind: copy, type: type(symbolic_constant6)} -// CHECK:STDOUT: 'type(inst(WitnessType))': {kind: copy, type: type(inst(WitnessType))} -// CHECK:STDOUT: 'type(symbolic_constant3)': {kind: copy, type: type(symbolic_constant3)} -// CHECK:STDOUT: 'type(symbolic_constant5)': {kind: pointer, type: type(symbolic_constant6)} +// CHECK:STDOUT: 'type(TypeType)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(TypeType)} +// CHECK:STDOUT: 'type(Error)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(Error)} +// CHECK:STDOUT: 'type(inst(NamespaceType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(NamespaceType))} +// CHECK:STDOUT: 'type(inst40)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst23)} +// CHECK:STDOUT: 'type(inst23)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst23)} +// CHECK:STDOUT: 'type(symbolic_constant0)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant0)} +// CHECK:STDOUT: 'type(symbolic_constant2)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constant6)} +// CHECK:STDOUT: 'type(symbolic_constant6)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant6)} +// CHECK:STDOUT: 'type(inst(WitnessType))': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(WitnessType))} +// CHECK:STDOUT: 'type(symbolic_constant3)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant3)} +// CHECK:STDOUT: 'type(symbolic_constant5)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constant6)} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: type_block0: {} // CHECK:STDOUT: type_block1: diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 7328f57d900f3..9299b22d400a7 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -35,13 +35,13 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, constant_values_(ConstantId::NotConstant), inst_blocks_(allocator_), constants_(this) { - // `type` and the error type are both complete types. - types_.SetValueRepr( - TypeType::SingletonTypeId, - {.kind = ValueRepr::Copy, .type_id = TypeType::SingletonTypeId}); - types_.SetValueRepr( - ErrorInst::SingletonTypeId, - {.kind = ValueRepr::Copy, .type_id = ErrorInst::SingletonTypeId}); + // `type` and the error type are both complete & concrete types. + types_.SetComplete(TypeType::SingletonTypeId, + {.value_repr = {.kind = ValueRepr::Copy, + .type_id = TypeType::SingletonTypeId}}); + types_.SetComplete(ErrorInst::SingletonTypeId, + {.value_repr = {.kind = ValueRepr::Copy, + .type_id = ErrorInst::SingletonTypeId}}); insts_.Reserve(SingletonInstKinds.size()); for (auto kind : SingletonInstKinds) { diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index dc2669ae73a95..a2cf2d5e63043 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -87,7 +87,7 @@ class TypeStore : public Yaml::Printable { } // Gets the value representation to use for a type. This returns an - // invalid type if the given type is not complete. + // `None` type if the given type is not complete. auto GetValueRepr(TypeId type_id) const -> ValueRepr { if (auto type_info = complete_type_info_.Lookup(type_id)) { return type_info.value().value_repr; @@ -95,11 +95,20 @@ class TypeStore : public Yaml::Printable { return {.kind = ValueRepr::Unknown}; } - // Sets the value representation associated with a type. - auto SetValueRepr(TypeId type_id, ValueRepr value_repr) -> void { - CARBON_CHECK(value_repr.kind != ValueRepr::Unknown); - auto insert_info = - complete_type_info_.Insert(type_id, {.value_repr = value_repr}); + // Gets the `CompleteTypeInfo` for a type, with an empty value if the type is + // not complete. + auto GetCompleteTypeInfo(TypeId type_id) const -> CompleteTypeInfo { + if (auto type_info = complete_type_info_.Lookup(type_id)) { + return type_info.value(); + } + return {.value_repr = {.kind = ValueRepr::Unknown}}; + } + + // Sets the `CompleteTypeInfo` associated with a type, marking it as complete. + // This can be used with abstract types. + auto SetComplete(TypeId type_id, const CompleteTypeInfo& info) -> void { + CARBON_CHECK(info.value_repr.kind != ValueRepr::Unknown); + auto insert_info = complete_type_info_.Insert(type_id, info); CARBON_CHECK(insert_info.is_inserted(), "Type {0} completed more than once", type_id); complete_types_.push_back(type_id); @@ -148,8 +157,15 @@ class TypeStore : public Yaml::Printable { auto OutputYaml() const -> Yaml::OutputMapping { return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { for (auto type_id : complete_types_) { + auto info = GetCompleteTypeInfo(type_id); map.Add(PrintToString(type_id), - Yaml::OutputScalar(GetValueRepr(type_id))); + Yaml::OutputMapping([&](Yaml::OutputMapping::Map map2) { + map2.Add("value_repr", Yaml::OutputScalar(info.value_repr)); + if (info.abstract_class_id.has_value()) { + map2.Add("abstract_class_id", + Yaml::OutputScalar(info.abstract_class_id)); + } + })); } }); } diff --git a/toolchain/sem_ir/type_info.h b/toolchain/sem_ir/type_info.h index 460a4707754d8..60a9dd5a0d240 100644 --- a/toolchain/sem_ir/type_info.h +++ b/toolchain/sem_ir/type_info.h @@ -78,6 +78,9 @@ struct CompleteTypeInfo : public Printable { // The value representation for this type. Will be `Unknown` if the type is // not complete. ValueRepr value_repr = ValueRepr(); + + // If this type is abstract, this is id of an abstract class it uses. + SemIR::ClassId abstract_class_id = SemIR::ClassId::None; }; // The initializing representation to use when returning by value. From 24bde46181985f55a1fd64459070c4d564798eed Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 20 Feb 2025 17:42:47 -0500 Subject: [PATCH 04/56] Change array syntax from [T; N] to array(T, N) (#4981) In line with the proposal in #4682, this changes the array syntax to be array(T, N). `array` is a builtin keyword which must be followed by parens containing two expressions and a separating comma. The array type expression is still fully builtin, it does not forward to a Core.Array library type yet. It merely adds the `ArrayType` instruction, as was done with the previous syntax. Followup work will change the instruction to reference to Core.Array, once the library type exists and can be used directly. --------- Co-authored-by: zygoloid --- examples/advent2024/day10_common.carbon | 2 +- examples/advent2024/day10_part1.carbon | 4 +- examples/advent2024/day10_part2.carbon | 4 +- examples/advent2024/day11_part2.carbon | 2 +- examples/advent2024/day12_common.carbon | 4 +- examples/advent2024/day12_part2.carbon | 8 +- examples/advent2024/day1_common.carbon | 2 +- examples/advent2024/day1_part1.carbon | 4 +- examples/advent2024/day1_part2.carbon | 4 +- examples/advent2024/day2_part2.carbon | 2 +- examples/advent2024/day4_common.carbon | 6 +- examples/advent2024/day4_part1.carbon | 2 +- examples/advent2024/day4_part2.carbon | 2 +- examples/advent2024/day5_common.carbon | 4 +- examples/advent2024/day6_common.carbon | 2 +- examples/advent2024/day7_common.carbon | 2 +- examples/advent2024/day8_common.carbon | 2 +- examples/advent2024/day8_part2.carbon | 8 +- examples/advent2024/day9_common.carbon | 2 +- examples/advent2024/sort.carbon | 6 +- examples/sieve.carbon | 2 +- toolchain/check/convert.cpp | 2 +- ... 0444b366b646a800d860d362876dec36afb41e42} | 2 +- ... 17dc6eb1bbb8fd9671f46aa63924cf1a76837a2c} | 4 +- ... 1c56a65ba702fd27f5a72caf9c5e9170312db350} | 4 +- ... 306f80d197d3d627368e752f1ad6aa42d2e89aa6} | 2 +- ... 310b6d61f64901b21169432ef6bbc13a2b602376} | 2 +- ... 48f161ebf1c515fbc92fc959814c40d6394b5360} | 2 +- ... 54dab9151ed3293f3aec67e58aa20e26aa632a98} | 2 +- ... b08132223d41827e2b8cd8f849ffb7ac4af4e993} | 2 +- ... b0e276497e7036c6b3c90deeff71a055256ed5e3} | 2 +- ... bb0ee9a7c7f604c41cfef744a974c6603df4b0db} | 2 +- ... dbd0b78b1bfd4878676ac3d882aee2b797d7af15} | 4 +- ... f2b43d44db5dec0cca4bc6fc63f487fabae1b941} | 2 +- ... f71cbd0475ddb41b78a0d439aa78ae1e2eec0df5} | 2 +- toolchain/check/handle_array.cpp | 24 +- toolchain/check/node_stack.h | 5 +- .../testdata/array/array_in_place.carbon | 34 +- .../testdata/array/array_vs_tuple.carbon | 66 +-- .../testdata/array/assign_return_value.carbon | 20 +- .../check/testdata/array/assign_var.carbon | 26 +- toolchain/check/testdata/array/base.carbon | 96 ++-- .../testdata/array/canonicalize_index.carbon | 142 +++--- .../testdata/array/fail_bound_negative.carbon | 42 +- .../testdata/array/fail_bound_overflow.carbon | 28 +- .../array/fail_incomplete_element.carbon | 8 +- .../testdata/array/fail_invalid_type.carbon | 24 +- .../testdata/array/fail_out_of_bound.carbon | 10 +- .../fail_out_of_bound_non_literal.carbon | 60 +-- .../testdata/array/fail_type_mismatch.carbon | 74 +-- .../array/fail_undefined_bound.carbon | 23 - .../testdata/array/function_param.carbon | 18 +- .../check/testdata/array/generic_empty.carbon | 26 +- toolchain/check/testdata/array/import.carbon | 2 +- .../testdata/array/index_not_literal.carbon | 60 +-- .../array/init_dependent_bound.carbon | 72 +-- .../check/testdata/array/nine_elements.carbon | 168 +++---- .../testdata/basics/numeric_literals.carbon | 12 +- .../value_with_type_through_access.carbon | 56 +-- .../check/testdata/builtins/int/and.carbon | 4 +- .../testdata/builtins/int/complement.carbon | 4 +- .../check/testdata/builtins/int/or.carbon | 4 +- .../check/testdata/builtins/int/sadd.carbon | 32 +- .../check/testdata/builtins/int/sdiv.carbon | 4 +- .../check/testdata/builtins/int/smod.carbon | 4 +- .../testdata/builtins/int/snegate.carbon | 36 +- .../check/testdata/builtins/int/ssub.carbon | 4 +- .../check/testdata/builtins/int/uadd.carbon | 36 +- .../check/testdata/builtins/int/udiv.carbon | 4 +- .../check/testdata/builtins/int/umod.carbon | 4 +- .../check/testdata/builtins/int/umul.carbon | 4 +- .../testdata/builtins/int/unegate.carbon | 36 +- .../check/testdata/builtins/int/usub.carbon | 4 +- .../check/testdata/builtins/int/xor.carbon | 4 +- toolchain/check/testdata/deduce/array.carbon | 460 +++++++++--------- .../check/testdata/eval/aggregate.carbon | 66 +-- .../check/testdata/eval/fail_aggregate.carbon | 118 ++--- toolchain/check/testdata/eval/symbolic.carbon | 44 +- .../testdata/function/builtin/call.carbon | 48 +- .../testdata/function/builtin/method.carbon | 60 +-- .../no_prelude/call_from_operator.carbon | 154 +++--- .../function/builtin/no_prelude/import.carbon | 90 ++-- .../declaration/fail_param_in_type.carbon | 14 +- .../function/generic/param_in_type.carbon | 40 +- .../function/generic/return_slot.carbon | 2 +- toolchain/check/testdata/if_expr/basic.carbon | 24 +- .../testdata/impl/assoc_const_self.carbon | 8 +- .../impl/fail_impl_bad_assoc_fn.carbon | 46 +- .../impl/fail_todo_use_assoc_const.carbon | 42 +- .../index/array_element_access.carbon | 38 +- .../check/testdata/index/expr_category.carbon | 138 +++--- .../index/fail_array_large_index.carbon | 16 +- .../index/fail_array_non_int_indexing.carbon | 16 +- .../fail_array_out_of_bound_access.carbon | 16 +- .../testdata/index/fail_expr_category.carbon | 4 +- .../index/fail_negative_indexing.carbon | 42 +- .../tuple/access/fail_non_tuple_access.carbon | 42 +- toolchain/diagnostics/diagnostic_kind.def | 2 +- toolchain/lex/lex.cpp | 2 +- toolchain/lex/lex.h | 3 +- .../lex/testdata/numeric_literals.carbon | 114 ++--- toolchain/lex/token_kind.def | 1 + toolchain/lex/tokenized_buffer.h | 5 +- .../testdata/array/array_in_place.carbon | 16 +- .../testdata/array/assign_return_value.carbon | 24 +- toolchain/lower/testdata/array/base.carbon | 50 +- toolchain/lower/testdata/array/field.carbon | 2 +- .../testdata/array/function_param.carbon | 2 +- .../testdata/basics/numeric_literals.carbon | 8 +- .../index/array_element_access.carbon | 38 +- toolchain/parse/handle_array_expr.cpp | 32 +- toolchain/parse/handle_expr.cpp | 2 +- toolchain/parse/node_kind.def | 5 +- toolchain/parse/state.def | 26 +- .../{with_length.carbon => basic.carbon} | 23 +- .../array/fail_require_close_bracket.carbon | 29 -- .../testdata/array/fail_require_semi.carbon | 30 -- .../parse/testdata/array/fail_syntax.carbon | 264 +++++++--- .../testdata/array/without_length.carbon | 26 - .../basics/fail_bracket_recovery.carbon | 41 +- .../testdata/basics/numeric_literals.carbon | 36 +- .../testdata/for/fail_square_brackets.carbon | 33 +- .../testdata/if/fail_square_brackets.carbon | 31 +- toolchain/parse/typed_nodes.h | 30 +- toolchain/parse/typed_nodes_test.cpp | 2 +- 125 files changed, 1908 insertions(+), 1885 deletions(-) rename toolchain/check/fuzzer_corpus/{dd0aadb8d4ae92d3f07fd7f03c9bfcdc88b1f6bc => 0444b366b646a800d860d362876dec36afb41e42} (92%) rename toolchain/check/fuzzer_corpus/{0e272375f1c866bb051eab5262ad87da60f5ce8c => 17dc6eb1bbb8fd9671f46aa63924cf1a76837a2c} (89%) rename toolchain/check/fuzzer_corpus/{9e2fa6d7320a5b7aa4a136fbc5b9fb9ba6c8d26a => 1c56a65ba702fd27f5a72caf9c5e9170312db350} (81%) rename toolchain/check/fuzzer_corpus/{958211e37b230431232fd97eedce8db62b6c711e => 306f80d197d3d627368e752f1ad6aa42d2e89aa6} (83%) rename toolchain/check/fuzzer_corpus/{5ae87d7a9d55141806809261a2ea9fb567e70aae => 310b6d61f64901b21169432ef6bbc13a2b602376} (92%) rename toolchain/check/fuzzer_corpus/{9369cbcfcb8792587b18645cb5914fa5edeed78d => 48f161ebf1c515fbc92fc959814c40d6394b5360} (91%) rename toolchain/check/fuzzer_corpus/{8670e2da7432feef1ab66b434f95a97fc209b2b0 => 54dab9151ed3293f3aec67e58aa20e26aa632a98} (93%) rename toolchain/check/fuzzer_corpus/{ae7557cf66185fad53df0aa262e52a4dbd8ff8da => b08132223d41827e2b8cd8f849ffb7ac4af4e993} (92%) rename toolchain/check/fuzzer_corpus/{0ca753d0d0e5afc30bc37f855501c9db4776cb5c => b0e276497e7036c6b3c90deeff71a055256ed5e3} (92%) rename toolchain/check/fuzzer_corpus/{530ca26b3435b4490f3e882c3837aef588592497 => bb0ee9a7c7f604c41cfef744a974c6603df4b0db} (91%) rename toolchain/check/fuzzer_corpus/{431077e0b0c67e3442d71fc8dd7b1664c3287b3a => dbd0b78b1bfd4878676ac3d882aee2b797d7af15} (82%) rename toolchain/check/fuzzer_corpus/{9a9abdfff166a4ff4ee660bcce9ec0ba6844d028 => f2b43d44db5dec0cca4bc6fc63f487fabae1b941} (92%) rename toolchain/check/fuzzer_corpus/{45051e270ef1a1b856e7e0a9ad17925204e7efee => f71cbd0475ddb41b78a0d439aa78ae1e2eec0df5} (91%) delete mode 100644 toolchain/check/testdata/array/fail_undefined_bound.carbon rename toolchain/parse/testdata/array/{with_length.carbon => basic.carbon} (62%) delete mode 100644 toolchain/parse/testdata/array/fail_require_close_bracket.carbon delete mode 100644 toolchain/parse/testdata/array/fail_require_semi.carbon delete mode 100644 toolchain/parse/testdata/array/without_length.carbon diff --git a/examples/advent2024/day10_common.carbon b/examples/advent2024/day10_common.carbon index d2c40d9af10ce..839965030215a 100644 --- a/examples/advent2024/day10_common.carbon +++ b/examples/advent2024/day10_common.carbon @@ -25,5 +25,5 @@ class Terrain { return var; } - var height: [[i32; 43]; 43]; + var height: array(array(i32, 43), 43); } diff --git a/examples/advent2024/day10_part1.carbon b/examples/advent2024/day10_part1.carbon index 33877ade6b6ed..a5cf816100de7 100644 --- a/examples/advent2024/day10_part1.carbon +++ b/examples/advent2024/day10_part1.carbon @@ -42,7 +42,7 @@ class Reachable { } fn AddLevel[addr self: Self*](terrain: Terrain, level: i32) { - let adj: [(i32, i32); 4] = ((-1, 0), (0, -1), (1, 0), (0, 1)); + let adj: array((i32, i32), 4) = ((-1, 0), (0, -1), (1, 0), (0, 1)); var y: i32 = 0; while (y < 43) { var x: i32 = 0; @@ -84,7 +84,7 @@ class Reachable { return total; } - var trailheads: [[u256; 43]; 43]; + var trailheads: array(array(u256, 43), 43); } fn Run() { diff --git a/examples/advent2024/day10_part2.carbon b/examples/advent2024/day10_part2.carbon index 0ac9731b524d6..d4ec248f471da 100644 --- a/examples/advent2024/day10_part2.carbon +++ b/examples/advent2024/day10_part2.carbon @@ -28,7 +28,7 @@ class PathsToTop { fn AddLevel[addr self: Self*](terrain: Terrain, level: i32) -> i64 { var total: i64 = 0; - let adj: [(i32, i32); 4] = ((-1, 0), (0, -1), (1, 0), (0, 1)); + let adj: array((i32, i32), 4) = ((-1, 0), (0, -1), (1, 0), (0, 1)); var y: i32 = 0; while (y < 43) { var x: i32 = 0; @@ -56,7 +56,7 @@ class PathsToTop { return total; } - var paths: [[i64; 43]; 43]; + var paths: array(array(i64, 43), 43); } fn Run() { diff --git a/examples/advent2024/day11_part2.carbon b/examples/advent2024/day11_part2.carbon index ea359d7ecdd02..958eee5840c50 100644 --- a/examples/advent2024/day11_part2.carbon +++ b/examples/advent2024/day11_part2.carbon @@ -41,7 +41,7 @@ class Digits { Core.PrintChar(0x0A); } - var count: [[i64; 75]; 10]; + var count: array(array(i64, 75), 10); } // TODO: Add a builtin to perform integer conversion / truncation. diff --git a/examples/advent2024/day12_common.carbon b/examples/advent2024/day12_common.carbon index e1de4a983664d..464d9981886d5 100644 --- a/examples/advent2024/day12_common.carbon +++ b/examples/advent2024/day12_common.carbon @@ -31,7 +31,7 @@ class Map { else self.kind[x][y]; } - var kind: [[i32; 140]; 140]; + var kind: array(array(i32, 140), 140); } class DisjointSetForest { @@ -86,7 +86,7 @@ class DisjointSetForest { // TODO: Consider adding ranked choice. // TODO: Make this generic in the payload data. - var nodes: [{.next: i32, .weight: i32, .unions: i32}; 140 * 140]; + var nodes: array({.next: i32, .weight: i32, .unions: i32}, 140 * 140); } fn MakeRegions(map: Map) -> DisjointSetForest { diff --git a/examples/advent2024/day12_part2.carbon b/examples/advent2024/day12_part2.carbon index 0adb06ce8ed93..ddcebcb94d088 100644 --- a/examples/advent2024/day12_part2.carbon +++ b/examples/advent2024/day12_part2.carbon @@ -9,15 +9,15 @@ import Core library "io"; import library "day12_common"; import library "io_utils"; -fn CountExtensions(map: Map, regions: DisjointSetForest*) -> [i32; 140 * 140] { - returned var extensions: [i32; 140 * 140]; +fn CountExtensions(map: Map, regions: DisjointSetForest*) -> array(i32, 140 * 140) { + returned var extensions: array(i32, 140 * 140); var i: i32 = 0; while (i < 140 * 140) { extensions[i] = 0; ++i; } - var ext: [{.same: (i32, i32), .adj: (i32, i32)}; 4] = ( + var ext: array({.same: (i32, i32), .adj: (i32, i32)}, 4) = ( {.same = (-1, 0), .adj = (0, -1)}, {.same = (-1, 0), .adj = (0, 1)}, {.same = (0, -1), .adj = (-1, 0)}, @@ -49,7 +49,7 @@ fn CountExtensions(map: Map, regions: DisjointSetForest*) -> [i32; 140 * 140] { fn Run() { var map: Map = Map.Read(); var regions: DisjointSetForest = MakeRegions(map); - var ext: [i32; 140 * 140] = CountExtensions(map, ®ions); + var ext: array(i32, 140 * 140) = CountExtensions(map, ®ions); var total: i32 = 0; diff --git a/examples/advent2024/day1_common.carbon b/examples/advent2024/day1_common.carbon index 5913081e0c419..db602fe58a0a1 100644 --- a/examples/advent2024/day1_common.carbon +++ b/examples/advent2024/day1_common.carbon @@ -10,7 +10,7 @@ import library "io_utils"; // Read a sequence of lines each containing a pair of numbers into two arrays. // Returns the number of lines read. -fn ReadInputs(ap: [i32; 1000]*, bp: [i32; 1000]*) -> i32 { +fn ReadInputs(ap: array(i32, 1000)*, bp: array(i32, 1000)*) -> i32 { var n: i32 = 0; var a: i32; var b: i32; diff --git a/examples/advent2024/day1_part1.carbon b/examples/advent2024/day1_part1.carbon index eb1a6ed739ab9..9a422a651b6ac 100644 --- a/examples/advent2024/day1_part1.carbon +++ b/examples/advent2024/day1_part1.carbon @@ -12,8 +12,8 @@ import library "sort"; fn Abs(n: i32) -> i32 { return if n < 0 then -n else n; } fn Run() { - var a: [i32; 1000]; - var b: [i32; 1000]; + var a: array(i32, 1000); + var b: array(i32, 1000); var n: i32 = ReadInputs(&a, &b); Quicksort(&a, 0, n); Quicksort(&b, 0, n); diff --git a/examples/advent2024/day1_part2.carbon b/examples/advent2024/day1_part2.carbon index 65b98a6b37ad9..c725ffc818fb9 100644 --- a/examples/advent2024/day1_part2.carbon +++ b/examples/advent2024/day1_part2.carbon @@ -10,8 +10,8 @@ import library "day1_common"; import library "sort"; fn Run() { - var a: [i32; 1000]; - var b: [i32; 1000]; + var a: array(i32, 1000); + var b: array(i32, 1000); var n: i32 = ReadInputs(&a, &b); Quicksort(&a, 0, n); Quicksort(&b, 0, n); diff --git a/examples/advent2024/day2_part2.carbon b/examples/advent2024/day2_part2.carbon index e085e655c32fc..9559c79595e7f 100644 --- a/examples/advent2024/day2_part2.carbon +++ b/examples/advent2024/day2_part2.carbon @@ -19,7 +19,7 @@ class Window { ++self->size; } - var data: [i32; 3]; + var data: array(i32, 3); var size: i32; } diff --git a/examples/advent2024/day4_common.carbon b/examples/advent2024/day4_common.carbon index 9f42bd129f3e3..f734b4821b0ac 100644 --- a/examples/advent2024/day4_common.carbon +++ b/examples/advent2024/day4_common.carbon @@ -32,7 +32,7 @@ class Wordsearch { } // TODO: Make this generic in the length of the search query. - fn Check4[self: Self](xmas: [i32; 4], x: i32, y: i32, dx: i32, dy: i32) -> bool { + fn Check4[self: Self](xmas: array(i32, 4), x: i32, y: i32, dx: i32, dy: i32) -> bool { var i: i32 = 0; while (i < 4) { if (self.At(x + i * dx, y + i * dy) != xmas[i]) { @@ -43,7 +43,7 @@ class Wordsearch { return true; } - fn Check3[self: Self](mas: [i32; 3], x: i32, y: i32, dx: i32, dy: i32) -> bool { + fn Check3[self: Self](mas: array(i32, 3), x: i32, y: i32, dx: i32, dy: i32) -> bool { var i: i32 = 0; while (i < 3) { if (self.At(x + i * dx, y + i * dy) != mas[i]) { @@ -54,5 +54,5 @@ class Wordsearch { return true; } - var grid: [[i32; 140]; 140]; + var grid: array(array(i32, 140), 140); } diff --git a/examples/advent2024/day4_part1.carbon b/examples/advent2024/day4_part1.carbon index 938f90da0ffda..7bcce71d2fa69 100644 --- a/examples/advent2024/day4_part1.carbon +++ b/examples/advent2024/day4_part1.carbon @@ -11,7 +11,7 @@ import library "io_utils"; fn Run() { var search: Wordsearch = Wordsearch.Read(); - var xmas: [i32; 4] = (0x58, 0x4D, 0x41, 0x53); + var xmas: array(i32, 4) = (0x58, 0x4D, 0x41, 0x53); var found: i32 = 0; // TODO: Use for loops once they're implemented. diff --git a/examples/advent2024/day4_part2.carbon b/examples/advent2024/day4_part2.carbon index 291a5d69cff76..e685434c450d4 100644 --- a/examples/advent2024/day4_part2.carbon +++ b/examples/advent2024/day4_part2.carbon @@ -11,7 +11,7 @@ import library "io_utils"; fn Run() { var search: Wordsearch = Wordsearch.Read(); - var mas: [i32; 3] = (0x4D, 0x41, 0x53); + var mas: array(i32, 3) = (0x4D, 0x41, 0x53); var found: i32 = 0; // TODO: Use for loops once they're implemented. diff --git a/examples/advent2024/day5_common.carbon b/examples/advent2024/day5_common.carbon index d468790a9d267..58a26560e4c24 100644 --- a/examples/advent2024/day5_common.carbon +++ b/examples/advent2024/day5_common.carbon @@ -36,7 +36,7 @@ class Rules { return self.disallowed_before[b] & PageMask(a) == 0; } - var disallowed_before: [Core.UInt(100); 100]; + var disallowed_before: array(Core.UInt(100), 100); }; class PageList { @@ -112,6 +112,6 @@ class PageList { return self.pages[self.num_pages / 2]; } - var pages: [i32; 24]; + var pages: array(i32, 24); var num_pages: i32; }; diff --git a/examples/advent2024/day6_common.carbon b/examples/advent2024/day6_common.carbon index eb945d2bcd4b4..5da9cb1158c00 100644 --- a/examples/advent2024/day6_common.carbon +++ b/examples/advent2024/day6_common.carbon @@ -104,7 +104,7 @@ class Maze { return total; } - var data: [[i8; 130]; 130]; + var data: array(array(i8, 130), 130); var loc: (i32, i32); var dir: (i32, i32); } diff --git a/examples/advent2024/day7_common.carbon b/examples/advent2024/day7_common.carbon index d457cd5dc1c0c..a0dc05f187aa6 100644 --- a/examples/advent2024/day7_common.carbon +++ b/examples/advent2024/day7_common.carbon @@ -52,7 +52,7 @@ class Equation { return self.SolveFrom(1, self.operands[0], concat); } - var operands: [i64; 16]; + var operands: array(i64, 16); var num_operands: i32; var result: i64; } diff --git a/examples/advent2024/day8_common.carbon b/examples/advent2024/day8_common.carbon index 308f4743511c3..e86918cd9d3ef 100644 --- a/examples/advent2024/day8_common.carbon +++ b/examples/advent2024/day8_common.carbon @@ -25,5 +25,5 @@ class Grid { return var; } - var data: [[i32; 50]; 50]; + var data: array(array(i32, 50), 50); } diff --git a/examples/advent2024/day8_part2.carbon b/examples/advent2024/day8_part2.carbon index 2539e8754e825..6ee243c1fc373 100644 --- a/examples/advent2024/day8_part2.carbon +++ b/examples/advent2024/day8_part2.carbon @@ -9,7 +9,7 @@ import Core library "io"; import library "day8_common"; import library "io_utils"; -fn MarkAndCount(marks: [[bool; 50]; 50]*, x: i32, y: i32) -> i32 { +fn MarkAndCount(marks: array(array(bool, 50), 50)*, x: i32, y: i32) -> i32 { if (not (*marks)[x][y]) { (*marks)[x][y] = true; return 1; @@ -17,7 +17,7 @@ fn MarkAndCount(marks: [[bool; 50]; 50]*, x: i32, y: i32) -> i32 { return 0; } -fn MarkAndCountAntinodesFor(grid: Grid, marks: [[bool; 50]; 50]*, ax: i32, ay: i32) -> i32 { +fn MarkAndCountAntinodesFor(grid: Grid, marks: array(array(bool, 50), 50)*, ax: i32, ay: i32) -> i32 { var count: i32 = 0; var by: i32 = 0; while (by < 50) { @@ -44,7 +44,7 @@ fn MarkAndCountAntinodesFor(grid: Grid, marks: [[bool; 50]; 50]*, ax: i32, ay: i return count; } -fn MarkAndCountAntinodes(grid: Grid, marks: [[bool; 50]; 50]*) -> i32 { +fn MarkAndCountAntinodes(grid: Grid, marks: array(array(bool, 50), 50)*) -> i32 { var count: i32 = 0; var y: i32 = 0; while (y < 50) { @@ -61,7 +61,7 @@ fn MarkAndCountAntinodes(grid: Grid, marks: [[bool; 50]; 50]*) -> i32 { } fn Run() { - var marks: [[bool; 50]; 50]; + var marks: array(array(bool, 50), 50); var y: i32 = 0; while (y < 50) { var x: i32 = 0; diff --git a/examples/advent2024/day9_common.carbon b/examples/advent2024/day9_common.carbon index 52cc69abb2510..9b66138f5036e 100644 --- a/examples/advent2024/day9_common.carbon +++ b/examples/advent2024/day9_common.carbon @@ -116,6 +116,6 @@ class SectorList { return total; } - var data: [i32; 200000]; + var data: array(i32, 200000); var size: i32; } diff --git a/examples/advent2024/sort.carbon b/examples/advent2024/sort.carbon index c0be66c5a5da4..990ad91c9a674 100644 --- a/examples/advent2024/sort.carbon +++ b/examples/advent2024/sort.carbon @@ -7,13 +7,13 @@ library "sort"; // TODO: Generalize this for other container types once we implement lowering // for generic functions. -fn Swap(p: [i32; 1000]*, from: i32, to: i32) { +fn Swap(p: array(i32, 1000)*, from: i32, to: i32) { var tmp: i32 = (*p)[from]; (*p)[from] = (*p)[to]; (*p)[to] = tmp; } -fn Partition(p: [i32; 1000]*, from_in: i32, to_in: i32) -> i32 { +fn Partition(p: array(i32, 1000)*, from_in: i32, to_in: i32) -> i32 { var pivot_index: i32 = from_in; var pivot: i32 = (*p)[pivot_index]; var from: i32 = from_in + 1; @@ -35,7 +35,7 @@ fn Partition(p: [i32; 1000]*, from_in: i32, to_in: i32) -> i32 { return from - 1; } -fn Quicksort(p: [i32; 1000]*, from: i32, to: i32) { +fn Quicksort(p: array(i32, 1000)*, from: i32, to: i32) { if (from + 1 >= to) { return; } var pivot: i32 = Partition(p, from, to); Quicksort(p, from, pivot); diff --git a/examples/sieve.carbon b/examples/sieve.carbon index 9fddf037330b6..0753cc604fb00 100644 --- a/examples/sieve.carbon +++ b/examples/sieve.carbon @@ -28,7 +28,7 @@ class Sieve { } } - var is_prime: [bool; 1000]; + var is_prime: array(bool, 1000); } fn Run() -> i32 { diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 8016a5f630b4f..e61b06325e0b6 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -935,7 +935,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id, } } - // A tuple (T1, T2, ..., Tn) converts to [T; n] if each Ti converts to T. + // A tuple (T1, T2, ..., Tn) converts to array(T, n) if each Ti converts to T. if (auto target_array_type = target_type_inst.TryAs()) { if (auto src_tuple_type = sem_ir.types().TryGetAs(value_type_id)) { diff --git a/toolchain/check/fuzzer_corpus/dd0aadb8d4ae92d3f07fd7f03c9bfcdc88b1f6bc b/toolchain/check/fuzzer_corpus/0444b366b646a800d860d362876dec36afb41e42 similarity index 92% rename from toolchain/check/fuzzer_corpus/dd0aadb8d4ae92d3f07fd7f03c9bfcdc88b1f6bc rename to toolchain/check/fuzzer_corpus/0444b366b646a800d860d362876dec36afb41e42 index 7c15e78de911a..65a02ea4906f2 100644 --- a/toolchain/check/fuzzer_corpus/dd0aadb8d4ae92d3f07fd7f03c9bfcdc88b1f6bc +++ b/toolchain/check/fuzzer_corpus/0444b366b646a800d860d362876dec36afb41e42 @@ -20,6 +20,6 @@ class A{ fn Main() -> i32 { var a1: A = {.n = 2}; - var a: [A; 2] = ({.n = 1},{.n = 0}); + var a: array(A, 2) = ({.n = 1},{.n = 0}); return 1; } diff --git a/toolchain/check/fuzzer_corpus/0e272375f1c866bb051eab5262ad87da60f5ce8c b/toolchain/check/fuzzer_corpus/17dc6eb1bbb8fd9671f46aa63924cf1a76837a2c similarity index 89% rename from toolchain/check/fuzzer_corpus/0e272375f1c866bb051eab5262ad87da60f5ce8c rename to toolchain/check/fuzzer_corpus/17dc6eb1bbb8fd9671f46aa63924cf1a76837a2c index 9b9750ffebc90..1c46019341d98 100644 --- a/toolchain/check/fuzzer_corpus/0e272375f1c866bb051eab5262ad87da60f5ce8c +++ b/toolchain/check/fuzzer_corpus/17dc6eb1bbb8fd9671f46aa63924cf1a76837a2c @@ -22,11 +22,11 @@ impl i32 as ImplicitAs(A) { } fn Main() -> i32 { - var arr1: [i32; 2] = (1, 2 as A); + var arr1: array(i32, 2) = (1, 2 as A); Print("1: {0}", arr1[0]); Print("2: {0}", arr1[1]); - var arr2: [A; 2] = (3, 4 as A); + var arr2: array(A, 2) = (3, 4 as A); Print("3: {0}", arr2[0].n); Print("4: {0}", arr2[1].n); return 0; diff --git a/toolchain/check/fuzzer_corpus/9e2fa6d7320a5b7aa4a136fbc5b9fb9ba6c8d26a b/toolchain/check/fuzzer_corpus/1c56a65ba702fd27f5a72caf9c5e9170312db350 similarity index 81% rename from toolchain/check/fuzzer_corpus/9e2fa6d7320a5b7aa4a136fbc5b9fb9ba6c8d26a rename to toolchain/check/fuzzer_corpus/1c56a65ba702fd27f5a72caf9c5e9170312db350 index 16a0ede84e1c9..c415b6fdb96ef 100644 --- a/toolchain/check/fuzzer_corpus/9e2fa6d7320a5b7aa4a136fbc5b9fb9ba6c8d26a +++ b/toolchain/check/fuzzer_corpus/1c56a65ba702fd27f5a72caf9c5e9170312db350 @@ -7,7 +7,7 @@ package ExplorerTest; fn Main() -> i32 { - // CHECK:STDERR: COMPILATION ERROR: fail_size_mismatch.carbon:[[@LINE+1]]: type error in initializer of variable: '(i32, i32, i32)' is not implicitly convertible to '[i32; 2]' - var x: [i32; 2] = (0, 1, 2); + // CHECK:STDERR: COMPILATION ERROR: fail_size_mismatch.carbon:[[@LINE+1]]: type error in initializer of variable: '(i32, i32, i32)' is not implicitly convertible to 'array(i32, 2)' + var x: array(i32, 2) = (0, 1, 2); return x[0]; } diff --git a/toolchain/check/fuzzer_corpus/958211e37b230431232fd97eedce8db62b6c711e b/toolchain/check/fuzzer_corpus/306f80d197d3d627368e752f1ad6aa42d2e89aa6 similarity index 83% rename from toolchain/check/fuzzer_corpus/958211e37b230431232fd97eedce8db62b6c711e rename to toolchain/check/fuzzer_corpus/306f80d197d3d627368e752f1ad6aa42d2e89aa6 index 0dd7ee61d8881..35bf5968d2789 100644 --- a/toolchain/check/fuzzer_corpus/958211e37b230431232fd97eedce8db62b6c711e +++ b/toolchain/check/fuzzer_corpus/306f80d197d3d627368e752f1ad6aa42d2e89aa6 @@ -8,6 +8,6 @@ package ExplorerTest; fn Main() -> i32 { - var x: [[i32; 3]; 2] = ((0, 1, 2), (3, 4, 5)); + var x: array(array(i32, 3), 2) = ((0, 1, 2), (3, 4, 5)); return x[1][2] - 5; } diff --git a/toolchain/check/fuzzer_corpus/5ae87d7a9d55141806809261a2ea9fb567e70aae b/toolchain/check/fuzzer_corpus/310b6d61f64901b21169432ef6bbc13a2b602376 similarity index 92% rename from toolchain/check/fuzzer_corpus/5ae87d7a9d55141806809261a2ea9fb567e70aae rename to toolchain/check/fuzzer_corpus/310b6d61f64901b21169432ef6bbc13a2b602376 index 3821170619b62..29b3c789f6f8b 100644 --- a/toolchain/check/fuzzer_corpus/5ae87d7a9d55141806809261a2ea9fb567e70aae +++ b/toolchain/check/fuzzer_corpus/310b6d61f64901b21169432ef6bbc13a2b602376 @@ -9,6 +9,6 @@ package ExplorerTest; fn Main() -> i32 { var t: auto = (1, 2); - var a: [i32; 2] = t; + var a: array(i32, 2) = t; return a[0] + a[1]; } diff --git a/toolchain/check/fuzzer_corpus/9369cbcfcb8792587b18645cb5914fa5edeed78d b/toolchain/check/fuzzer_corpus/48f161ebf1c515fbc92fc959814c40d6394b5360 similarity index 91% rename from toolchain/check/fuzzer_corpus/9369cbcfcb8792587b18645cb5914fa5edeed78d rename to toolchain/check/fuzzer_corpus/48f161ebf1c515fbc92fc959814c40d6394b5360 index 28b4e51f7d3cc..86d13bbdcdc1e 100644 --- a/toolchain/check/fuzzer_corpus/9369cbcfcb8792587b18645cb5914fa5edeed78d +++ b/toolchain/check/fuzzer_corpus/48f161ebf1c515fbc92fc959814c40d6394b5360 @@ -8,7 +8,7 @@ package ExplorerTest; fn Main() -> i32 { - var arr: [i32; 2] = (0, 1); + var arr: array(i32, 2) = (0, 1); var x: [i32;] = arr; var index: i32 = 1; x[index] = 0; diff --git a/toolchain/check/fuzzer_corpus/8670e2da7432feef1ab66b434f95a97fc209b2b0 b/toolchain/check/fuzzer_corpus/54dab9151ed3293f3aec67e58aa20e26aa632a98 similarity index 93% rename from toolchain/check/fuzzer_corpus/8670e2da7432feef1ab66b434f95a97fc209b2b0 rename to toolchain/check/fuzzer_corpus/54dab9151ed3293f3aec67e58aa20e26aa632a98 index 3138db86109ca..2b0d8cc7f61c4 100644 --- a/toolchain/check/fuzzer_corpus/8670e2da7432feef1ab66b434f95a97fc209b2b0 +++ b/toolchain/check/fuzzer_corpus/54dab9151ed3293f3aec67e58aa20e26aa632a98 @@ -7,7 +7,7 @@ package ExplorerTest; fn Main() -> i32 { - var v: [i32; 2]; + var v: array(i32, 2); // CHECK:STDERR: COMPILATION ERROR: fail_array.carbon:[[@LINE+1]]: use of uninitialized variable v return v[0]; } diff --git a/toolchain/check/fuzzer_corpus/ae7557cf66185fad53df0aa262e52a4dbd8ff8da b/toolchain/check/fuzzer_corpus/b08132223d41827e2b8cd8f849ffb7ac4af4e993 similarity index 92% rename from toolchain/check/fuzzer_corpus/ae7557cf66185fad53df0aa262e52a4dbd8ff8da rename to toolchain/check/fuzzer_corpus/b08132223d41827e2b8cd8f849ffb7ac4af4e993 index 46d235406bc84..f77ab56aee24f 100644 --- a/toolchain/check/fuzzer_corpus/ae7557cf66185fad53df0aa262e52a4dbd8ff8da +++ b/toolchain/check/fuzzer_corpus/b08132223d41827e2b8cd8f849ffb7ac4af4e993 @@ -8,7 +8,7 @@ package ExplorerTest; fn Main() -> i32 { - var ar: [i32; 4] = (0, 1,2,3); + var ar: array(i32, 4) = (0, 1,2,3); var count : i32 = 0; for( x: i32 in ar){ count = count +1; diff --git a/toolchain/check/fuzzer_corpus/0ca753d0d0e5afc30bc37f855501c9db4776cb5c b/toolchain/check/fuzzer_corpus/b0e276497e7036c6b3c90deeff71a055256ed5e3 similarity index 92% rename from toolchain/check/fuzzer_corpus/0ca753d0d0e5afc30bc37f855501c9db4776cb5c rename to toolchain/check/fuzzer_corpus/b0e276497e7036c6b3c90deeff71a055256ed5e3 index c55c91ede5d1c..5516affc5b966 100644 --- a/toolchain/check/fuzzer_corpus/0ca753d0d0e5afc30bc37f855501c9db4776cb5c +++ b/toolchain/check/fuzzer_corpus/b0e276497e7036c6b3c90deeff71a055256ed5e3 @@ -9,7 +9,7 @@ package ExplorerTest; fn Main() -> i32 { - var ar: [i32; 0] = () ; + var ar: array(i32, 0) = () ; var count : i32 = 0; for( x: i32 in ar ){ count = 2; diff --git a/toolchain/check/fuzzer_corpus/530ca26b3435b4490f3e882c3837aef588592497 b/toolchain/check/fuzzer_corpus/bb0ee9a7c7f604c41cfef744a974c6603df4b0db similarity index 91% rename from toolchain/check/fuzzer_corpus/530ca26b3435b4490f3e882c3837aef588592497 rename to toolchain/check/fuzzer_corpus/bb0ee9a7c7f604c41cfef744a974c6603df4b0db index a7d39d8098e17..3f4c8c6a5794c 100644 --- a/toolchain/check/fuzzer_corpus/530ca26b3435b4490f3e882c3837aef588592497 +++ b/toolchain/check/fuzzer_corpus/bb0ee9a7c7f604c41cfef744a974c6603df4b0db @@ -7,7 +7,7 @@ package ExplorerTest; fn Main() -> i32 { - var x: [i32; 2] = (0, 1); + var x: array(i32, 2) = (0, 1); // CHECK:STDERR: RUNTIME ERROR: fail_index.carbon:[[@LINE+1]]: index 2 out of range in (0, 1) return x[2]; } diff --git a/toolchain/check/fuzzer_corpus/431077e0b0c67e3442d71fc8dd7b1664c3287b3a b/toolchain/check/fuzzer_corpus/dbd0b78b1bfd4878676ac3d882aee2b797d7af15 similarity index 82% rename from toolchain/check/fuzzer_corpus/431077e0b0c67e3442d71fc8dd7b1664c3287b3a rename to toolchain/check/fuzzer_corpus/dbd0b78b1bfd4878676ac3d882aee2b797d7af15 index 09b7bd6181e3e..1b7295c748739 100644 --- a/toolchain/check/fuzzer_corpus/431077e0b0c67e3442d71fc8dd7b1664c3287b3a +++ b/toolchain/check/fuzzer_corpus/dbd0b78b1bfd4878676ac3d882aee2b797d7af15 @@ -22,7 +22,7 @@ class A{ } fn Main() -> i32 { - var a: [A; 2] = ({.n = 6},{.n = 5}); - var b: [[A; 2]; 2] = (({.n = 4},{.n = 3}), ({.n = 2},{.n = 1})); + var a: array(A, 2) = ({.n = 6},{.n = 5}); + var b: array(array(A, 2), 2) = (({.n = 4},{.n = 3}), ({.n = 2},{.n = 1})); return 1; } diff --git a/toolchain/check/fuzzer_corpus/9a9abdfff166a4ff4ee660bcce9ec0ba6844d028 b/toolchain/check/fuzzer_corpus/f2b43d44db5dec0cca4bc6fc63f487fabae1b941 similarity index 92% rename from toolchain/check/fuzzer_corpus/9a9abdfff166a4ff4ee660bcce9ec0ba6844d028 rename to toolchain/check/fuzzer_corpus/f2b43d44db5dec0cca4bc6fc63f487fabae1b941 index 6af810d10f738..5e6bf2db9e893 100644 --- a/toolchain/check/fuzzer_corpus/9a9abdfff166a4ff4ee660bcce9ec0ba6844d028 +++ b/toolchain/check/fuzzer_corpus/f2b43d44db5dec0cca4bc6fc63f487fabae1b941 @@ -8,6 +8,6 @@ package ExplorerTest; fn Main() -> i32 { // CHECK:STDERR: COMPILATION ERROR: fail_negative_size.carbon:[[@LINE+1]]: Array size cannot be negative - var x: [i32; -1] = (); + var x: array(i32, -1) = (); return x[0]; } diff --git a/toolchain/check/fuzzer_corpus/45051e270ef1a1b856e7e0a9ad17925204e7efee b/toolchain/check/fuzzer_corpus/f71cbd0475ddb41b78a0d439aa78ae1e2eec0df5 similarity index 91% rename from toolchain/check/fuzzer_corpus/45051e270ef1a1b856e7e0a9ad17925204e7efee rename to toolchain/check/fuzzer_corpus/f71cbd0475ddb41b78a0d439aa78ae1e2eec0df5 index 23aeaa5545769..00f052f3019de 100644 --- a/toolchain/check/fuzzer_corpus/45051e270ef1a1b856e7e0a9ad17925204e7efee +++ b/toolchain/check/fuzzer_corpus/f71cbd0475ddb41b78a0d439aa78ae1e2eec0df5 @@ -11,7 +11,7 @@ package ExplorerTest; fn Main() -> i32 { - var ar: [i32; 4] = (0, 1,2,3); + var ar: array(i32, 4) = (0, 1,2,3); var count : i32 = 0; for( x: i32 in ar){ count = count +x; diff --git a/toolchain/check/handle_array.cpp b/toolchain/check/handle_array.cpp index 943334cd46aff..33ad2d2d9378b 100644 --- a/toolchain/check/handle_array.cpp +++ b/toolchain/check/handle_array.cpp @@ -11,27 +11,23 @@ namespace Carbon::Check { -auto HandleParseNode(Context& /*context*/, Parse::ArrayExprStartId /*node_id*/) - -> bool { +auto HandleParseNode(Context& /*context*/, + Parse::ArrayExprOpenParenId /*node_id*/) -> bool { return true; } -auto HandleParseNode(Context& context, Parse::ArrayExprSemiId node_id) -> bool { - context.node_stack().Push(node_id); +auto HandleParseNode(Context& /*context*/, + Parse::ArrayExprKeywordId /*node_id*/) -> bool { return true; } -auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool { - // TODO: Handle array type with undefined bound. - if (context.node_stack() - .PopAndDiscardSoloNodeIdIf()) { - context.node_stack().PopAndIgnore(); - return context.TODO(node_id, "HandleArrayExprWithoutBounds"); - } +auto HandleParseNode(Context& /*context*/, Parse::ArrayExprCommaId /*node_id*/) + -> bool { + return true; +} +auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool { auto bound_inst_id = context.node_stack().PopExpr(); - context.node_stack() - .PopAndDiscardSoloNodeId(); auto [element_type_node_id, element_type_inst_id] = context.node_stack().PopExprWithNodeId(); @@ -43,7 +39,7 @@ auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool { // call to compile-time-only function" error. // // TODO: Should we support runtime-phase bounds in cases such as: - // comptime fn F(n: i32) -> type { return [i32; n]; } + // comptime fn F(n: i32) -> type { return array(i32; n); } if (!context.constant_values().Get(bound_inst_id).is_constant()) { CARBON_DIAGNOSTIC(InvalidArrayExpr, Error, "array bound is not a constant"); context.emitter().Emit(bound_inst_id, InvalidArrayExpr); diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index fe05db6d3b07b..0dea644ee397e 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -426,7 +426,6 @@ class NodeStack { case Parse::NodeKind::DefaultLibrary: case Parse::NodeKind::LibraryName: return Id::KindFor(); - case Parse::NodeKind::ArrayExprSemi: case Parse::NodeKind::BuiltinName: case Parse::NodeKind::ChoiceIntroducer: case Parse::NodeKind::ClassIntroducer: @@ -452,7 +451,9 @@ class NodeStack { case Parse::NodeKind::AdaptIntroducer: case Parse::NodeKind::AliasInitializer: case Parse::NodeKind::AliasIntroducer: - case Parse::NodeKind::ArrayExprStart: + case Parse::NodeKind::ArrayExprComma: + case Parse::NodeKind::ArrayExprKeyword: + case Parse::NodeKind::ArrayExprOpenParen: case Parse::NodeKind::BaseColon: case Parse::NodeKind::BaseIntroducer: case Parse::NodeKind::BreakStatementStart: diff --git a/toolchain/check/testdata/array/array_in_place.carbon b/toolchain/check/testdata/array/array_in_place.carbon index 01de23daf8792..3d469c5671c1b 100644 --- a/toolchain/check/testdata/array/array_in_place.carbon +++ b/toolchain/check/testdata/array/array_in_place.carbon @@ -11,7 +11,7 @@ fn F() -> (i32, i32, i32); fn G() { - var v: [(i32, i32, i32); 2] = (F(), F()); + var v: array((i32, i32, i32), 2) = (F(), F()); } // CHECK:STDOUT: --- array_in_place.carbon @@ -74,32 +74,32 @@ fn G() { // CHECK:STDOUT: %.loc14_3.1: %array_type = var_pattern %v.patt // CHECK:STDOUT: } // CHECK:STDOUT: %v.var: ref %array_type = var v -// CHECK:STDOUT: %F.ref.loc14_34: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %.loc14_42.1: ref %tuple.type.189 = splice_block %.loc14_42.2 { +// CHECK:STDOUT: %F.ref.loc14_39: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %.loc14_47.1: ref %tuple.type.189 = splice_block %.loc14_47.2 { // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc14_42.2: ref %tuple.type.189 = array_index %v.var, %int_0 +// CHECK:STDOUT: %.loc14_47.2: ref %tuple.type.189 = array_index %v.var, %int_0 // CHECK:STDOUT: } -// CHECK:STDOUT: %F.call.loc14_36: init %tuple.type.189 = call %F.ref.loc14_34() to %.loc14_42.1 -// CHECK:STDOUT: %F.ref.loc14_39: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %.loc14_42.3: ref %tuple.type.189 = splice_block %.loc14_42.4 { +// CHECK:STDOUT: %F.call.loc14_41: init %tuple.type.189 = call %F.ref.loc14_39() to %.loc14_47.1 +// CHECK:STDOUT: %F.ref.loc14_44: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %.loc14_47.3: ref %tuple.type.189 = splice_block %.loc14_47.4 { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc14_42.4: ref %tuple.type.189 = array_index %v.var, %int_1 +// CHECK:STDOUT: %.loc14_47.4: ref %tuple.type.189 = array_index %v.var, %int_1 // CHECK:STDOUT: } -// CHECK:STDOUT: %F.call.loc14_41: init %tuple.type.189 = call %F.ref.loc14_39() to %.loc14_42.3 -// CHECK:STDOUT: %.loc14_42.5: %tuple.type.99b = tuple_literal (%F.call.loc14_36, %F.call.loc14_41) -// CHECK:STDOUT: %.loc14_42.6: init %array_type = array_init (%F.call.loc14_36, %F.call.loc14_41) to %v.var -// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %.loc14_42.5, %.loc14_42.6 +// CHECK:STDOUT: %F.call.loc14_46: init %tuple.type.189 = call %F.ref.loc14_44() to %.loc14_47.3 +// CHECK:STDOUT: %.loc14_47.5: %tuple.type.99b = tuple_literal (%F.call.loc14_41, %F.call.loc14_46) +// CHECK:STDOUT: %.loc14_47.6: init %array_type = array_init (%F.call.loc14_41, %F.call.loc14_46) to %v.var +// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %.loc14_47.5, %.loc14_47.6 // CHECK:STDOUT: assign %v.var, %.loc14_3.2 -// CHECK:STDOUT: %.loc14_29: type = splice_block %array_type [concrete = constants.%array_type] { -// CHECK:STDOUT: %int_32.loc14_12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc14_12: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc14_34: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc14_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc14_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_32.loc14_22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc14_22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %.loc14_25.1: %tuple.type.ff9 = tuple_literal (%i32.loc14_12, %i32.loc14_17, %i32.loc14_22) +// CHECK:STDOUT: %int_32.loc14_27: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc14_27: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc14_30.1: %tuple.type.ff9 = tuple_literal (%i32.loc14_17, %i32.loc14_22, %i32.loc14_27) // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc14_25.2: type = converted %.loc14_25.1, constants.%tuple.type.189 [concrete = constants.%tuple.type.189] +// CHECK:STDOUT: %.loc14_30.2: type = converted %.loc14_30.1, constants.%tuple.type.189 [concrete = constants.%tuple.type.189] // CHECK:STDOUT: %array_type: type = array_type %int_2, %tuple.type.189 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref %array_type = bind_name v, %v.var diff --git a/toolchain/check/testdata/array/array_vs_tuple.carbon b/toolchain/check/testdata/array/array_vs_tuple.carbon index d2a5ec242e18a..1708659da78ff 100644 --- a/toolchain/check/testdata/array/array_vs_tuple.carbon +++ b/toolchain/check/testdata/array/array_vs_tuple.carbon @@ -10,7 +10,7 @@ fn G() { // These should have two different constant values. - var a: [i32; 3] = (1, 2, 3); + var a: array(i32, 3) = (1, 2, 3); var b: (i32, i32, i32) = (1, 2, 3); } @@ -74,42 +74,42 @@ fn G() { // CHECK:STDOUT: %.loc13_3.1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %int_1.loc13_22: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc13_25: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_3.loc13_28: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc13_29.1: %tuple.type.37f = tuple_literal (%int_1.loc13_22, %int_2.loc13_25, %int_3.loc13_28) -// CHECK:STDOUT: %impl.elem0.loc13_29.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc13_29.1: = bound_method %int_1.loc13_22, %impl.elem0.loc13_29.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc13_29.1: = specific_function %bound_method.loc13_29.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc13_29.1: init %i32 = call %specific_fn.loc13_29.1(%int_1.loc13_22) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc13_29.2: init %i32 = converted %int_1.loc13_22, %int.convert_checked.loc13_29.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int_1.loc13_27: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc13_30: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_3.loc13_33: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc13_34.1: %tuple.type.37f = tuple_literal (%int_1.loc13_27, %int_2.loc13_30, %int_3.loc13_33) +// CHECK:STDOUT: %impl.elem0.loc13_34.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc13_34.1: = bound_method %int_1.loc13_27, %impl.elem0.loc13_34.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc13_34.1: = specific_function %bound_method.loc13_34.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc13_34.1: init %i32 = call %specific_fn.loc13_34.1(%int_1.loc13_27) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc13_34.2: init %i32 = converted %int_1.loc13_27, %int.convert_checked.loc13_34.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc13_29.3: ref %i32 = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc13_29.4: init %i32 = initialize_from %.loc13_29.2 to %.loc13_29.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc13_29.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc13_29.2: = bound_method %int_2.loc13_25, %impl.elem0.loc13_29.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc13_29.2: = specific_function %bound_method.loc13_29.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc13_29.2: init %i32 = call %specific_fn.loc13_29.2(%int_2.loc13_25) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc13_29.5: init %i32 = converted %int_2.loc13_25, %int.convert_checked.loc13_29.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc13_29: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc13_29.6: ref %i32 = array_index %a.var, %int_1.loc13_29 -// CHECK:STDOUT: %.loc13_29.7: init %i32 = initialize_from %.loc13_29.5 to %.loc13_29.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc13_29.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc13_29.3: = bound_method %int_3.loc13_28, %impl.elem0.loc13_29.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc13_29.3: = specific_function %bound_method.loc13_29.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc13_29.3: init %i32 = call %specific_fn.loc13_29.3(%int_3.loc13_28) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc13_29.8: init %i32 = converted %int_3.loc13_28, %int.convert_checked.loc13_29.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc13_29: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc13_29.9: ref %i32 = array_index %a.var, %int_2.loc13_29 -// CHECK:STDOUT: %.loc13_29.10: init %i32 = initialize_from %.loc13_29.8 to %.loc13_29.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc13_29.11: init %array_type = array_init (%.loc13_29.4, %.loc13_29.7, %.loc13_29.10) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc13_3.2: init %array_type = converted %.loc13_29.1, %.loc13_29.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc13_34.3: ref %i32 = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc13_34.4: init %i32 = initialize_from %.loc13_34.2 to %.loc13_34.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc13_34.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc13_34.2: = bound_method %int_2.loc13_30, %impl.elem0.loc13_34.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc13_34.2: = specific_function %bound_method.loc13_34.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc13_34.2: init %i32 = call %specific_fn.loc13_34.2(%int_2.loc13_30) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc13_34.5: init %i32 = converted %int_2.loc13_30, %int.convert_checked.loc13_34.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc13_34: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc13_34.6: ref %i32 = array_index %a.var, %int_1.loc13_34 +// CHECK:STDOUT: %.loc13_34.7: init %i32 = initialize_from %.loc13_34.5 to %.loc13_34.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc13_34.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc13_34.3: = bound_method %int_3.loc13_33, %impl.elem0.loc13_34.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc13_34.3: = specific_function %bound_method.loc13_34.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc13_34.3: init %i32 = call %specific_fn.loc13_34.3(%int_3.loc13_33) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc13_34.8: init %i32 = converted %int_3.loc13_33, %int.convert_checked.loc13_34.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc13_34: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc13_34.9: ref %i32 = array_index %a.var, %int_2.loc13_34 +// CHECK:STDOUT: %.loc13_34.10: init %i32 = initialize_from %.loc13_34.8 to %.loc13_34.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc13_34.11: init %array_type = array_init (%.loc13_34.4, %.loc13_34.7, %.loc13_34.10) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc13_3.2: init %array_type = converted %.loc13_34.1, %.loc13_34.11 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc13_3.2 -// CHECK:STDOUT: %.loc13_17: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc13_22: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc13: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_3.loc13_16: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type: type = array_type %int_3.loc13_16, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %int_3.loc13_21: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type: type = array_type %int_3.loc13_21, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %array_type = bind_name a, %a.var // CHECK:STDOUT: name_binding_decl { diff --git a/toolchain/check/testdata/array/assign_return_value.carbon b/toolchain/check/testdata/array/assign_return_value.carbon index 6c3a75b3e6818..7a7f6723d6ded 100644 --- a/toolchain/check/testdata/array/assign_return_value.carbon +++ b/toolchain/check/testdata/array/assign_return_value.carbon @@ -11,7 +11,7 @@ fn F() -> (i32,) { return (0,); } fn Run() { - var t: [i32; 1] = F(); + var t: array(i32, 1) = F(); } // CHECK:STDOUT: --- assign_return_value.carbon @@ -96,17 +96,17 @@ fn Run() { // CHECK:STDOUT: %t.var: ref %array_type = var t // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] // CHECK:STDOUT: %F.call: init %tuple.type.a1c = call %F.ref() -// CHECK:STDOUT: %.loc14_23.1: ref %tuple.type.a1c = temporary_storage -// CHECK:STDOUT: %.loc14_23.2: ref %tuple.type.a1c = temporary %.loc14_23.1, %F.call -// CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %.loc14_23.2, element0 -// CHECK:STDOUT: %.loc14_23.3: %i32 = bind_value %tuple.elem0 +// CHECK:STDOUT: %.loc14_28.1: ref %tuple.type.a1c = temporary_storage +// CHECK:STDOUT: %.loc14_28.2: ref %tuple.type.a1c = temporary %.loc14_28.1, %F.call +// CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %.loc14_28.2, element0 +// CHECK:STDOUT: %.loc14_28.3: %i32 = bind_value %tuple.elem0 // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc14_23.4: ref %i32 = array_index %t.var, %int_0 -// CHECK:STDOUT: %.loc14_23.5: init %i32 = initialize_from %.loc14_23.3 to %.loc14_23.4 -// CHECK:STDOUT: %.loc14_23.6: init %array_type = array_init (%.loc14_23.5) to %t.var -// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %F.call, %.loc14_23.6 +// CHECK:STDOUT: %.loc14_28.4: ref %i32 = array_index %t.var, %int_0 +// CHECK:STDOUT: %.loc14_28.5: init %i32 = initialize_from %.loc14_28.3 to %.loc14_28.4 +// CHECK:STDOUT: %.loc14_28.6: init %array_type = array_init (%.loc14_28.5) to %t.var +// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %F.call, %.loc14_28.6 // CHECK:STDOUT: assign %t.var, %.loc14_3.2 -// CHECK:STDOUT: %.loc14_17: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc14_22: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] diff --git a/toolchain/check/testdata/array/assign_var.carbon b/toolchain/check/testdata/array/assign_var.carbon index 1e3b17c452dba..6d255d0f94440 100644 --- a/toolchain/check/testdata/array/assign_var.carbon +++ b/toolchain/check/testdata/array/assign_var.carbon @@ -9,7 +9,7 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/assign_var.carbon var a: (i32, i32, i32) = (1, 2, 3); -var b: [i32; 3] = a; +var b: array(i32, 3) = a; // CHECK:STDOUT: --- assign_var.carbon // CHECK:STDOUT: @@ -80,7 +80,7 @@ var b: [i32; 3] = a; // CHECK:STDOUT: %.loc12_1: %array_type = var_pattern %b.patt // CHECK:STDOUT: } // CHECK:STDOUT: %b.var: ref %array_type = var b -// CHECK:STDOUT: %.loc12_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc12_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc12: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] @@ -121,22 +121,22 @@ var b: [i32; 3] = a; // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref: ref %tuple.type.189 = name_ref a, file.%a // CHECK:STDOUT: %tuple.elem0.loc12: ref %i32 = tuple_access %a.ref, element0 -// CHECK:STDOUT: %.loc12_19.1: %i32 = bind_value %tuple.elem0.loc12 +// CHECK:STDOUT: %.loc12_24.1: %i32 = bind_value %tuple.elem0.loc12 // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc12_19.2: ref %i32 = array_index file.%b.var, %int_0 -// CHECK:STDOUT: %.loc12_19.3: init %i32 = initialize_from %.loc12_19.1 to %.loc12_19.2 +// CHECK:STDOUT: %.loc12_24.2: ref %i32 = array_index file.%b.var, %int_0 +// CHECK:STDOUT: %.loc12_24.3: init %i32 = initialize_from %.loc12_24.1 to %.loc12_24.2 // CHECK:STDOUT: %tuple.elem1.loc12: ref %i32 = tuple_access %a.ref, element1 -// CHECK:STDOUT: %.loc12_19.4: %i32 = bind_value %tuple.elem1.loc12 +// CHECK:STDOUT: %.loc12_24.4: %i32 = bind_value %tuple.elem1.loc12 // CHECK:STDOUT: %int_1.loc12: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc12_19.5: ref %i32 = array_index file.%b.var, %int_1.loc12 -// CHECK:STDOUT: %.loc12_19.6: init %i32 = initialize_from %.loc12_19.4 to %.loc12_19.5 +// CHECK:STDOUT: %.loc12_24.5: ref %i32 = array_index file.%b.var, %int_1.loc12 +// CHECK:STDOUT: %.loc12_24.6: init %i32 = initialize_from %.loc12_24.4 to %.loc12_24.5 // CHECK:STDOUT: %tuple.elem2.loc12: ref %i32 = tuple_access %a.ref, element2 -// CHECK:STDOUT: %.loc12_19.7: %i32 = bind_value %tuple.elem2.loc12 +// CHECK:STDOUT: %.loc12_24.7: %i32 = bind_value %tuple.elem2.loc12 // CHECK:STDOUT: %int_2.loc12: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc12_19.8: ref %i32 = array_index file.%b.var, %int_2.loc12 -// CHECK:STDOUT: %.loc12_19.9: init %i32 = initialize_from %.loc12_19.7 to %.loc12_19.8 -// CHECK:STDOUT: %.loc12_19.10: init %array_type = array_init (%.loc12_19.3, %.loc12_19.6, %.loc12_19.9) to file.%b.var -// CHECK:STDOUT: %.loc12_1: init %array_type = converted %a.ref, %.loc12_19.10 +// CHECK:STDOUT: %.loc12_24.8: ref %i32 = array_index file.%b.var, %int_2.loc12 +// CHECK:STDOUT: %.loc12_24.9: init %i32 = initialize_from %.loc12_24.7 to %.loc12_24.8 +// CHECK:STDOUT: %.loc12_24.10: init %array_type = array_init (%.loc12_24.3, %.loc12_24.6, %.loc12_24.9) to file.%b.var +// CHECK:STDOUT: %.loc12_1: init %array_type = converted %a.ref, %.loc12_24.10 // CHECK:STDOUT: assign file.%b.var, %.loc12_1 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/array/base.carbon b/toolchain/check/testdata/array/base.carbon index e50104610842d..edc9fa2ce27b6 100644 --- a/toolchain/check/testdata/array/base.carbon +++ b/toolchain/check/testdata/array/base.carbon @@ -8,9 +8,9 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/base.carbon -var a: [i32; 1] = (1,); -var b: [f64; 2] = (11.1, 2.2,); -var c: [(); 5] = ((), (), (), (), (),); +var a: array(i32, 1) = (1,); +var b: array(f64, 2) = (11.1, 2.2,); +var c: array((), 5) = ((), (), (), (), (),); // CHECK:STDOUT: --- base.carbon // CHECK:STDOUT: @@ -74,7 +74,7 @@ var c: [(); 5] = ((), (), (), (), (),); // CHECK:STDOUT: %.loc11_1: %array_type.0cb = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.0cb = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type.loc11 [concrete = constants.%array_type.0cb] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type.loc11 [concrete = constants.%array_type.0cb] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -86,12 +86,12 @@ var c: [(); 5] = ((), (), (), (), (),); // CHECK:STDOUT: %.loc12_1: %array_type.ce7 = var_pattern %b.patt // CHECK:STDOUT: } // CHECK:STDOUT: %b.var: ref %array_type.ce7 = var b -// CHECK:STDOUT: %.loc12_15: type = splice_block %array_type.loc12 [concrete = constants.%array_type.ce7] { +// CHECK:STDOUT: %.loc12_20: type = splice_block %array_type.loc12 [concrete = constants.%array_type.ce7] { // CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] // CHECK:STDOUT: %float.make_type: init type = call constants.%Float(%int_64) [concrete = f64] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc12_9.1: type = value_of_initializer %float.make_type [concrete = f64] -// CHECK:STDOUT: %.loc12_9.2: type = converted %float.make_type, %.loc12_9.1 [concrete = f64] +// CHECK:STDOUT: %.loc12_14.1: type = value_of_initializer %float.make_type [concrete = f64] +// CHECK:STDOUT: %.loc12_14.2: type = converted %float.make_type, %.loc12_14.1 [concrete = f64] // CHECK:STDOUT: %array_type.loc12: type = array_type %int_2, f64 [concrete = constants.%array_type.ce7] // CHECK:STDOUT: } // CHECK:STDOUT: %b: ref %array_type.ce7 = bind_name b, %b.var @@ -100,10 +100,10 @@ var c: [(); 5] = ((), (), (), (), (),); // CHECK:STDOUT: %.loc13_1: %array_type.c13 = var_pattern %c.patt // CHECK:STDOUT: } // CHECK:STDOUT: %c.var: ref %array_type.c13 = var c -// CHECK:STDOUT: %.loc13_14: type = splice_block %array_type.loc13 [concrete = constants.%array_type.c13] { -// CHECK:STDOUT: %.loc13_10.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_19: type = splice_block %array_type.loc13 [concrete = constants.%array_type.c13] { +// CHECK:STDOUT: %.loc13_15.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5] -// CHECK:STDOUT: %.loc13_10.2: type = converted %.loc13_10.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc13_15.2: type = converted %.loc13_15.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %array_type.loc13: type = array_type %int_5, %empty_tuple.type [concrete = constants.%array_type.c13] // CHECK:STDOUT: } // CHECK:STDOUT: %c: ref %array_type.c13 = bind_name c, %c.var @@ -112,58 +112,58 @@ var c: [(); 5] = ((), (), (), (), (),); // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_1.loc11: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc11_22.1: %tuple.type.985 = tuple_literal (%int_1.loc11) +// CHECK:STDOUT: %.loc11_27.1: %tuple.type.985 = tuple_literal (%int_1.loc11) // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] // CHECK:STDOUT: %bound_method: = bound_method %int_1.loc11, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_1.loc11) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc11_22.2: init %i32 = converted %int_1.loc11, %int.convert_checked [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_27.2: init %i32 = converted %int_1.loc11, %int.convert_checked [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0.loc11: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_22.3: ref %i32 = array_index file.%a.var, %int_0.loc11 -// CHECK:STDOUT: %.loc11_22.4: init %i32 = initialize_from %.loc11_22.2 to %.loc11_22.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc11_22.5: init %array_type.0cb = array_init (%.loc11_22.4) to file.%a.var [concrete = constants.%array.237] -// CHECK:STDOUT: %.loc11_1: init %array_type.0cb = converted %.loc11_22.1, %.loc11_22.5 [concrete = constants.%array.237] +// CHECK:STDOUT: %.loc11_27.3: ref %i32 = array_index file.%a.var, %int_0.loc11 +// CHECK:STDOUT: %.loc11_27.4: init %i32 = initialize_from %.loc11_27.2 to %.loc11_27.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_27.5: init %array_type.0cb = array_init (%.loc11_27.4) to file.%a.var [concrete = constants.%array.237] +// CHECK:STDOUT: %.loc11_1: init %array_type.0cb = converted %.loc11_27.1, %.loc11_27.5 [concrete = constants.%array.237] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 -// CHECK:STDOUT: %float.loc12_20: f64 = float_literal 11.100000000000001 [concrete = constants.%float.6e4] -// CHECK:STDOUT: %float.loc12_26: f64 = float_literal 2.2000000000000002 [concrete = constants.%float.9f7] -// CHECK:STDOUT: %.loc12_30.1: %tuple.type.bdb = tuple_literal (%float.loc12_20, %float.loc12_26) +// CHECK:STDOUT: %float.loc12_25: f64 = float_literal 11.100000000000001 [concrete = constants.%float.6e4] +// CHECK:STDOUT: %float.loc12_31: f64 = float_literal 2.2000000000000002 [concrete = constants.%float.9f7] +// CHECK:STDOUT: %.loc12_35.1: %tuple.type.bdb = tuple_literal (%float.loc12_25, %float.loc12_31) // CHECK:STDOUT: %int_0.loc12: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc12_30.2: ref f64 = array_index file.%b.var, %int_0.loc12 -// CHECK:STDOUT: %.loc12_30.3: init f64 = initialize_from %float.loc12_20 to %.loc12_30.2 [concrete = constants.%float.6e4] +// CHECK:STDOUT: %.loc12_35.2: ref f64 = array_index file.%b.var, %int_0.loc12 +// CHECK:STDOUT: %.loc12_35.3: init f64 = initialize_from %float.loc12_25 to %.loc12_35.2 [concrete = constants.%float.6e4] // CHECK:STDOUT: %int_1.loc12: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc12_30.4: ref f64 = array_index file.%b.var, %int_1.loc12 -// CHECK:STDOUT: %.loc12_30.5: init f64 = initialize_from %float.loc12_26 to %.loc12_30.4 [concrete = constants.%float.9f7] -// CHECK:STDOUT: %.loc12_30.6: init %array_type.ce7 = array_init (%.loc12_30.3, %.loc12_30.5) to file.%b.var [concrete = constants.%array.6a2] -// CHECK:STDOUT: %.loc12_1: init %array_type.ce7 = converted %.loc12_30.1, %.loc12_30.6 [concrete = constants.%array.6a2] +// CHECK:STDOUT: %.loc12_35.4: ref f64 = array_index file.%b.var, %int_1.loc12 +// CHECK:STDOUT: %.loc12_35.5: init f64 = initialize_from %float.loc12_31 to %.loc12_35.4 [concrete = constants.%float.9f7] +// CHECK:STDOUT: %.loc12_35.6: init %array_type.ce7 = array_init (%.loc12_35.3, %.loc12_35.5) to file.%b.var [concrete = constants.%array.6a2] +// CHECK:STDOUT: %.loc12_1: init %array_type.ce7 = converted %.loc12_35.1, %.loc12_35.6 [concrete = constants.%array.6a2] // CHECK:STDOUT: assign file.%b.var, %.loc12_1 -// CHECK:STDOUT: %.loc13_20.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_24.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_28.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_32.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_36.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_38.1: %tuple.type.5b2 = tuple_literal (%.loc13_20.1, %.loc13_24.1, %.loc13_28.1, %.loc13_32.1, %.loc13_36.1) +// CHECK:STDOUT: %.loc13_25.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_29.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_33.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_37.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_41.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_43.1: %tuple.type.5b2 = tuple_literal (%.loc13_25.1, %.loc13_29.1, %.loc13_33.1, %.loc13_37.1, %.loc13_41.1) // CHECK:STDOUT: %int_0.loc13: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc13_38.2: ref %empty_tuple.type = array_index file.%c.var, %int_0.loc13 -// CHECK:STDOUT: %.loc13_20.2: init %empty_tuple.type = tuple_init () to %.loc13_38.2 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.3: init %empty_tuple.type = converted %.loc13_20.1, %.loc13_20.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.2: ref %empty_tuple.type = array_index file.%c.var, %int_0.loc13 +// CHECK:STDOUT: %.loc13_25.2: init %empty_tuple.type = tuple_init () to %.loc13_43.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.3: init %empty_tuple.type = converted %.loc13_25.1, %.loc13_25.2 [concrete = constants.%empty_tuple] // CHECK:STDOUT: %int_1.loc13: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc13_38.4: ref %empty_tuple.type = array_index file.%c.var, %int_1.loc13 -// CHECK:STDOUT: %.loc13_24.2: init %empty_tuple.type = tuple_init () to %.loc13_38.4 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.5: init %empty_tuple.type = converted %.loc13_24.1, %.loc13_24.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.4: ref %empty_tuple.type = array_index file.%c.var, %int_1.loc13 +// CHECK:STDOUT: %.loc13_29.2: init %empty_tuple.type = tuple_init () to %.loc13_43.4 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.5: init %empty_tuple.type = converted %.loc13_29.1, %.loc13_29.2 [concrete = constants.%empty_tuple] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc13_38.6: ref %empty_tuple.type = array_index file.%c.var, %int_2 -// CHECK:STDOUT: %.loc13_28.2: init %empty_tuple.type = tuple_init () to %.loc13_38.6 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.7: init %empty_tuple.type = converted %.loc13_28.1, %.loc13_28.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.6: ref %empty_tuple.type = array_index file.%c.var, %int_2 +// CHECK:STDOUT: %.loc13_33.2: init %empty_tuple.type = tuple_init () to %.loc13_43.6 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.7: init %empty_tuple.type = converted %.loc13_33.1, %.loc13_33.2 [concrete = constants.%empty_tuple] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc13_38.8: ref %empty_tuple.type = array_index file.%c.var, %int_3 -// CHECK:STDOUT: %.loc13_32.2: init %empty_tuple.type = tuple_init () to %.loc13_38.8 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.9: init %empty_tuple.type = converted %.loc13_32.1, %.loc13_32.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.8: ref %empty_tuple.type = array_index file.%c.var, %int_3 +// CHECK:STDOUT: %.loc13_37.2: init %empty_tuple.type = tuple_init () to %.loc13_43.8 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.9: init %empty_tuple.type = converted %.loc13_37.1, %.loc13_37.2 [concrete = constants.%empty_tuple] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] -// CHECK:STDOUT: %.loc13_38.10: ref %empty_tuple.type = array_index file.%c.var, %int_4 -// CHECK:STDOUT: %.loc13_36.2: init %empty_tuple.type = tuple_init () to %.loc13_38.10 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.11: init %empty_tuple.type = converted %.loc13_36.1, %.loc13_36.2 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc13_38.12: init %array_type.c13 = array_init (%.loc13_38.3, %.loc13_38.5, %.loc13_38.7, %.loc13_38.9, %.loc13_38.11) to file.%c.var [concrete = constants.%array.1cb] -// CHECK:STDOUT: %.loc13_1: init %array_type.c13 = converted %.loc13_38.1, %.loc13_38.12 [concrete = constants.%array.1cb] +// CHECK:STDOUT: %.loc13_43.10: ref %empty_tuple.type = array_index file.%c.var, %int_4 +// CHECK:STDOUT: %.loc13_41.2: init %empty_tuple.type = tuple_init () to %.loc13_43.10 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.11: init %empty_tuple.type = converted %.loc13_41.1, %.loc13_41.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_43.12: init %array_type.c13 = array_init (%.loc13_43.3, %.loc13_43.5, %.loc13_43.7, %.loc13_43.9, %.loc13_43.11) to file.%c.var [concrete = constants.%array.1cb] +// CHECK:STDOUT: %.loc13_1: init %array_type.c13 = converted %.loc13_43.1, %.loc13_43.12 [concrete = constants.%array.1cb] // CHECK:STDOUT: assign file.%c.var, %.loc13_1 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/array/canonicalize_index.carbon b/toolchain/check/testdata/array/canonicalize_index.carbon index d72537c39c0d4..38a9fb7cc2f3e 100644 --- a/toolchain/check/testdata/array/canonicalize_index.carbon +++ b/toolchain/check/testdata/array/canonicalize_index.carbon @@ -11,9 +11,9 @@ fn Add(a: i32, b: i32) -> i32 = "int.sadd"; fn ConvertToU32(a: i32) -> u32 = "int.convert_checked"; -var a: [i32; Add(1, 2)] = (1, 2, 3); -let b: [i32; 3]* = &a; -let c: [i32; ConvertToU32(3)]* = &a; +var a: array(i32, Add(1, 2)) = (1, 2, 3); +let b: array(i32, 3)* = &a; +let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: --- canonicalize_index.carbon // CHECK:STDOUT: @@ -135,34 +135,34 @@ let c: [i32; ConvertToU32(3)]* = &a; // CHECK:STDOUT: %.loc14_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc14_23: type = splice_block %array_type.loc14 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc14_28: type = splice_block %array_type.loc14 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Add.ref: %Add.type.b1f = name_ref Add, %Add.decl [concrete = constants.%Add] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %impl.elem0.loc14_18: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_18: = bound_method %int_1, %impl.elem0.loc14_18 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc14_18: = specific_function %bound_method.loc14_18, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc14_18: init %i32 = call %specific_fn.loc14_18(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_18.1: %i32 = value_of_initializer %int.convert_checked.loc14_18 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_18.2: %i32 = converted %int_1, %.loc14_18.1 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc14_21: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_21: = bound_method %int_2, %impl.elem0.loc14_21 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc14_21: = specific_function %bound_method.loc14_21, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc14_21: init %i32 = call %specific_fn.loc14_21(%int_2) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc14_21.1: %i32 = value_of_initializer %int.convert_checked.loc14_21 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc14_21.2: %i32 = converted %int_2, %.loc14_21.1 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int.sadd: init %i32 = call %Add.ref(%.loc14_18.2, %.loc14_21.2) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %impl.elem0.loc14_22: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] -// CHECK:STDOUT: %bound_method.loc14_22: = bound_method %int.sadd, %impl.elem0.loc14_22 [concrete = constants.%Convert.bound.2d6] -// CHECK:STDOUT: %specific_fn.loc14_22: = specific_function %bound_method.loc14_22, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] -// CHECK:STDOUT: %.loc14_22.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc14_22.2: %i32 = converted %int.sadd, %.loc14_22.1 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int.convert_checked.loc14_22: init Core.IntLiteral = call %specific_fn.loc14_22(%.loc14_22.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc14_22.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14_22 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc14_22.4: Core.IntLiteral = converted %int.sadd, %.loc14_22.3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type.loc14: type = array_type %.loc14_22.4, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %impl.elem0.loc14_23: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_23: = bound_method %int_1, %impl.elem0.loc14_23 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc14_23: = specific_function %bound_method.loc14_23, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc14_23: init %i32 = call %specific_fn.loc14_23(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc14_23.1: %i32 = value_of_initializer %int.convert_checked.loc14_23 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc14_23.2: %i32 = converted %int_1, %.loc14_23.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc14_26: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_26: = bound_method %int_2, %impl.elem0.loc14_26 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc14_26: = specific_function %bound_method.loc14_26, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc14_26: init %i32 = call %specific_fn.loc14_26(%int_2) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc14_26.1: %i32 = value_of_initializer %int.convert_checked.loc14_26 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc14_26.2: %i32 = converted %int_2, %.loc14_26.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int.sadd: init %i32 = call %Add.ref(%.loc14_23.2, %.loc14_26.2) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %impl.elem0.loc14_27: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] +// CHECK:STDOUT: %bound_method.loc14_27: = bound_method %int.sadd, %impl.elem0.loc14_27 [concrete = constants.%Convert.bound.2d6] +// CHECK:STDOUT: %specific_fn.loc14_27: = specific_function %bound_method.loc14_27, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] +// CHECK:STDOUT: %.loc14_27.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc14_27.2: %i32 = converted %int.sadd, %.loc14_27.1 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int.convert_checked.loc14_27: init Core.IntLiteral = call %specific_fn.loc14_27(%.loc14_27.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc14_27.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc14_27 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc14_27.4: Core.IntLiteral = converted %int.sadd, %.loc14_27.3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type.loc14: type = array_type %.loc14_27.4, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %array_type = bind_name a, %a.var // CHECK:STDOUT: name_binding_decl { @@ -179,27 +179,27 @@ let c: [i32; ConvertToU32(3)]* = &a; // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %c.patt: %ptr = binding_pattern c // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc16_30: type = splice_block %ptr.loc16 [concrete = constants.%ptr] { +// CHECK:STDOUT: %.loc16_35: type = splice_block %ptr.loc16 [concrete = constants.%ptr] { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %ConvertToU32.ref: %ConvertToU32.type = name_ref ConvertToU32, %ConvertToU32.decl [concrete = constants.%ConvertToU32] // CHECK:STDOUT: %int_3.loc16: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %impl.elem0.loc16_27: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc16_27: = bound_method %int_3.loc16, %impl.elem0.loc16_27 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc16_27: = specific_function %bound_method.loc16_27, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc16_27: init %i32 = call %specific_fn.loc16_27(%int_3.loc16) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc16_27.1: %i32 = value_of_initializer %int.convert_checked.loc16_27 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc16_27.2: %i32 = converted %int_3.loc16, %.loc16_27.1 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int.convert_checked.loc16_28.1: init %u32 = call %ConvertToU32.ref(%.loc16_27.2) [concrete = constants.%int_3.d14] -// CHECK:STDOUT: %impl.elem0.loc16_28: %.88a = impl_witness_access constants.%impl_witness.8da2, element0 [concrete = constants.%Convert.47f] -// CHECK:STDOUT: %bound_method.loc16_28: = bound_method %int.convert_checked.loc16_28.1, %impl.elem0.loc16_28 [concrete = constants.%Convert.bound.258] -// CHECK:STDOUT: %specific_fn.loc16_28: = specific_function %bound_method.loc16_28, @Convert.9(constants.%int_32) [concrete = constants.%Convert.specific_fn.d14] -// CHECK:STDOUT: %.loc16_28.1: %u32 = value_of_initializer %int.convert_checked.loc16_28.1 [concrete = constants.%int_3.d14] -// CHECK:STDOUT: %.loc16_28.2: %u32 = converted %int.convert_checked.loc16_28.1, %.loc16_28.1 [concrete = constants.%int_3.d14] -// CHECK:STDOUT: %int.convert_checked.loc16_28.2: init Core.IntLiteral = call %specific_fn.loc16_28(%.loc16_28.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc16_28.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_28.2 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc16_28.4: Core.IntLiteral = converted %int.convert_checked.loc16_28.1, %.loc16_28.3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type.loc16: type = array_type %.loc16_28.4, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %impl.elem0.loc16_32: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc16_32: = bound_method %int_3.loc16, %impl.elem0.loc16_32 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc16_32: = specific_function %bound_method.loc16_32, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc16_32: init %i32 = call %specific_fn.loc16_32(%int_3.loc16) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc16_32.1: %i32 = value_of_initializer %int.convert_checked.loc16_32 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc16_32.2: %i32 = converted %int_3.loc16, %.loc16_32.1 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int.convert_checked.loc16_33.1: init %u32 = call %ConvertToU32.ref(%.loc16_32.2) [concrete = constants.%int_3.d14] +// CHECK:STDOUT: %impl.elem0.loc16_33: %.88a = impl_witness_access constants.%impl_witness.8da2, element0 [concrete = constants.%Convert.47f] +// CHECK:STDOUT: %bound_method.loc16_33: = bound_method %int.convert_checked.loc16_33.1, %impl.elem0.loc16_33 [concrete = constants.%Convert.bound.258] +// CHECK:STDOUT: %specific_fn.loc16_33: = specific_function %bound_method.loc16_33, @Convert.9(constants.%int_32) [concrete = constants.%Convert.specific_fn.d14] +// CHECK:STDOUT: %.loc16_33.1: %u32 = value_of_initializer %int.convert_checked.loc16_33.1 [concrete = constants.%int_3.d14] +// CHECK:STDOUT: %.loc16_33.2: %u32 = converted %int.convert_checked.loc16_33.1, %.loc16_33.1 [concrete = constants.%int_3.d14] +// CHECK:STDOUT: %int.convert_checked.loc16_33.2: init Core.IntLiteral = call %specific_fn.loc16_33(%.loc16_33.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc16_33.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_33.2 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc16_33.4: Core.IntLiteral = converted %int.convert_checked.loc16_33.1, %.loc16_33.3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type.loc16: type = array_type %.loc16_33.4, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: %ptr.loc16: type = ptr_type %array_type [concrete = constants.%ptr] // CHECK:STDOUT: } // CHECK:STDOUT: %c: %ptr = bind_name c, @__global_init.%addr.loc16 @@ -211,36 +211,36 @@ let c: [i32; ConvertToU32(3)]* = &a; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_1.loc14_28: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc14_31: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_1.loc14_33: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc14_36: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc14_35.1: %tuple.type = tuple_literal (%int_1.loc14_28, %int_2.loc14_31, %int_3) -// CHECK:STDOUT: %impl.elem0.loc14_35.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_35.1: = bound_method %int_1.loc14_28, %impl.elem0.loc14_35.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc14_35.1: = specific_function %bound_method.loc14_35.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc14_35.1: init %i32 = call %specific_fn.loc14_35.1(%int_1.loc14_28) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_35.2: init %i32 = converted %int_1.loc14_28, %int.convert_checked.loc14_35.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc14_40.1: %tuple.type = tuple_literal (%int_1.loc14_33, %int_2.loc14_36, %int_3) +// CHECK:STDOUT: %impl.elem0.loc14_40.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_40.1: = bound_method %int_1.loc14_33, %impl.elem0.loc14_40.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc14_40.1: = specific_function %bound_method.loc14_40.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc14_40.1: init %i32 = call %specific_fn.loc14_40.1(%int_1.loc14_33) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc14_40.2: init %i32 = converted %int_1.loc14_33, %int.convert_checked.loc14_40.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc14_35.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc14_35.4: init %i32 = initialize_from %.loc14_35.2 to %.loc14_35.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc14_35.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_35.2: = bound_method %int_2.loc14_31, %impl.elem0.loc14_35.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc14_35.2: = specific_function %bound_method.loc14_35.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc14_35.2: init %i32 = call %specific_fn.loc14_35.2(%int_2.loc14_31) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc14_35.5: init %i32 = converted %int_2.loc14_31, %int.convert_checked.loc14_35.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc14_35: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc14_35.6: ref %i32 = array_index file.%a.var, %int_1.loc14_35 -// CHECK:STDOUT: %.loc14_35.7: init %i32 = initialize_from %.loc14_35.5 to %.loc14_35.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc14_35.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_35.3: = bound_method %int_3, %impl.elem0.loc14_35.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc14_35.3: = specific_function %bound_method.loc14_35.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc14_35.3: init %i32 = call %specific_fn.loc14_35.3(%int_3) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc14_35.8: init %i32 = converted %int_3, %int.convert_checked.loc14_35.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc14_35: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc14_35.9: ref %i32 = array_index file.%a.var, %int_2.loc14_35 -// CHECK:STDOUT: %.loc14_35.10: init %i32 = initialize_from %.loc14_35.8 to %.loc14_35.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc14_35.11: init %array_type = array_init (%.loc14_35.4, %.loc14_35.7, %.loc14_35.10) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc14_1: init %array_type = converted %.loc14_35.1, %.loc14_35.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc14_40.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc14_40.4: init %i32 = initialize_from %.loc14_40.2 to %.loc14_40.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc14_40.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_40.2: = bound_method %int_2.loc14_36, %impl.elem0.loc14_40.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc14_40.2: = specific_function %bound_method.loc14_40.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc14_40.2: init %i32 = call %specific_fn.loc14_40.2(%int_2.loc14_36) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc14_40.5: init %i32 = converted %int_2.loc14_36, %int.convert_checked.loc14_40.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc14_40: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc14_40.6: ref %i32 = array_index file.%a.var, %int_1.loc14_40 +// CHECK:STDOUT: %.loc14_40.7: init %i32 = initialize_from %.loc14_40.5 to %.loc14_40.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc14_40.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_40.3: = bound_method %int_3, %impl.elem0.loc14_40.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc14_40.3: = specific_function %bound_method.loc14_40.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc14_40.3: init %i32 = call %specific_fn.loc14_40.3(%int_3) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc14_40.8: init %i32 = converted %int_3, %int.convert_checked.loc14_40.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc14_40: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc14_40.9: ref %i32 = array_index file.%a.var, %int_2.loc14_40 +// CHECK:STDOUT: %.loc14_40.10: init %i32 = initialize_from %.loc14_40.8 to %.loc14_40.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc14_40.11: init %array_type = array_init (%.loc14_40.4, %.loc14_40.7, %.loc14_40.10) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc14_1: init %array_type = converted %.loc14_40.1, %.loc14_40.11 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc14_1 // CHECK:STDOUT: %a.ref.loc15: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %addr.loc15: %ptr = addr_of %a.ref.loc15 diff --git a/toolchain/check/testdata/array/fail_bound_negative.carbon b/toolchain/check/testdata/array/fail_bound_negative.carbon index e42cd5acfb5e5..456d8df51da85 100644 --- a/toolchain/check/testdata/array/fail_bound_negative.carbon +++ b/toolchain/check/testdata/array/fail_bound_negative.carbon @@ -10,11 +10,11 @@ fn Negate(n: i32) -> i32 = "int.snegate"; -// CHECK:STDERR: fail_bound_negative.carbon:[[@LINE+4]]:14: error: array bound of -1 is negative [ArrayBoundNegative] -// CHECK:STDERR: var a: [i32; Negate(1)]; -// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_bound_negative.carbon:[[@LINE+4]]:19: error: array bound of -1 is negative [ArrayBoundNegative] +// CHECK:STDERR: var a: array(i32, Negate(1)); +// CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: -var a: [i32; Negate(1)]; +var a: array(i32, Negate(1)); // CHECK:STDOUT: --- fail_bound_negative.carbon // CHECK:STDOUT: @@ -85,27 +85,27 @@ var a: [i32; Negate(1)]; // CHECK:STDOUT: %.loc17_1: = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref = var a -// CHECK:STDOUT: %.loc17_23: type = splice_block %array_type [concrete = ] { +// CHECK:STDOUT: %.loc17_28: type = splice_block %array_type [concrete = ] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Negate.ref: %Negate.type.15b = name_ref Negate, %Negate.decl [concrete = constants.%Negate] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %impl.elem0.loc17_21: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_21: = bound_method %int_1, %impl.elem0.loc17_21 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc17_21: = specific_function %bound_method.loc17_21, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc17_21: init %i32 = call %specific_fn.loc17_21(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc17_21.1: %i32 = value_of_initializer %int.convert_checked.loc17_21 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc17_21.2: %i32 = converted %int_1, %.loc17_21.1 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %int.snegate: init %i32 = call %Negate.ref(%.loc17_21.2) [concrete = constants.%int_-1.251] -// CHECK:STDOUT: %impl.elem0.loc17_22: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] -// CHECK:STDOUT: %bound_method.loc17_22: = bound_method %int.snegate, %impl.elem0.loc17_22 [concrete = constants.%Convert.bound.75d] -// CHECK:STDOUT: %specific_fn.loc17_22: = specific_function %bound_method.loc17_22, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.4af] -// CHECK:STDOUT: %.loc17_22.1: %i32 = value_of_initializer %int.snegate [concrete = constants.%int_-1.251] -// CHECK:STDOUT: %.loc17_22.2: %i32 = converted %int.snegate, %.loc17_22.1 [concrete = constants.%int_-1.251] -// CHECK:STDOUT: %int.convert_checked.loc17_22: init Core.IntLiteral = call %specific_fn.loc17_22(%.loc17_22.2) [concrete = constants.%int_-1.638] -// CHECK:STDOUT: %.loc17_22.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc17_22 [concrete = constants.%int_-1.638] -// CHECK:STDOUT: %.loc17_22.4: Core.IntLiteral = converted %int.snegate, %.loc17_22.3 [concrete = constants.%int_-1.638] -// CHECK:STDOUT: %array_type: type = array_type %.loc17_22.4, %i32 [concrete = ] +// CHECK:STDOUT: %impl.elem0.loc17_26: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_26: = bound_method %int_1, %impl.elem0.loc17_26 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc17_26: = specific_function %bound_method.loc17_26, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc17_26: init %i32 = call %specific_fn.loc17_26(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc17_26.1: %i32 = value_of_initializer %int.convert_checked.loc17_26 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc17_26.2: %i32 = converted %int_1, %.loc17_26.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int.snegate: init %i32 = call %Negate.ref(%.loc17_26.2) [concrete = constants.%int_-1.251] +// CHECK:STDOUT: %impl.elem0.loc17_27: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] +// CHECK:STDOUT: %bound_method.loc17_27: = bound_method %int.snegate, %impl.elem0.loc17_27 [concrete = constants.%Convert.bound.75d] +// CHECK:STDOUT: %specific_fn.loc17_27: = specific_function %bound_method.loc17_27, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.4af] +// CHECK:STDOUT: %.loc17_27.1: %i32 = value_of_initializer %int.snegate [concrete = constants.%int_-1.251] +// CHECK:STDOUT: %.loc17_27.2: %i32 = converted %int.snegate, %.loc17_27.1 [concrete = constants.%int_-1.251] +// CHECK:STDOUT: %int.convert_checked.loc17_27: init Core.IntLiteral = call %specific_fn.loc17_27(%.loc17_27.2) [concrete = constants.%int_-1.638] +// CHECK:STDOUT: %.loc17_27.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc17_27 [concrete = constants.%int_-1.638] +// CHECK:STDOUT: %.loc17_27.4: Core.IntLiteral = converted %int.snegate, %.loc17_27.3 [concrete = constants.%int_-1.638] +// CHECK:STDOUT: %array_type: type = array_type %.loc17_27.4, %i32 [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/array/fail_bound_overflow.carbon b/toolchain/check/testdata/array/fail_bound_overflow.carbon index b4b6334f13069..d13f939b2798c 100644 --- a/toolchain/check/testdata/array/fail_bound_overflow.carbon +++ b/toolchain/check/testdata/array/fail_bound_overflow.carbon @@ -8,20 +8,20 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_bound_overflow.carbon -// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:14: error: array bound of 39999999999999999993 is too large [ArrayBoundTooLarge] -// CHECK:STDERR: var a: [i32; 39999999999999999993]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:19: error: array bound of 39999999999999999993 is too large [ArrayBoundTooLarge] +// CHECK:STDERR: var a: array(i32, 39999999999999999993); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var a: [i32; 39999999999999999993]; +var a: array(i32, 39999999999999999993); -// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+7]]:9: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure] -// CHECK:STDERR: var b: [1; 39999999999999999993]; -// CHECK:STDERR: ^ -// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:9: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote] -// CHECK:STDERR: var b: [1; 39999999999999999993]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+7]]:14: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure] +// CHECK:STDERR: var b: array(1, 39999999999999999993); +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:14: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote] +// CHECK:STDERR: var b: array(1, 39999999999999999993); +// CHECK:STDERR: ^ // CHECK:STDERR: -var b: [1; 39999999999999999993]; +var b: array(1, 39999999999999999993); // CHECK:STDOUT: --- fail_bound_overflow.carbon // CHECK:STDOUT: @@ -53,7 +53,7 @@ var b: [1; 39999999999999999993]; // CHECK:STDOUT: %.loc15_1: = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref = var a -// CHECK:STDOUT: %.loc15_34: type = splice_block %array_type.loc15 [concrete = ] { +// CHECK:STDOUT: %.loc15_39: type = splice_block %array_type.loc15 [concrete = ] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_39999999999999999993.loc15: Core.IntLiteral = int_value 39999999999999999993 [concrete = constants.%int_39999999999999999993] @@ -65,10 +65,10 @@ var b: [1; 39999999999999999993]; // CHECK:STDOUT: %.loc24_1: = var_pattern %b.patt // CHECK:STDOUT: } // CHECK:STDOUT: %b.var: ref = var b -// CHECK:STDOUT: %.loc24_32: type = splice_block %array_type.loc24 [concrete = ] { +// CHECK:STDOUT: %.loc24_37: type = splice_block %array_type.loc24 [concrete = ] { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %int_39999999999999999993.loc24: Core.IntLiteral = int_value 39999999999999999993 [concrete = constants.%int_39999999999999999993] -// CHECK:STDOUT: %.loc24_9: type = converted %int_1, [concrete = ] +// CHECK:STDOUT: %.loc24_14: type = converted %int_1, [concrete = ] // CHECK:STDOUT: %array_type.loc24: type = array_type %int_39999999999999999993.loc24, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %b: = bind_name b, diff --git a/toolchain/check/testdata/array/fail_incomplete_element.carbon b/toolchain/check/testdata/array/fail_incomplete_element.carbon index 41fb1d685b7b5..012834259a82f 100644 --- a/toolchain/check/testdata/array/fail_incomplete_element.carbon +++ b/toolchain/check/testdata/array/fail_incomplete_element.carbon @@ -11,13 +11,13 @@ class Incomplete; // CHECK:STDERR: fail_incomplete_element.carbon:[[@LINE+7]]:8: error: binding pattern has incomplete type `[Incomplete; 1]` in name binding declaration [IncompleteTypeInBindingDecl] -// CHECK:STDERR: var a: [Incomplete; 1]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: var a: array(Incomplete, 1); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_incomplete_element.carbon:[[@LINE-5]]:1: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: class Incomplete; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var a: [Incomplete; 1]; +var a: array(Incomplete, 1); var p: Incomplete* = &a[0]; @@ -52,7 +52,7 @@ var p: Incomplete* = &a[0]; // CHECK:STDOUT: %.loc20_1: = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref = var a -// CHECK:STDOUT: %.loc20_22: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc20_27: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %Incomplete.ref.loc20: type = name_ref Incomplete, %Incomplete.decl [concrete = constants.%Incomplete] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %array_type: type = array_type %int_1, %Incomplete [concrete = constants.%array_type] diff --git a/toolchain/check/testdata/array/fail_invalid_type.carbon b/toolchain/check/testdata/array/fail_invalid_type.carbon index fbdd43780b9e6..e5872a18ef46d 100644 --- a/toolchain/check/testdata/array/fail_invalid_type.carbon +++ b/toolchain/check/testdata/array/fail_invalid_type.carbon @@ -8,14 +8,14 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_invalid_type.carbon -// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+7]]:9: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure] -// CHECK:STDERR: var a: [1; 1]; -// CHECK:STDERR: ^ -// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+4]]:9: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote] -// CHECK:STDERR: var a: [1; 1]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+7]]:14: error: cannot implicitly convert from `Core.IntLiteral` to `type` [ImplicitAsConversionFailure] +// CHECK:STDERR: var a: array(1, 1); +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_type.carbon:[[@LINE+4]]:14: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote] +// CHECK:STDERR: var a: array(1, 1); +// CHECK:STDERR: ^ // CHECK:STDERR: -var a: [1; 1]; +var a: array(1, 1); // CHECK:STDOUT: --- fail_invalid_type.carbon // CHECK:STDOUT: @@ -42,11 +42,11 @@ var a: [1; 1]; // CHECK:STDOUT: %.loc18_1: = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref = var a -// CHECK:STDOUT: %.loc18_13: type = splice_block %array_type [concrete = ] { -// CHECK:STDOUT: %int_1.loc18_9: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %int_1.loc18_12: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc18_9: type = converted %int_1.loc18_9, [concrete = ] -// CHECK:STDOUT: %array_type: type = array_type %int_1.loc18_12, [concrete = ] +// CHECK:STDOUT: %.loc18_18: type = splice_block %array_type [concrete = ] { +// CHECK:STDOUT: %int_1.loc18_14: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_1.loc18_17: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %.loc18_14: type = converted %int_1.loc18_14, [concrete = ] +// CHECK:STDOUT: %array_type: type = array_type %int_1.loc18_17, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/array/fail_out_of_bound.carbon b/toolchain/check/testdata/array/fail_out_of_bound.carbon index 6f066f77a10d3..ddb277e90b875 100644 --- a/toolchain/check/testdata/array/fail_out_of_bound.carbon +++ b/toolchain/check/testdata/array/fail_out_of_bound.carbon @@ -8,11 +8,11 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_out_of_bound.carbon -// CHECK:STDERR: fail_out_of_bound.carbon:[[@LINE+4]]:19: error: cannot initialize array of 1 element from 3 initializers [ArrayInitFromLiteralArgCountMismatch] -// CHECK:STDERR: var a: [i32; 1] = (1, 2, 3); -// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_out_of_bound.carbon:[[@LINE+4]]:24: error: cannot initialize array of 1 element from 3 initializers [ArrayInitFromLiteralArgCountMismatch] +// CHECK:STDERR: var a: array(i32, 1) = (1, 2, 3); +// CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: -var a: [i32; 1] = (1, 2, 3); +var a: array(i32, 1) = (1, 2, 3); // CHECK:STDOUT: --- fail_out_of_bound.carbon // CHECK:STDOUT: @@ -45,7 +45,7 @@ var a: [i32; 1] = (1, 2, 3); // CHECK:STDOUT: %.loc15_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc15_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc15_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] diff --git a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon index 99ed6f44a22a5..43954fdef4a4c 100644 --- a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon +++ b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon -var a: [i32; 3] = (1, 2, 3); +var a: array(i32, 3) = (1, 2, 3); // CHECK:STDERR: fail_out_of_bound_non_literal.carbon:[[@LINE+4]]:16: error: array index `3` is past the end of type `[i32; 3]` [ArrayIndexOutOfBounds] // CHECK:STDERR: var b: i32 = a[{.index = 3}.index]; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ @@ -68,7 +68,7 @@ var b: i32 = a[{.index = 3}.index]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] @@ -89,36 +89,36 @@ var b: i32 = a[{.index = 3}.index]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_1.loc11_20: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc11_23: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_1.loc11_25: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc11_28: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %int_3.loc11: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc11_27.1: %tuple.type = tuple_literal (%int_1.loc11_20, %int_2.loc11_23, %int_3.loc11) -// CHECK:STDOUT: %impl.elem0.loc11_27.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.1: = bound_method %int_1.loc11_20, %impl.elem0.loc11_27.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc11_27.1: = specific_function %bound_method.loc11_27.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc11_27.1: init %i32 = call %specific_fn.loc11_27.1(%int_1.loc11_20) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc11_27.2: init %i32 = converted %int_1.loc11_20, %int.convert_checked.loc11_27.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_32.1: %tuple.type = tuple_literal (%int_1.loc11_25, %int_2.loc11_28, %int_3.loc11) +// CHECK:STDOUT: %impl.elem0.loc11_32.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.1: = bound_method %int_1.loc11_25, %impl.elem0.loc11_32.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc11_32.1: = specific_function %bound_method.loc11_32.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc11_32.1: init %i32 = call %specific_fn.loc11_32.1(%int_1.loc11_25) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_32.2: init %i32 = converted %int_1.loc11_25, %int.convert_checked.loc11_32.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_27.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_27.4: init %i32 = initialize_from %.loc11_27.2 to %.loc11_27.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc11_27.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.2: = bound_method %int_2.loc11_23, %impl.elem0.loc11_27.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc11_27.2: = specific_function %bound_method.loc11_27.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc11_27.2: init %i32 = call %specific_fn.loc11_27.2(%int_2.loc11_23) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc11_27.5: init %i32 = converted %int_2.loc11_23, %int.convert_checked.loc11_27.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc11_27: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc11_27.6: ref %i32 = array_index file.%a.var, %int_1.loc11_27 -// CHECK:STDOUT: %.loc11_27.7: init %i32 = initialize_from %.loc11_27.5 to %.loc11_27.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc11_27.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.3: = bound_method %int_3.loc11, %impl.elem0.loc11_27.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc11_27.3: = specific_function %bound_method.loc11_27.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc11_27.3: init %i32 = call %specific_fn.loc11_27.3(%int_3.loc11) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc11_27.8: init %i32 = converted %int_3.loc11, %int.convert_checked.loc11_27.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc11_27: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc11_27.9: ref %i32 = array_index file.%a.var, %int_2.loc11_27 -// CHECK:STDOUT: %.loc11_27.10: init %i32 = initialize_from %.loc11_27.8 to %.loc11_27.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc11_27.11: init %array_type = array_init (%.loc11_27.4, %.loc11_27.7, %.loc11_27.10) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_27.1, %.loc11_27.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_32.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_32.4: init %i32 = initialize_from %.loc11_32.2 to %.loc11_32.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc11_32.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.2: = bound_method %int_2.loc11_28, %impl.elem0.loc11_32.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc11_32.2: = specific_function %bound_method.loc11_32.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc11_32.2: init %i32 = call %specific_fn.loc11_32.2(%int_2.loc11_28) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc11_32.5: init %i32 = converted %int_2.loc11_28, %int.convert_checked.loc11_32.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc11_32: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc11_32.6: ref %i32 = array_index file.%a.var, %int_1.loc11_32 +// CHECK:STDOUT: %.loc11_32.7: init %i32 = initialize_from %.loc11_32.5 to %.loc11_32.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc11_32.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.3: = bound_method %int_3.loc11, %impl.elem0.loc11_32.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc11_32.3: = specific_function %bound_method.loc11_32.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc11_32.3: init %i32 = call %specific_fn.loc11_32.3(%int_3.loc11) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc11_32.8: init %i32 = converted %int_3.loc11, %int.convert_checked.loc11_32.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc11_32: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc11_32.9: ref %i32 = array_index file.%a.var, %int_2.loc11_32 +// CHECK:STDOUT: %.loc11_32.10: init %i32 = initialize_from %.loc11_32.8 to %.loc11_32.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc11_32.11: init %array_type = array_init (%.loc11_32.4, %.loc11_32.7, %.loc11_32.10) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_32.1, %.loc11_32.11 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %int_3.loc16: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] diff --git a/toolchain/check/testdata/array/fail_type_mismatch.carbon b/toolchain/check/testdata/array/fail_type_mismatch.carbon index 9d59bc3b1443b..a556a25cdc4f2 100644 --- a/toolchain/check/testdata/array/fail_type_mismatch.carbon +++ b/toolchain/check/testdata/array/fail_type_mismatch.carbon @@ -8,37 +8,37 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_type_mismatch.carbon -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:19: error: cannot implicitly convert from `String` to `i32` [ImplicitAsConversionFailure] -// CHECK:STDERR: var a: [i32; 3] = (1, "Hello", "World"); -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:19: note: type `String` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote] -// CHECK:STDERR: var a: [i32; 3] = (1, "Hello", "World"); -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:24: error: cannot implicitly convert from `String` to `i32` [ImplicitAsConversionFailure] +// CHECK:STDERR: var a: array(i32, 3) = (1, "Hello", "World"); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:24: note: type `String` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote] +// CHECK:STDERR: var a: array(i32, 3) = (1, "Hello", "World"); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var a: [i32; 3] = (1, "Hello", "World"); +var a: array(i32, 3) = (1, "Hello", "World"); var t1: (i32, String, String); -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:19: error: cannot implicitly convert from `String` to `i32` [ImplicitAsConversionFailure] -// CHECK:STDERR: var b: [i32; 3] = t1; -// CHECK:STDERR: ^~ -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:19: note: type `String` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote] -// CHECK:STDERR: var b: [i32; 3] = t1; -// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:24: error: cannot implicitly convert from `String` to `i32` [ImplicitAsConversionFailure] +// CHECK:STDERR: var b: array(i32, 3) = t1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:24: note: type `String` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote] +// CHECK:STDERR: var b: array(i32, 3) = t1; +// CHECK:STDERR: ^~ // CHECK:STDERR: -var b: [i32; 3] = t1; +var b: array(i32, 3) = t1; -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:19: error: cannot initialize array of 3 elements from 2 initializers [ArrayInitFromLiteralArgCountMismatch] -// CHECK:STDERR: var c: [i32; 3] = (1, 2); -// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:24: error: cannot initialize array of 3 elements from 2 initializers [ArrayInitFromLiteralArgCountMismatch] +// CHECK:STDERR: var c: array(i32, 3) = (1, 2); +// CHECK:STDERR: ^~~~~~ // CHECK:STDERR: -var c: [i32; 3] = (1, 2); +var c: array(i32, 3) = (1, 2); var t2: (i32, i32); -// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:19: error: cannot initialize array of 3 elements from tuple with 2 elements [ArrayInitFromExprArgCountMismatch] -// CHECK:STDERR: var d: [i32; 3] = t2; -// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:24: error: cannot initialize array of 3 elements from tuple with 2 elements [ArrayInitFromExprArgCountMismatch] +// CHECK:STDERR: var d: array(i32, 3) = t2; +// CHECK:STDERR: ^~ // CHECK:STDERR: -var d: [i32; 3] = t2; +var d: array(i32, 3) = t2; // CHECK:STDOUT: --- fail_type_mismatch.carbon // CHECK:STDOUT: @@ -95,7 +95,7 @@ var d: [i32; 3] = t2; // CHECK:STDOUT: %.loc18_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc18_15: type = splice_block %array_type.loc18 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc18_20: type = splice_block %array_type.loc18 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc18: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] @@ -119,7 +119,7 @@ var d: [i32; 3] = t2; // CHECK:STDOUT: %.loc28_1: %array_type = var_pattern %b.patt // CHECK:STDOUT: } // CHECK:STDOUT: %b.var: ref %array_type = var b -// CHECK:STDOUT: %.loc28_15: type = splice_block %array_type.loc28 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc28_20: type = splice_block %array_type.loc28 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc28: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc28: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc28: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] @@ -131,7 +131,7 @@ var d: [i32; 3] = t2; // CHECK:STDOUT: %.loc34_1: %array_type = var_pattern %c.patt // CHECK:STDOUT: } // CHECK:STDOUT: %c.var: ref %array_type = var c -// CHECK:STDOUT: %.loc34_15: type = splice_block %array_type.loc34 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc34_20: type = splice_block %array_type.loc34 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc34: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc34: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc34: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] @@ -157,7 +157,7 @@ var d: [i32; 3] = t2; // CHECK:STDOUT: %.loc41_1: %array_type = var_pattern %d.patt // CHECK:STDOUT: } // CHECK:STDOUT: %d.var: ref %array_type = var d -// CHECK:STDOUT: %.loc41_15: type = splice_block %array_type.loc41 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc41_20: type = splice_block %array_type.loc41 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc41: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc41: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc41: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] @@ -169,27 +169,27 @@ var d: [i32; 3] = t2; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_1.loc18: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %str.loc18_23: String = string_literal "Hello" [concrete = constants.%str.ef1] -// CHECK:STDOUT: %str.loc18_32: String = string_literal "World" [concrete = constants.%str.abb] -// CHECK:STDOUT: %.loc18_39.1: %tuple.type.b0f = tuple_literal (%int_1.loc18, %str.loc18_23, %str.loc18_32) +// CHECK:STDOUT: %str.loc18_28: String = string_literal "Hello" [concrete = constants.%str.ef1] +// CHECK:STDOUT: %str.loc18_37: String = string_literal "World" [concrete = constants.%str.abb] +// CHECK:STDOUT: %.loc18_44.1: %tuple.type.b0f = tuple_literal (%int_1.loc18, %str.loc18_28, %str.loc18_37) // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] // CHECK:STDOUT: %bound_method: = bound_method %int_1.loc18, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_1.loc18) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc18_39.2: init %i32 = converted %int_1.loc18, %int.convert_checked [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc18_44.2: init %i32 = converted %int_1.loc18, %int.convert_checked [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0.loc18: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc18_39.3: ref %i32 = array_index file.%a.var, %int_0.loc18 -// CHECK:STDOUT: %.loc18_39.4: init %i32 = initialize_from %.loc18_39.2 to %.loc18_39.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc18_39.5: %i32 = converted %str.loc18_23, [concrete = ] +// CHECK:STDOUT: %.loc18_44.3: ref %i32 = array_index file.%a.var, %int_0.loc18 +// CHECK:STDOUT: %.loc18_44.4: init %i32 = initialize_from %.loc18_44.2 to %.loc18_44.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc18_44.5: %i32 = converted %str.loc18_28, [concrete = ] // CHECK:STDOUT: assign file.%a.var, // CHECK:STDOUT: %t1.ref: ref %tuple.type.9e7 = name_ref t1, file.%t1 // CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %t1.ref, element0 -// CHECK:STDOUT: %.loc28_19.1: %i32 = bind_value %tuple.elem0 +// CHECK:STDOUT: %.loc28_24.1: %i32 = bind_value %tuple.elem0 // CHECK:STDOUT: %int_0.loc28: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc28_19.2: ref %i32 = array_index file.%b.var, %int_0.loc28 -// CHECK:STDOUT: %.loc28_19.3: init %i32 = initialize_from %.loc28_19.1 to %.loc28_19.2 +// CHECK:STDOUT: %.loc28_24.2: ref %i32 = array_index file.%b.var, %int_0.loc28 +// CHECK:STDOUT: %.loc28_24.3: init %i32 = initialize_from %.loc28_24.1 to %.loc28_24.2 // CHECK:STDOUT: %tuple.elem1: ref String = tuple_access %t1.ref, element1 -// CHECK:STDOUT: %.loc28_19.4: %i32 = converted %tuple.elem1, [concrete = ] +// CHECK:STDOUT: %.loc28_24.4: %i32 = converted %tuple.elem1, [concrete = ] // CHECK:STDOUT: assign file.%b.var, // CHECK:STDOUT: %int_1.loc34: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] diff --git a/toolchain/check/testdata/array/fail_undefined_bound.carbon b/toolchain/check/testdata/array/fail_undefined_bound.carbon deleted file mode 100644 index 83a0e21e61fbd..0000000000000 --- a/toolchain/check/testdata/array/fail_undefined_bound.carbon +++ /dev/null @@ -1,23 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/array/fail_undefined_bound.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_undefined_bound.carbon - -// CHECK:STDERR: fail_undefined_bound.carbon:[[@LINE+4]]:8: error: semantics TODO: `HandleArrayExprWithoutBounds` [SemanticsTodo] -// CHECK:STDERR: var a: [i32; ]; -// CHECK:STDERR: ^~~~~~~ -// CHECK:STDERR: -var a: [i32; ]; - -// CHECK:STDOUT: --- fail_undefined_bound.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/array/function_param.carbon b/toolchain/check/testdata/array/function_param.carbon index 5d7f524fc9a09..caad8bcef9e21 100644 --- a/toolchain/check/testdata/array/function_param.carbon +++ b/toolchain/check/testdata/array/function_param.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/function_param.carbon -fn F(arr: [i32; 3], i: i32) -> i32 { +fn F(arr: array(i32, 3), i: i32) -> i32 { return arr[i]; } @@ -74,20 +74,20 @@ fn G() -> i32 { // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param2 // CHECK:STDOUT: } { -// CHECK:STDOUT: %int_32.loc11_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc11_32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc11_37: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc11_37: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %arr.param: %array_type = value_param runtime_param0 -// CHECK:STDOUT: %.loc11_18: type = splice_block %array_type [concrete = constants.%array_type] { -// CHECK:STDOUT: %int_32.loc11_12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc11_12: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc11_23: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %int_32.loc11_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc11_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %array_type: type = array_type %int_3, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %arr: %array_type = bind_name arr, %arr.param // CHECK:STDOUT: %i.param: %i32 = value_param runtime_param1 -// CHECK:STDOUT: %.loc11_24: type = splice_block %i32.loc11_24 [concrete = constants.%i32] { -// CHECK:STDOUT: %int_32.loc11_24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc11_24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc11_29: type = splice_block %i32.loc11_29 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc11_29: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc11_29: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %i: %i32 = bind_name i, %i.param // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param2 diff --git a/toolchain/check/testdata/array/generic_empty.carbon b/toolchain/check/testdata/array/generic_empty.carbon index 507aeec23b092..d92cd3dd09419 100644 --- a/toolchain/check/testdata/array/generic_empty.carbon +++ b/toolchain/check/testdata/array/generic_empty.carbon @@ -10,7 +10,7 @@ fn G(T:! type) { // We can initialize this without knowing T. - var arr: [T; 0] = (); + var arr: array(T, 0) = (); } // CHECK:STDOUT: --- generic_empty.carbon @@ -54,27 +54,27 @@ fn G(T:! type) { // CHECK:STDOUT: %T.patt.loc11_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %array_type.loc13_17.2: type = array_type constants.%int_0, @G.%T.loc11_6.2 (%T) [symbolic = %array_type.loc13_17.2 (constants.%array_type)] -// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc13_17.2 (%array_type) [symbolic = %require_complete (constants.%require_complete)] -// CHECK:STDOUT: %array: @G.%array_type.loc13_17.2 (%array_type) = tuple_value () [symbolic = %array (constants.%array)] +// CHECK:STDOUT: %array_type.loc13_22.2: type = array_type constants.%int_0, @G.%T.loc11_6.2 (%T) [symbolic = %array_type.loc13_22.2 (constants.%array_type)] +// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc13_22.2 (%array_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %array: @G.%array_type.loc13_22.2 (%array_type) = tuple_value () [symbolic = %array (constants.%array)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%T.param_patt: type) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %arr.patt: @G.%array_type.loc13_17.2 (%array_type) = binding_pattern arr -// CHECK:STDOUT: %.loc13_3.1: @G.%array_type.loc13_17.2 (%array_type) = var_pattern %arr.patt +// CHECK:STDOUT: %arr.patt: @G.%array_type.loc13_22.2 (%array_type) = binding_pattern arr +// CHECK:STDOUT: %.loc13_3.1: @G.%array_type.loc13_22.2 (%array_type) = var_pattern %arr.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc13_17.2 (%array_type) = var arr -// CHECK:STDOUT: %.loc13_22.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_22.2: init @G.%array_type.loc13_17.2 (%array_type) = array_init () to %arr.var [symbolic = %array (constants.%array)] -// CHECK:STDOUT: %.loc13_3.2: init @G.%array_type.loc13_17.2 (%array_type) = converted %.loc13_22.1, %.loc13_22.2 [symbolic = %array (constants.%array)] +// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc13_22.2 (%array_type) = var arr +// CHECK:STDOUT: %.loc13_27.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc13_27.2: init @G.%array_type.loc13_22.2 (%array_type) = array_init () to %arr.var [symbolic = %array (constants.%array)] +// CHECK:STDOUT: %.loc13_3.2: init @G.%array_type.loc13_22.2 (%array_type) = converted %.loc13_27.1, %.loc13_27.2 [symbolic = %array (constants.%array)] // CHECK:STDOUT: assign %arr.var, %.loc13_3.2 -// CHECK:STDOUT: %.loc13_17: type = splice_block %array_type.loc13_17.1 [symbolic = %array_type.loc13_17.2 (constants.%array_type)] { +// CHECK:STDOUT: %.loc13_22: type = splice_block %array_type.loc13_22.1 [symbolic = %array_type.loc13_22.2 (constants.%array_type)] { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %array_type.loc13_17.1: type = array_type %int_0, %T [symbolic = %array_type.loc13_17.2 (constants.%array_type)] +// CHECK:STDOUT: %array_type.loc13_22.1: type = array_type %int_0, %T [symbolic = %array_type.loc13_22.2 (constants.%array_type)] // CHECK:STDOUT: } -// CHECK:STDOUT: %arr: ref @G.%array_type.loc13_17.2 (%array_type) = bind_name arr, %arr.var +// CHECK:STDOUT: %arr: ref @G.%array_type.loc13_22.2 (%array_type) = bind_name arr, %arr.var // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/array/import.carbon b/toolchain/check/testdata/array/import.carbon index 8d46270e22436..8e40983902669 100644 --- a/toolchain/check/testdata/array/import.carbon +++ b/toolchain/check/testdata/array/import.carbon @@ -12,7 +12,7 @@ library "[[@TEST_NAME]]"; -fn F() -> [i32; 42]; +fn F() -> array(i32, 42); // --- user.carbon diff --git a/toolchain/check/testdata/array/index_not_literal.carbon b/toolchain/check/testdata/array/index_not_literal.carbon index d5395f44acdee..0e3c910d4b02d 100644 --- a/toolchain/check/testdata/array/index_not_literal.carbon +++ b/toolchain/check/testdata/array/index_not_literal.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/index_not_literal.carbon -var a: [i32; 3] = (1, 2, 3); +var a: array(i32, 3) = (1, 2, 3); var b: i32 = a[{.index = 2}.index]; // CHECK:STDOUT: --- index_not_literal.carbon @@ -64,7 +64,7 @@ var b: i32 = a[{.index = 2}.index]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] @@ -85,36 +85,36 @@ var b: i32 = a[{.index = 2}.index]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_1.loc11_20: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc11_23: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_1.loc11_25: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc11_28: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc11_27.1: %tuple.type = tuple_literal (%int_1.loc11_20, %int_2.loc11_23, %int_3) -// CHECK:STDOUT: %impl.elem0.loc11_27.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.1: = bound_method %int_1.loc11_20, %impl.elem0.loc11_27.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc11_27.1: = specific_function %bound_method.loc11_27.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc11_27.1: init %i32 = call %specific_fn.loc11_27.1(%int_1.loc11_20) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc11_27.2: init %i32 = converted %int_1.loc11_20, %int.convert_checked.loc11_27.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_32.1: %tuple.type = tuple_literal (%int_1.loc11_25, %int_2.loc11_28, %int_3) +// CHECK:STDOUT: %impl.elem0.loc11_32.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.1: = bound_method %int_1.loc11_25, %impl.elem0.loc11_32.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc11_32.1: = specific_function %bound_method.loc11_32.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc11_32.1: init %i32 = call %specific_fn.loc11_32.1(%int_1.loc11_25) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_32.2: init %i32 = converted %int_1.loc11_25, %int.convert_checked.loc11_32.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_27.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_27.4: init %i32 = initialize_from %.loc11_27.2 to %.loc11_27.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc11_27.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.2: = bound_method %int_2.loc11_23, %impl.elem0.loc11_27.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc11_27.2: = specific_function %bound_method.loc11_27.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc11_27.2: init %i32 = call %specific_fn.loc11_27.2(%int_2.loc11_23) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc11_27.5: init %i32 = converted %int_2.loc11_23, %int.convert_checked.loc11_27.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc11_27: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc11_27.6: ref %i32 = array_index file.%a.var, %int_1.loc11_27 -// CHECK:STDOUT: %.loc11_27.7: init %i32 = initialize_from %.loc11_27.5 to %.loc11_27.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc11_27.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_27.3: = bound_method %int_3, %impl.elem0.loc11_27.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc11_27.3: = specific_function %bound_method.loc11_27.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc11_27.3: init %i32 = call %specific_fn.loc11_27.3(%int_3) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc11_27.8: init %i32 = converted %int_3, %int.convert_checked.loc11_27.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc11_27: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc11_27.9: ref %i32 = array_index file.%a.var, %int_2.loc11_27 -// CHECK:STDOUT: %.loc11_27.10: init %i32 = initialize_from %.loc11_27.8 to %.loc11_27.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc11_27.11: init %array_type = array_init (%.loc11_27.4, %.loc11_27.7, %.loc11_27.10) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_27.1, %.loc11_27.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_32.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_32.4: init %i32 = initialize_from %.loc11_32.2 to %.loc11_32.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc11_32.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.2: = bound_method %int_2.loc11_28, %impl.elem0.loc11_32.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc11_32.2: = specific_function %bound_method.loc11_32.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc11_32.2: init %i32 = call %specific_fn.loc11_32.2(%int_2.loc11_28) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc11_32.5: init %i32 = converted %int_2.loc11_28, %int.convert_checked.loc11_32.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc11_32: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc11_32.6: ref %i32 = array_index file.%a.var, %int_1.loc11_32 +// CHECK:STDOUT: %.loc11_32.7: init %i32 = initialize_from %.loc11_32.5 to %.loc11_32.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc11_32.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_32.3: = bound_method %int_3, %impl.elem0.loc11_32.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc11_32.3: = specific_function %bound_method.loc11_32.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc11_32.3: init %i32 = call %specific_fn.loc11_32.3(%int_3) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc11_32.8: init %i32 = converted %int_3, %int.convert_checked.loc11_32.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc11_32: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc11_32.9: ref %i32 = array_index file.%a.var, %int_2.loc11_32 +// CHECK:STDOUT: %.loc11_32.10: init %i32 = initialize_from %.loc11_32.8 to %.loc11_32.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc11_32.11: init %array_type = array_init (%.loc11_32.4, %.loc11_32.7, %.loc11_32.10) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_32.1, %.loc11_32.11 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %int_2.loc12: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] diff --git a/toolchain/check/testdata/array/init_dependent_bound.carbon b/toolchain/check/testdata/array/init_dependent_bound.carbon index effb6a6937df7..07ca418653f32 100644 --- a/toolchain/check/testdata/array/init_dependent_bound.carbon +++ b/toolchain/check/testdata/array/init_dependent_bound.carbon @@ -13,11 +13,11 @@ library "[[@TEST_NAME]]"; fn F(N:! i32) { - // CHECK:STDERR: fail_init_dependent_bound.carbon:[[@LINE+4]]:23: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] - // CHECK:STDERR: var arr: [i32; N] = (1, 2, 3); - // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fail_init_dependent_bound.carbon:[[@LINE+4]]:28: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] + // CHECK:STDERR: var arr: array(i32, N) = (1, 2, 3); + // CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: - var arr: [i32; N] = (1, 2, 3); + var arr: array(i32, N) = (1, 2, 3); } // --- fail_todo_init_template_dependent_bound.carbon @@ -26,11 +26,11 @@ library "[[@TEST_NAME]]"; // TODO: This should be valid. fn G(template N:! i32) { - // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:23: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] - // CHECK:STDERR: var arr: [i32; N] = (1, 2, 3); - // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:28: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] + // CHECK:STDERR: var arr: array(i32, N) = (1, 2, 3); + // CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: - var arr: [i32; N] = (1, 2, 3); + var arr: array(i32, N) = (1, 2, 3); } fn H() { G(3); } @@ -97,35 +97,35 @@ fn H() { G(3); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc4_6.2, constants.%Convert.960 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc9_18.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc4_6.2) [symbolic = %int.convert_checked.loc9_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc9_19.2: type = array_type %int.convert_checked.loc9_18.2, %i32 [symbolic = %array_type.loc9_19.2 (constants.%array_type)] -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc9_19.2 (%array_type) [symbolic = %require_complete (constants.%require_complete.9dc)] +// CHECK:STDOUT: %int.convert_checked.loc9_23.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc4_6.2) [symbolic = %int.convert_checked.loc9_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc9_24.2: type = array_type %int.convert_checked.loc9_23.2, %i32 [symbolic = %array_type.loc9_24.2 (constants.%array_type)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc9_24.2 (%array_type) [symbolic = %require_complete (constants.%require_complete.9dc)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%N.param_patt: %i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %arr.patt: @F.%array_type.loc9_19.2 (%array_type) = binding_pattern arr -// CHECK:STDOUT: %.loc9_3: @F.%array_type.loc9_19.2 (%array_type) = var_pattern %arr.patt +// CHECK:STDOUT: %arr.patt: @F.%array_type.loc9_24.2 (%array_type) = binding_pattern arr +// CHECK:STDOUT: %.loc9_3: @F.%array_type.loc9_24.2 (%array_type) = var_pattern %arr.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %arr.var: ref @F.%array_type.loc9_19.2 (%array_type) = var arr +// CHECK:STDOUT: %arr.var: ref @F.%array_type.loc9_24.2 (%array_type) = var arr // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc9_31: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) +// CHECK:STDOUT: %.loc9_36: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) // CHECK:STDOUT: assign %arr.var, -// CHECK:STDOUT: %.loc9_19: type = splice_block %array_type.loc9_19.1 [symbolic = %array_type.loc9_19.2 (constants.%array_type)] { +// CHECK:STDOUT: %.loc9_24: type = splice_block %array_type.loc9_24.1 [symbolic = %array_type.loc9_24.2 (constants.%array_type)] { // CHECK:STDOUT: %int_32.loc9: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc9: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc4_6.1 [symbolic = %N.loc4_6.2 (constants.%N.51e)] // CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] // CHECK:STDOUT: %bound_method: = bound_method %N.ref, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc9_18.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc9_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc9_18.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc9_18.1 [symbolic = %int.convert_checked.loc9_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc9_18.2: Core.IntLiteral = converted %N.ref, %.loc9_18.1 [symbolic = %int.convert_checked.loc9_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc9_19.1: type = array_type %.loc9_18.2, %i32 [symbolic = %array_type.loc9_19.2 (constants.%array_type)] +// CHECK:STDOUT: %int.convert_checked.loc9_23.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc9_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc9_23.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc9_23.1 [symbolic = %int.convert_checked.loc9_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc9_23.2: Core.IntLiteral = converted %N.ref, %.loc9_23.1 [symbolic = %int.convert_checked.loc9_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc9_24.1: type = array_type %.loc9_23.2, %i32 [symbolic = %array_type.loc9_24.2 (constants.%array_type)] // CHECK:STDOUT: } -// CHECK:STDOUT: %arr: ref @F.%array_type.loc9_19.2 (%array_type) = bind_name arr, %arr.var +// CHECK:STDOUT: %arr: ref @F.%array_type.loc9_24.2 (%array_type) = bind_name arr, %arr.var // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -217,35 +217,35 @@ fn H() { G(3); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc5_15.2, constants.%Convert.960 [template = %Convert.bound (constants.%Convert.bound.588)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.3(constants.%int_32) [template = %Convert.specific_fn (constants.%Convert.specific_fn.18b)] -// CHECK:STDOUT: %int.convert_checked.loc10_18.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc5_15.2) [template = %int.convert_checked.loc10_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc10_19.2: type = array_type %int.convert_checked.loc10_18.2, %i32 [template = %array_type.loc10_19.2 (constants.%array_type.b04)] -// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc10_19.2 (%array_type.b04) [template = %require_complete (constants.%require_complete.9dc)] +// CHECK:STDOUT: %int.convert_checked.loc10_23.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc5_15.2) [template = %int.convert_checked.loc10_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc10_24.2: type = array_type %int.convert_checked.loc10_23.2, %i32 [template = %array_type.loc10_24.2 (constants.%array_type.b04)] +// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc10_24.2 (%array_type.b04) [template = %require_complete (constants.%require_complete.9dc)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%N.param_patt: %i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %arr.patt: @G.%array_type.loc10_19.2 (%array_type.b04) = binding_pattern arr -// CHECK:STDOUT: %.loc10_3: @G.%array_type.loc10_19.2 (%array_type.b04) = var_pattern %arr.patt +// CHECK:STDOUT: %arr.patt: @G.%array_type.loc10_24.2 (%array_type.b04) = binding_pattern arr +// CHECK:STDOUT: %.loc10_3: @G.%array_type.loc10_24.2 (%array_type.b04) = var_pattern %arr.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc10_19.2 (%array_type.b04) = var arr +// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc10_24.2 (%array_type.b04) = var arr // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc10_31: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) +// CHECK:STDOUT: %.loc10_36: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) // CHECK:STDOUT: assign %arr.var, -// CHECK:STDOUT: %.loc10_19: type = splice_block %array_type.loc10_19.1 [template = %array_type.loc10_19.2 (constants.%array_type.b04)] { +// CHECK:STDOUT: %.loc10_24: type = splice_block %array_type.loc10_24.1 [template = %array_type.loc10_24.2 (constants.%array_type.b04)] { // CHECK:STDOUT: %int_32.loc10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc5_15.1 [template = %N.loc5_15.2 (constants.%N.51e)] // CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] // CHECK:STDOUT: %bound_method: = bound_method %N.ref, %impl.elem0 [template = %Convert.bound (constants.%Convert.bound.588)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.3(constants.%int_32) [template = %Convert.specific_fn (constants.%Convert.specific_fn.18b)] -// CHECK:STDOUT: %int.convert_checked.loc10_18.1: init Core.IntLiteral = call %specific_fn(%N.ref) [template = %int.convert_checked.loc10_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc10_18.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc10_18.1 [template = %int.convert_checked.loc10_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc10_18.2: Core.IntLiteral = converted %N.ref, %.loc10_18.1 [template = %int.convert_checked.loc10_18.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc10_19.1: type = array_type %.loc10_18.2, %i32 [template = %array_type.loc10_19.2 (constants.%array_type.b04)] +// CHECK:STDOUT: %int.convert_checked.loc10_23.1: init Core.IntLiteral = call %specific_fn(%N.ref) [template = %int.convert_checked.loc10_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc10_23.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc10_23.1 [template = %int.convert_checked.loc10_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc10_23.2: Core.IntLiteral = converted %N.ref, %.loc10_23.1 [template = %int.convert_checked.loc10_23.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc10_24.1: type = array_type %.loc10_23.2, %i32 [template = %array_type.loc10_24.2 (constants.%array_type.b04)] // CHECK:STDOUT: } -// CHECK:STDOUT: %arr: ref @G.%array_type.loc10_19.2 (%array_type.b04) = bind_name arr, %arr.var +// CHECK:STDOUT: %arr: ref @G.%array_type.loc10_24.2 (%array_type.b04) = bind_name arr, %arr.var // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -277,8 +277,8 @@ fn H() { G(3); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Convert.bound => constants.%Convert.bound.2d6 // CHECK:STDOUT: %Convert.specific_fn => constants.%Convert.specific_fn.377 -// CHECK:STDOUT: %int.convert_checked.loc10_18.2 => constants.%int_3.1ba -// CHECK:STDOUT: %array_type.loc10_19.2 => constants.%array_type.3fb +// CHECK:STDOUT: %int.convert_checked.loc10_23.2 => constants.%int_3.1ba +// CHECK:STDOUT: %array_type.loc10_24.2 => constants.%array_type.3fb // CHECK:STDOUT: %require_complete => constants.%complete_type.cbf // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/array/nine_elements.carbon b/toolchain/check/testdata/array/nine_elements.carbon index ecb804cd10df8..c6ae0fa7781e1 100644 --- a/toolchain/check/testdata/array/nine_elements.carbon +++ b/toolchain/check/testdata/array/nine_elements.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/nine_elements.carbon -var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9); +var a: array(i32, 9) = (1, 2, 3, 4, 5, 6, 7, 8, 9); // CHECK:STDOUT: --- nine_elements.carbon // CHECK:STDOUT: @@ -84,7 +84,7 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9); // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9.988] @@ -95,90 +95,90 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9); // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_1.loc11_20: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc11_23: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_3.loc11_26: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %int_4.loc11_29: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] -// CHECK:STDOUT: %int_5.loc11_32: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] -// CHECK:STDOUT: %int_6.loc11_35: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462] -// CHECK:STDOUT: %int_7.loc11_38: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] -// CHECK:STDOUT: %int_8.loc11_41: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85] +// CHECK:STDOUT: %int_1.loc11_25: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc11_28: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_3.loc11_31: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %int_4.loc11_34: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] +// CHECK:STDOUT: %int_5.loc11_37: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] +// CHECK:STDOUT: %int_6.loc11_40: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462] +// CHECK:STDOUT: %int_7.loc11_43: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] +// CHECK:STDOUT: %int_8.loc11_46: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85] // CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9.988] -// CHECK:STDOUT: %.loc11_45.1: %tuple.type = tuple_literal (%int_1.loc11_20, %int_2.loc11_23, %int_3.loc11_26, %int_4.loc11_29, %int_5.loc11_32, %int_6.loc11_35, %int_7.loc11_38, %int_8.loc11_41, %int_9) -// CHECK:STDOUT: %impl.elem0.loc11_45.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.1: = bound_method %int_1.loc11_20, %impl.elem0.loc11_45.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc11_45.1: = specific_function %bound_method.loc11_45.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc11_45.1: init %i32 = call %specific_fn.loc11_45.1(%int_1.loc11_20) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc11_45.2: init %i32 = converted %int_1.loc11_20, %int.convert_checked.loc11_45.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_50.1: %tuple.type = tuple_literal (%int_1.loc11_25, %int_2.loc11_28, %int_3.loc11_31, %int_4.loc11_34, %int_5.loc11_37, %int_6.loc11_40, %int_7.loc11_43, %int_8.loc11_46, %int_9) +// CHECK:STDOUT: %impl.elem0.loc11_50.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.1: = bound_method %int_1.loc11_25, %impl.elem0.loc11_50.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc11_50.1: = specific_function %bound_method.loc11_50.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc11_50.1: init %i32 = call %specific_fn.loc11_50.1(%int_1.loc11_25) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc11_50.2: init %i32 = converted %int_1.loc11_25, %int.convert_checked.loc11_50.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_45.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_45.4: init %i32 = initialize_from %.loc11_45.2 to %.loc11_45.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc11_45.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.2: = bound_method %int_2.loc11_23, %impl.elem0.loc11_45.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc11_45.2: = specific_function %bound_method.loc11_45.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc11_45.2: init %i32 = call %specific_fn.loc11_45.2(%int_2.loc11_23) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc11_45.5: init %i32 = converted %int_2.loc11_23, %int.convert_checked.loc11_45.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc11_45: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc11_45.6: ref %i32 = array_index file.%a.var, %int_1.loc11_45 -// CHECK:STDOUT: %.loc11_45.7: init %i32 = initialize_from %.loc11_45.5 to %.loc11_45.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc11_45.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.3: = bound_method %int_3.loc11_26, %impl.elem0.loc11_45.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc11_45.3: = specific_function %bound_method.loc11_45.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc11_45.3: init %i32 = call %specific_fn.loc11_45.3(%int_3.loc11_26) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc11_45.8: init %i32 = converted %int_3.loc11_26, %int.convert_checked.loc11_45.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc11_45: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc11_45.9: ref %i32 = array_index file.%a.var, %int_2.loc11_45 -// CHECK:STDOUT: %.loc11_45.10: init %i32 = initialize_from %.loc11_45.8 to %.loc11_45.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %impl.elem0.loc11_45.4: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.4: = bound_method %int_4.loc11_29, %impl.elem0.loc11_45.4 [concrete = constants.%Convert.bound.ac3] -// CHECK:STDOUT: %specific_fn.loc11_45.4: = specific_function %bound_method.loc11_45.4, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.450] -// CHECK:STDOUT: %int.convert_checked.loc11_45.4: init %i32 = call %specific_fn.loc11_45.4(%int_4.loc11_29) [concrete = constants.%int_4.940] -// CHECK:STDOUT: %.loc11_45.11: init %i32 = converted %int_4.loc11_29, %int.convert_checked.loc11_45.4 [concrete = constants.%int_4.940] -// CHECK:STDOUT: %int_3.loc11_45: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc11_45.12: ref %i32 = array_index file.%a.var, %int_3.loc11_45 -// CHECK:STDOUT: %.loc11_45.13: init %i32 = initialize_from %.loc11_45.11 to %.loc11_45.12 [concrete = constants.%int_4.940] -// CHECK:STDOUT: %impl.elem0.loc11_45.5: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.5: = bound_method %int_5.loc11_32, %impl.elem0.loc11_45.5 [concrete = constants.%Convert.bound.4e6] -// CHECK:STDOUT: %specific_fn.loc11_45.5: = specific_function %bound_method.loc11_45.5, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.ba9] -// CHECK:STDOUT: %int.convert_checked.loc11_45.5: init %i32 = call %specific_fn.loc11_45.5(%int_5.loc11_32) [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc11_45.14: init %i32 = converted %int_5.loc11_32, %int.convert_checked.loc11_45.5 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %int_4.loc11_45: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] -// CHECK:STDOUT: %.loc11_45.15: ref %i32 = array_index file.%a.var, %int_4.loc11_45 -// CHECK:STDOUT: %.loc11_45.16: init %i32 = initialize_from %.loc11_45.14 to %.loc11_45.15 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %impl.elem0.loc11_45.6: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.6: = bound_method %int_6.loc11_35, %impl.elem0.loc11_45.6 [concrete = constants.%Convert.bound.ce9] -// CHECK:STDOUT: %specific_fn.loc11_45.6: = specific_function %bound_method.loc11_45.6, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.631] -// CHECK:STDOUT: %int.convert_checked.loc11_45.6: init %i32 = call %specific_fn.loc11_45.6(%int_6.loc11_35) [concrete = constants.%int_6.e56] -// CHECK:STDOUT: %.loc11_45.17: init %i32 = converted %int_6.loc11_35, %int.convert_checked.loc11_45.6 [concrete = constants.%int_6.e56] -// CHECK:STDOUT: %int_5.loc11_45: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] -// CHECK:STDOUT: %.loc11_45.18: ref %i32 = array_index file.%a.var, %int_5.loc11_45 -// CHECK:STDOUT: %.loc11_45.19: init %i32 = initialize_from %.loc11_45.17 to %.loc11_45.18 [concrete = constants.%int_6.e56] -// CHECK:STDOUT: %impl.elem0.loc11_45.7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.7: = bound_method %int_7.loc11_38, %impl.elem0.loc11_45.7 [concrete = constants.%Convert.bound.208] -// CHECK:STDOUT: %specific_fn.loc11_45.7: = specific_function %bound_method.loc11_45.7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c12] -// CHECK:STDOUT: %int.convert_checked.loc11_45.7: init %i32 = call %specific_fn.loc11_45.7(%int_7.loc11_38) [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %.loc11_45.20: init %i32 = converted %int_7.loc11_38, %int.convert_checked.loc11_45.7 [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %int_6.loc11_45: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462] -// CHECK:STDOUT: %.loc11_45.21: ref %i32 = array_index file.%a.var, %int_6.loc11_45 -// CHECK:STDOUT: %.loc11_45.22: init %i32 = initialize_from %.loc11_45.20 to %.loc11_45.21 [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %impl.elem0.loc11_45.8: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.8: = bound_method %int_8.loc11_41, %impl.elem0.loc11_45.8 [concrete = constants.%Convert.bound.e09] -// CHECK:STDOUT: %specific_fn.loc11_45.8: = specific_function %bound_method.loc11_45.8, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.e0d] -// CHECK:STDOUT: %int.convert_checked.loc11_45.8: init %i32 = call %specific_fn.loc11_45.8(%int_8.loc11_41) [concrete = constants.%int_8.98c] -// CHECK:STDOUT: %.loc11_45.23: init %i32 = converted %int_8.loc11_41, %int.convert_checked.loc11_45.8 [concrete = constants.%int_8.98c] -// CHECK:STDOUT: %int_7.loc11_45: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] -// CHECK:STDOUT: %.loc11_45.24: ref %i32 = array_index file.%a.var, %int_7.loc11_45 -// CHECK:STDOUT: %.loc11_45.25: init %i32 = initialize_from %.loc11_45.23 to %.loc11_45.24 [concrete = constants.%int_8.98c] -// CHECK:STDOUT: %impl.elem0.loc11_45.9: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_45.9: = bound_method %int_9, %impl.elem0.loc11_45.9 [concrete = constants.%Convert.bound.9e2] -// CHECK:STDOUT: %specific_fn.loc11_45.9: = specific_function %bound_method.loc11_45.9, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b02] -// CHECK:STDOUT: %int.convert_checked.loc11_45.9: init %i32 = call %specific_fn.loc11_45.9(%int_9) [concrete = constants.%int_9.f88] -// CHECK:STDOUT: %.loc11_45.26: init %i32 = converted %int_9, %int.convert_checked.loc11_45.9 [concrete = constants.%int_9.f88] -// CHECK:STDOUT: %int_8.loc11_45: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85] -// CHECK:STDOUT: %.loc11_45.27: ref %i32 = array_index file.%a.var, %int_8.loc11_45 -// CHECK:STDOUT: %.loc11_45.28: init %i32 = initialize_from %.loc11_45.26 to %.loc11_45.27 [concrete = constants.%int_9.f88] -// CHECK:STDOUT: %.loc11_45.29: init %array_type = array_init (%.loc11_45.4, %.loc11_45.7, %.loc11_45.10, %.loc11_45.13, %.loc11_45.16, %.loc11_45.19, %.loc11_45.22, %.loc11_45.25, %.loc11_45.28) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_45.1, %.loc11_45.29 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_50.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_50.4: init %i32 = initialize_from %.loc11_50.2 to %.loc11_50.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc11_50.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.2: = bound_method %int_2.loc11_28, %impl.elem0.loc11_50.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc11_50.2: = specific_function %bound_method.loc11_50.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc11_50.2: init %i32 = call %specific_fn.loc11_50.2(%int_2.loc11_28) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc11_50.5: init %i32 = converted %int_2.loc11_28, %int.convert_checked.loc11_50.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc11_50: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc11_50.6: ref %i32 = array_index file.%a.var, %int_1.loc11_50 +// CHECK:STDOUT: %.loc11_50.7: init %i32 = initialize_from %.loc11_50.5 to %.loc11_50.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc11_50.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.3: = bound_method %int_3.loc11_31, %impl.elem0.loc11_50.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc11_50.3: = specific_function %bound_method.loc11_50.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc11_50.3: init %i32 = call %specific_fn.loc11_50.3(%int_3.loc11_31) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc11_50.8: init %i32 = converted %int_3.loc11_31, %int.convert_checked.loc11_50.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc11_50: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc11_50.9: ref %i32 = array_index file.%a.var, %int_2.loc11_50 +// CHECK:STDOUT: %.loc11_50.10: init %i32 = initialize_from %.loc11_50.8 to %.loc11_50.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %impl.elem0.loc11_50.4: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.4: = bound_method %int_4.loc11_34, %impl.elem0.loc11_50.4 [concrete = constants.%Convert.bound.ac3] +// CHECK:STDOUT: %specific_fn.loc11_50.4: = specific_function %bound_method.loc11_50.4, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.450] +// CHECK:STDOUT: %int.convert_checked.loc11_50.4: init %i32 = call %specific_fn.loc11_50.4(%int_4.loc11_34) [concrete = constants.%int_4.940] +// CHECK:STDOUT: %.loc11_50.11: init %i32 = converted %int_4.loc11_34, %int.convert_checked.loc11_50.4 [concrete = constants.%int_4.940] +// CHECK:STDOUT: %int_3.loc11_50: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc11_50.12: ref %i32 = array_index file.%a.var, %int_3.loc11_50 +// CHECK:STDOUT: %.loc11_50.13: init %i32 = initialize_from %.loc11_50.11 to %.loc11_50.12 [concrete = constants.%int_4.940] +// CHECK:STDOUT: %impl.elem0.loc11_50.5: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.5: = bound_method %int_5.loc11_37, %impl.elem0.loc11_50.5 [concrete = constants.%Convert.bound.4e6] +// CHECK:STDOUT: %specific_fn.loc11_50.5: = specific_function %bound_method.loc11_50.5, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.ba9] +// CHECK:STDOUT: %int.convert_checked.loc11_50.5: init %i32 = call %specific_fn.loc11_50.5(%int_5.loc11_37) [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc11_50.14: init %i32 = converted %int_5.loc11_37, %int.convert_checked.loc11_50.5 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %int_4.loc11_50: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] +// CHECK:STDOUT: %.loc11_50.15: ref %i32 = array_index file.%a.var, %int_4.loc11_50 +// CHECK:STDOUT: %.loc11_50.16: init %i32 = initialize_from %.loc11_50.14 to %.loc11_50.15 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %impl.elem0.loc11_50.6: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.6: = bound_method %int_6.loc11_40, %impl.elem0.loc11_50.6 [concrete = constants.%Convert.bound.ce9] +// CHECK:STDOUT: %specific_fn.loc11_50.6: = specific_function %bound_method.loc11_50.6, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.631] +// CHECK:STDOUT: %int.convert_checked.loc11_50.6: init %i32 = call %specific_fn.loc11_50.6(%int_6.loc11_40) [concrete = constants.%int_6.e56] +// CHECK:STDOUT: %.loc11_50.17: init %i32 = converted %int_6.loc11_40, %int.convert_checked.loc11_50.6 [concrete = constants.%int_6.e56] +// CHECK:STDOUT: %int_5.loc11_50: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] +// CHECK:STDOUT: %.loc11_50.18: ref %i32 = array_index file.%a.var, %int_5.loc11_50 +// CHECK:STDOUT: %.loc11_50.19: init %i32 = initialize_from %.loc11_50.17 to %.loc11_50.18 [concrete = constants.%int_6.e56] +// CHECK:STDOUT: %impl.elem0.loc11_50.7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.7: = bound_method %int_7.loc11_43, %impl.elem0.loc11_50.7 [concrete = constants.%Convert.bound.208] +// CHECK:STDOUT: %specific_fn.loc11_50.7: = specific_function %bound_method.loc11_50.7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c12] +// CHECK:STDOUT: %int.convert_checked.loc11_50.7: init %i32 = call %specific_fn.loc11_50.7(%int_7.loc11_43) [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %.loc11_50.20: init %i32 = converted %int_7.loc11_43, %int.convert_checked.loc11_50.7 [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %int_6.loc11_50: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462] +// CHECK:STDOUT: %.loc11_50.21: ref %i32 = array_index file.%a.var, %int_6.loc11_50 +// CHECK:STDOUT: %.loc11_50.22: init %i32 = initialize_from %.loc11_50.20 to %.loc11_50.21 [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %impl.elem0.loc11_50.8: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.8: = bound_method %int_8.loc11_46, %impl.elem0.loc11_50.8 [concrete = constants.%Convert.bound.e09] +// CHECK:STDOUT: %specific_fn.loc11_50.8: = specific_function %bound_method.loc11_50.8, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.e0d] +// CHECK:STDOUT: %int.convert_checked.loc11_50.8: init %i32 = call %specific_fn.loc11_50.8(%int_8.loc11_46) [concrete = constants.%int_8.98c] +// CHECK:STDOUT: %.loc11_50.23: init %i32 = converted %int_8.loc11_46, %int.convert_checked.loc11_50.8 [concrete = constants.%int_8.98c] +// CHECK:STDOUT: %int_7.loc11_50: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] +// CHECK:STDOUT: %.loc11_50.24: ref %i32 = array_index file.%a.var, %int_7.loc11_50 +// CHECK:STDOUT: %.loc11_50.25: init %i32 = initialize_from %.loc11_50.23 to %.loc11_50.24 [concrete = constants.%int_8.98c] +// CHECK:STDOUT: %impl.elem0.loc11_50.9: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_50.9: = bound_method %int_9, %impl.elem0.loc11_50.9 [concrete = constants.%Convert.bound.9e2] +// CHECK:STDOUT: %specific_fn.loc11_50.9: = specific_function %bound_method.loc11_50.9, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b02] +// CHECK:STDOUT: %int.convert_checked.loc11_50.9: init %i32 = call %specific_fn.loc11_50.9(%int_9) [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %.loc11_50.26: init %i32 = converted %int_9, %int.convert_checked.loc11_50.9 [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %int_8.loc11_50: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85] +// CHECK:STDOUT: %.loc11_50.27: ref %i32 = array_index file.%a.var, %int_8.loc11_50 +// CHECK:STDOUT: %.loc11_50.28: init %i32 = initialize_from %.loc11_50.26 to %.loc11_50.27 [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %.loc11_50.29: init %array_type = array_init (%.loc11_50.4, %.loc11_50.7, %.loc11_50.10, %.loc11_50.13, %.loc11_50.16, %.loc11_50.19, %.loc11_50.22, %.loc11_50.25, %.loc11_50.28) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_50.1, %.loc11_50.29 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/basics/numeric_literals.carbon b/toolchain/check/testdata/basics/numeric_literals.carbon index b08417cb8bf36..adbe4bf535684 100644 --- a/toolchain/check/testdata/basics/numeric_literals.carbon +++ b/toolchain/check/testdata/basics/numeric_literals.carbon @@ -11,7 +11,7 @@ fn F() { // 8 and 9 trigger special behavior in APInt when mishandling signed versus // unsigned, so we pay extra attention to those. - var ints: [i32; 6] = ( + var ints: array(i32, 6) = ( 8, 9, 0x8, @@ -19,7 +19,7 @@ fn F() { 2147483647, 0x7FFFFFFF, ); - var floats: [f64; 6] = ( + var floats: array(f64, 6) = ( 0.9, 8.0, 80.0, @@ -163,7 +163,7 @@ fn F() { // CHECK:STDOUT: %.loc21_3.20: init %array_type.d49 = array_init (%.loc21_3.4, %.loc21_3.7, %.loc21_3.10, %.loc21_3.13, %.loc21_3.16, %.loc21_3.19) to %ints.var [concrete = constants.%array.ae2] // CHECK:STDOUT: %.loc14_3.2: init %array_type.d49 = converted %.loc21_3.1, %.loc21_3.20 [concrete = constants.%array.ae2] // CHECK:STDOUT: assign %ints.var, %.loc14_3.2 -// CHECK:STDOUT: %.loc14_20: type = splice_block %array_type.loc14 [concrete = constants.%array_type.d49] { +// CHECK:STDOUT: %.loc14_25: type = splice_block %array_type.loc14 [concrete = constants.%array_type.d49] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_6.loc14: Core.IntLiteral = int_value 6 [concrete = constants.%int_6] @@ -203,12 +203,12 @@ fn F() { // CHECK:STDOUT: %.loc29_3.14: init %array_type.72b = array_init (%.loc29_3.3, %.loc29_3.5, %.loc29_3.7, %.loc29_3.9, %.loc29_3.11, %.loc29_3.13) to %floats.var [concrete = constants.%array.a2f] // CHECK:STDOUT: %.loc22_3.2: init %array_type.72b = converted %.loc29_3.1, %.loc29_3.14 [concrete = constants.%array.a2f] // CHECK:STDOUT: assign %floats.var, %.loc22_3.2 -// CHECK:STDOUT: %.loc22_22: type = splice_block %array_type.loc22 [concrete = constants.%array_type.72b] { +// CHECK:STDOUT: %.loc22_27: type = splice_block %array_type.loc22 [concrete = constants.%array_type.72b] { // CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] // CHECK:STDOUT: %float.make_type: init type = call constants.%Float(%int_64) [concrete = f64] // CHECK:STDOUT: %int_6.loc22: Core.IntLiteral = int_value 6 [concrete = constants.%int_6] -// CHECK:STDOUT: %.loc22_16.1: type = value_of_initializer %float.make_type [concrete = f64] -// CHECK:STDOUT: %.loc22_16.2: type = converted %float.make_type, %.loc22_16.1 [concrete = f64] +// CHECK:STDOUT: %.loc22_21.1: type = value_of_initializer %float.make_type [concrete = f64] +// CHECK:STDOUT: %.loc22_21.2: type = converted %float.make_type, %.loc22_21.1 [concrete = f64] // CHECK:STDOUT: %array_type.loc22: type = array_type %int_6.loc22, f64 [concrete = constants.%array_type.72b] // CHECK:STDOUT: } // CHECK:STDOUT: %floats: ref %array_type.72b = bind_name floats, %floats.var diff --git a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon index 86fcd7f7b507c..6a5cee487233c 100644 --- a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon @@ -74,27 +74,27 @@ fn G() { library "[[@TEST_NAME]]"; -class HoldsType(T:! [type; 1]) {} +class HoldsType(T:! array(type, 1)) {} // `a` is received as a value, and has a type that requires going through // ArrayIndex. Building the value representation must handle this indirection. -// CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE+4]]:41: error: cannot evaluate type expression [TypeExprEvaluationFailure] -// CHECK:STDERR: fn F[T:! [type; 1]](x: HoldsType(T), a: T[0]) {} -// CHECK:STDERR: ^~~~ +// CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE+4]]:46: error: cannot evaluate type expression [TypeExprEvaluationFailure] +// CHECK:STDERR: fn F[T:! array(type, 1)](x: HoldsType(T), a: T[0]) {} +// CHECK:STDERR: ^~~~ // CHECK:STDERR: -fn F[T:! [type; 1]](x: HoldsType(T), a: T[0]) {} +fn F[T:! array(type, 1)](x: HoldsType(T), a: T[0]) {} class C {} fn G() { // CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE+7]]:11: error: argument for generic parameter is not a compile-time constant [CompTimeArgumentNotConstant] - // CHECK:STDERR: F({} as HoldsType((C, ) as [type; 1]), {}); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: F({} as HoldsType((C, ) as array(type, 1)), {}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_todo_array_index.carbon:[[@LINE-16]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam] - // CHECK:STDERR: class HoldsType(T:! [type; 1]) {} + // CHECK:STDERR: class HoldsType(T:! array(type, 1)) {} // CHECK:STDERR: ^ // CHECK:STDERR: - F({} as HoldsType((C, ) as [type; 1]), {}); + F({} as HoldsType((C, ) as array(type, 1)), {}); } @@ -720,27 +720,27 @@ fn G() { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc12_6.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: %array_type = value_param_pattern %T.patt.loc12_6.1, runtime_param [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %x.patt: @F.%HoldsType.loc12_35.2 (%HoldsType) = binding_pattern x -// CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc12_35.2 (%HoldsType) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: %a.patt: = binding_pattern a // CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: %array_type = value_param runtime_param -// CHECK:STDOUT: %.loc12_18: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc12_23: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_6.2 (constants.%T)] -// CHECK:STDOUT: %x.param: @F.%HoldsType.loc12_35.2 (%HoldsType) = value_param runtime_param0 -// CHECK:STDOUT: %.loc12_35: type = splice_block %HoldsType.loc12_35.1 [symbolic = %HoldsType.loc12_35.2 (constants.%HoldsType)] { +// CHECK:STDOUT: %x.param: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param runtime_param0 +// CHECK:STDOUT: %.loc12_40: type = splice_block %HoldsType.loc12_40.1 [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] { // CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic] -// CHECK:STDOUT: %T.ref.loc12_34: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] -// CHECK:STDOUT: %HoldsType.loc12_35.1: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc12_35.2 (constants.%HoldsType)] +// CHECK:STDOUT: %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] +// CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: @F.%HoldsType.loc12_35.2 (%HoldsType) = bind_name x, %x.param +// CHECK:STDOUT: %x: @F.%HoldsType.loc12_40.2 (%HoldsType) = bind_name x, %x.param // CHECK:STDOUT: %a.param: = value_param runtime_param1 // CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %T.ref.loc12_41: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] +// CHECK:STDOUT: %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -748,11 +748,11 @@ fn G() { // CHECK:STDOUT: %bound_method: = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc12_43.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc12_43.2: %i32 = converted %int_0, %.loc12_43.1 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc12_44.1: ref %array_type = value_as_ref %T.ref.loc12_41 -// CHECK:STDOUT: %.loc12_44.2: ref type = array_index %.loc12_44.1, %.loc12_43.2 -// CHECK:STDOUT: %.loc12_44.3: type = bind_value %.loc12_44.2 +// CHECK:STDOUT: %.loc12_48.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc12_48.2: %i32 = converted %int_0, %.loc12_48.1 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc12_49.1: ref %array_type = value_as_ref %T.ref.loc12_46 +// CHECK:STDOUT: %.loc12_49.2: ref type = array_index %.loc12_49.1, %.loc12_48.2 +// CHECK:STDOUT: %.loc12_49.3: type = bind_value %.loc12_49.2 // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, %a.param // CHECK:STDOUT: } @@ -786,12 +786,12 @@ fn G() { // CHECK:STDOUT: generic fn @F(%T.loc12_6.1: %array_type) { // CHECK:STDOUT: %T.loc12_6.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc12_6.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %HoldsType.loc12_35.2: type = class_type @HoldsType, @HoldsType(%T.loc12_6.2) [symbolic = %HoldsType.loc12_35.2 (constants.%HoldsType)] +// CHECK:STDOUT: %HoldsType.loc12_40.2: type = class_type @HoldsType, @HoldsType(%T.loc12_6.2) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%HoldsType.loc12_35.2 (%HoldsType) [symbolic = %require_complete (constants.%require_complete.640)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%HoldsType.loc12_40.2 (%HoldsType) [symbolic = %require_complete (constants.%require_complete.640)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: %array_type](%x.param_patt: @F.%HoldsType.loc12_35.2 (%HoldsType), %a.param_patt: ) { +// CHECK:STDOUT: fn[%T.param_patt: %array_type](%x.param_patt: @F.%HoldsType.loc12_40.2 (%HoldsType), %a.param_patt: ) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -814,7 +814,7 @@ fn G() { // CHECK:STDOUT: %.loc24_27.1: init %array_type = converted %.loc24_25.1, %.loc24_25.5 [concrete = constants.%array] // CHECK:STDOUT: %.loc24_27.2: ref %array_type = temporary %.loc24_25.2, %.loc24_27.1 // CHECK:STDOUT: %.loc24_27.3: %array_type = bind_value %.loc24_27.2 -// CHECK:STDOUT: %.loc24_43: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc24_48: %empty_struct_type = struct_literal () // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -828,7 +828,7 @@ fn G() { // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc12_6.2 => constants.%T // CHECK:STDOUT: %T.patt.loc12_6.2 => constants.%T -// CHECK:STDOUT: %HoldsType.loc12_35.2 => constants.%HoldsType +// CHECK:STDOUT: %HoldsType.loc12_40.2 => constants.%HoldsType // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @HoldsType(@F.%T.loc12_6.2) {} diff --git a/toolchain/check/testdata/builtins/int/and.carbon b/toolchain/check/testdata/builtins/int/and.carbon index f624ff011d09d..cde56b841a995 100644 --- a/toolchain/check/testdata/builtins/int/and.carbon +++ b/toolchain/check/testdata/builtins/int/and.carbon @@ -16,8 +16,8 @@ library "[[@TEST_NAME]]"; fn And(a: i32, b: i32) -> i32 = "int.and"; -var arr: [i32; And(12, 10)]; -let arr_p: [i32; 8]* = &arr; +var arr: array(i32, And(12, 10)); +let arr_p: array(i32, 8)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return And(a, b); diff --git a/toolchain/check/testdata/builtins/int/complement.carbon b/toolchain/check/testdata/builtins/int/complement.carbon index a40d2c6960bae..58165355f02ab 100644 --- a/toolchain/check/testdata/builtins/int/complement.carbon +++ b/toolchain/check/testdata/builtins/int/complement.carbon @@ -17,8 +17,8 @@ library "[[@TEST_NAME]]"; fn Complement(a: i32) -> i32 = "int.complement"; fn And(a: i32, b: i32) -> i32 = "int.and"; -var arr: [i32; And(Complement(0x123456), 0xFFFFFF)]; -let arr_p: [i32; 0xEDCBA9]* = &arr; +var arr: array(i32, And(Complement(0x123456), 0xFFFFFF)); +let arr_p: array(i32, 0xEDCBA9)* = &arr; fn RuntimeCallIsValid(a: i32) -> i32 { return Complement(a); diff --git a/toolchain/check/testdata/builtins/int/or.carbon b/toolchain/check/testdata/builtins/int/or.carbon index 9dbd3cca8b7ef..001df66e5900b 100644 --- a/toolchain/check/testdata/builtins/int/or.carbon +++ b/toolchain/check/testdata/builtins/int/or.carbon @@ -14,8 +14,8 @@ fn Or(a: i32, b: i32) -> i32 = "int.or"; -var arr: [i32; Or(12, 10)]; -let arr_p: [i32; 14]* = &arr; +var arr: array(i32, Or(12, 10)); +let arr_p: array(i32, 14)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Or(a, b); diff --git a/toolchain/check/testdata/builtins/int/sadd.carbon b/toolchain/check/testdata/builtins/int/sadd.carbon index 45aa2db79c662..bfd730eac191c 100644 --- a/toolchain/check/testdata/builtins/int/sadd.carbon +++ b/toolchain/check/testdata/builtins/int/sadd.carbon @@ -94,30 +94,30 @@ fn MixedAdd3(a: i32, b: Core.IntLiteral()) -> Core.IntLiteral() = "int.sadd"; // CHECK:STDERR: fn MixedAdd4(a: Core.IntLiteral(), b: i32) -> Core.IntLiteral() = "int.sadd"; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_few: [i32; TooFew(1)]; -// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:25: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_few: array(i32, TooFew(1)); +// CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: -var too_few: [i32; TooFew(1)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_many: [i32; TooMany(1, 2, 3)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~ +var too_few: array(i32, TooFew(1)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:26: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_many: array(i32, TooMany(1, 2, 3)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~ // CHECK:STDERR: -var too_many: [i32; TooMany(1, 2, 3)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var bad_return_type: [i32; BadReturnType(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ +var too_many: array(i32, TooMany(1, 2, 3)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:33: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var bad_return_type: array(i32, BadReturnType(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_return_type: [i32; BadReturnType(1, 2)]; +var bad_return_type: array(i32, BadReturnType(1, 2)); -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch] -// CHECK:STDERR: var bad_call: [i32; JustRight(1, 2, 3)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:26: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch] +// CHECK:STDERR: var bad_call: array(i32, JustRight(1, 2, 3)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-43]]:1: note: calling function declared here [InCallToEntity] // CHECK:STDERR: fn JustRight(a: i32, b: i32) -> i32 = "int.sadd"; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_call: [i32; JustRight(1, 2, 3)]; +var bad_call: array(i32, JustRight(1, 2, 3)); fn RuntimeCallIsValidTooFew(a: i32) -> i32 { return TooFew(a); diff --git a/toolchain/check/testdata/builtins/int/sdiv.carbon b/toolchain/check/testdata/builtins/int/sdiv.carbon index 3de44450bb883..1850ce360d6af 100644 --- a/toolchain/check/testdata/builtins/int/sdiv.carbon +++ b/toolchain/check/testdata/builtins/int/sdiv.carbon @@ -14,8 +14,8 @@ fn Div(a: i32, b: i32) -> i32 = "int.sdiv"; -var arr: [i32; Div(3, 2)]; -let arr_p: [i32; 1]* = &arr; +var arr: array(i32, Div(3, 2)); +let arr_p: array(i32, 1)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Div(a, b); diff --git a/toolchain/check/testdata/builtins/int/smod.carbon b/toolchain/check/testdata/builtins/int/smod.carbon index bd15000b6a263..5e09cb6ab5865 100644 --- a/toolchain/check/testdata/builtins/int/smod.carbon +++ b/toolchain/check/testdata/builtins/int/smod.carbon @@ -14,8 +14,8 @@ fn Mod(a: i32, b: i32) -> i32 = "int.smod"; -var arr: [i32; Mod(5, 3)]; -let arr_p: [i32; 2]* = &arr; +var arr: array(i32, Mod(5, 3)); +let arr_p: array(i32, 2)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Mod(a, b); diff --git a/toolchain/check/testdata/builtins/int/snegate.carbon b/toolchain/check/testdata/builtins/int/snegate.carbon index 1c5a448f0263a..1e49effea7c7b 100644 --- a/toolchain/check/testdata/builtins/int/snegate.carbon +++ b/toolchain/check/testdata/builtins/int/snegate.carbon @@ -14,8 +14,8 @@ fn Negate(a: i32) -> i32 = "int.snegate"; -var arr: [i32; Negate(Negate(123))]; -let arr_p: [i32; 123]* = &arr; +var arr: array(i32, Negate(Negate(123))); +let arr_p: array(i32, 123)* = &arr; let n: i32 = Negate(1); @@ -59,30 +59,30 @@ fn TooMany(a: i32, b: i32) -> i32 = "int.snegate"; fn BadReturnType(a: i32) -> bool = "int.snegate"; fn JustRight(a: i32) -> i32 = "int.snegate"; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_few: [i32; TooFew()]; -// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:25: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_few: array(i32, TooFew()); +// CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: -var too_few: [i32; TooFew()]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_many: [i32; TooMany(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~ +var too_few: array(i32, TooFew()); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:26: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_many: array(i32, TooMany(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: -var too_many: [i32; TooMany(1, 2)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var bad_return_type: [i32; BadReturnType(1)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~ +var too_many: array(i32, TooMany(1, 2)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:33: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var bad_return_type: array(i32, BadReturnType(1)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_return_type: [i32; BadReturnType(1)]; +var bad_return_type: array(i32, BadReturnType(1)); -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch] -// CHECK:STDERR: var bad_call: [i32; JustRight(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:26: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch] +// CHECK:STDERR: var bad_call: array(i32, JustRight(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~ // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-21]]:1: note: calling function declared here [InCallToEntity] // CHECK:STDERR: fn JustRight(a: i32) -> i32 = "int.snegate"; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_call: [i32; JustRight(1, 2)]; +var bad_call: array(i32, JustRight(1, 2)); fn RuntimeCallIsValidTooFew(a: i32) -> i32 { // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 1 argument passed to function expecting 0 arguments [CallArgCountMismatch] diff --git a/toolchain/check/testdata/builtins/int/ssub.carbon b/toolchain/check/testdata/builtins/int/ssub.carbon index a52cad1d39f10..c2994dc1a0251 100644 --- a/toolchain/check/testdata/builtins/int/ssub.carbon +++ b/toolchain/check/testdata/builtins/int/ssub.carbon @@ -14,8 +14,8 @@ fn Sub(a: i32, b: i32) -> i32 = "int.ssub"; -var arr: [i32; Sub(3, 2)]; -let arr_p: [i32; 1]* = &arr; +var arr: array(i32, Sub(3, 2)); +let arr_p: array(i32, 1)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Sub(a, b); diff --git a/toolchain/check/testdata/builtins/int/uadd.carbon b/toolchain/check/testdata/builtins/int/uadd.carbon index 064caa751627a..1954b91e0271a 100644 --- a/toolchain/check/testdata/builtins/int/uadd.carbon +++ b/toolchain/check/testdata/builtins/int/uadd.carbon @@ -14,8 +14,8 @@ fn Add(a: i32, b: i32) -> i32 = "int.uadd"; -var arr: [i32; Add(1, 2)]; -let arr_p: [i32; 3]* = &arr; +var arr: array(i32, Add(1, 2)); +let arr_p: array(i32, 3)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Add(a, b); @@ -42,30 +42,30 @@ fn TooMany(a: i32, b: i32, c: i32) -> i32 = "int.uadd"; fn BadReturnType(a: i32, b: i32) -> bool = "int.uadd"; fn JustRight(a: i32, b: i32) -> i32 = "int.uadd"; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_few: [i32; TooFew(1)]; -// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:25: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_few: array(i32, TooFew(1)); +// CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: -var too_few: [i32; TooFew(1)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_many: [i32; TooMany(1, 2, 3)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~ +var too_few: array(i32, TooFew(1)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:26: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_many: array(i32, TooMany(1, 2, 3)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~ // CHECK:STDERR: -var too_many: [i32; TooMany(1, 2, 3)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var bad_return_type: [i32; BadReturnType(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ +var too_many: array(i32, TooMany(1, 2, 3)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:33: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var bad_return_type: array(i32, BadReturnType(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_return_type: [i32; BadReturnType(1, 2)]; +var bad_return_type: array(i32, BadReturnType(1, 2)); -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch] -// CHECK:STDERR: var bad_call: [i32; JustRight(1, 2, 3)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:26: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch] +// CHECK:STDERR: var bad_call: array(i32, JustRight(1, 2, 3)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-21]]:1: note: calling function declared here [InCallToEntity] // CHECK:STDERR: fn JustRight(a: i32, b: i32) -> i32 = "int.uadd"; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_call: [i32; JustRight(1, 2, 3)]; +var bad_call: array(i32, JustRight(1, 2, 3)); fn RuntimeCallIsValidTooFew(a: i32) -> i32 { return TooFew(a); diff --git a/toolchain/check/testdata/builtins/int/udiv.carbon b/toolchain/check/testdata/builtins/int/udiv.carbon index 9220345306509..6c6d574fbb40d 100644 --- a/toolchain/check/testdata/builtins/int/udiv.carbon +++ b/toolchain/check/testdata/builtins/int/udiv.carbon @@ -14,8 +14,8 @@ fn Div(a: i32, b: i32) -> i32 = "int.udiv"; -var arr: [i32; Div(3, 2)]; -let arr_p: [i32; 1]* = &arr; +var arr: array(i32, Div(3, 2)); +let arr_p: array(i32, 1)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Div(a, b); diff --git a/toolchain/check/testdata/builtins/int/umod.carbon b/toolchain/check/testdata/builtins/int/umod.carbon index 65498af8bea35..471afc30f2ef2 100644 --- a/toolchain/check/testdata/builtins/int/umod.carbon +++ b/toolchain/check/testdata/builtins/int/umod.carbon @@ -14,8 +14,8 @@ fn Mod(a: i32, b: i32) -> i32 = "int.umod"; -var arr: [i32; Mod(5, 3)]; -let arr_p: [i32; 2]* = &arr; +var arr: array(i32, Mod(5, 3)); +let arr_p: array(i32, 2)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Mod(a, b); diff --git a/toolchain/check/testdata/builtins/int/umul.carbon b/toolchain/check/testdata/builtins/int/umul.carbon index 40d89a11cd87f..f69e85163a22d 100644 --- a/toolchain/check/testdata/builtins/int/umul.carbon +++ b/toolchain/check/testdata/builtins/int/umul.carbon @@ -14,8 +14,8 @@ fn Mul(a: i32, b: i32) -> i32 = "int.umul"; -var arr: [i32; Mul(3, 2)]; -let arr_p: [i32; 6]* = &arr; +var arr: array(i32, Mul(3, 2)); +let arr_p: array(i32, 6)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Mul(a, b); diff --git a/toolchain/check/testdata/builtins/int/unegate.carbon b/toolchain/check/testdata/builtins/int/unegate.carbon index 39bdaf6f153c8..03160a963e995 100644 --- a/toolchain/check/testdata/builtins/int/unegate.carbon +++ b/toolchain/check/testdata/builtins/int/unegate.carbon @@ -14,8 +14,8 @@ fn Negate(a: u32) -> u32 = "int.unegate"; -var arr: [u32; Negate(Negate(123))]; -let arr_p: [u32; 123]* = &arr; +var arr: array(u32, Negate(Negate(123))); +let arr_p: array(u32, 123)* = &arr; let n: u32 = Negate(1); @@ -44,30 +44,30 @@ fn TooMany(a: u32, b: u32) -> u32 = "int.unegate"; fn BadReturnType(a: u32) -> bool = "int.unegate"; fn JustRight(a: u32) -> u32 = "int.unegate"; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_few: [u32; TooFew()]; -// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:25: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_few: array(u32, TooFew()); +// CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: -var too_few: [u32; TooFew()]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var too_many: [u32; TooMany(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~ +var too_few: array(u32, TooFew()); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:26: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var too_many: array(u32, TooMany(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: -var too_many: [u32; TooMany(1, 2)]; -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var bad_return_type: [u32; BadReturnType(1)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~ +var too_many: array(u32, TooMany(1, 2)); +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:33: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var bad_return_type: array(u32, BadReturnType(1)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_return_type: [u32; BadReturnType(1)]; +var bad_return_type: array(u32, BadReturnType(1)); -// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch] -// CHECK:STDERR: var bad_call: [u32; JustRight(1, 2)]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:26: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch] +// CHECK:STDERR: var bad_call: array(u32, JustRight(1, 2)); +// CHECK:STDERR: ^~~~~~~~~~~~~~~ // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-21]]:1: note: calling function declared here [InCallToEntity] // CHECK:STDERR: fn JustRight(a: u32) -> u32 = "int.unegate"; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var bad_call: [u32; JustRight(1, 2)]; +var bad_call: array(u32, JustRight(1, 2)); fn RuntimeCallIsValidTooFew(a: u32) -> u32 { // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 1 argument passed to function expecting 0 arguments [CallArgCountMismatch] diff --git a/toolchain/check/testdata/builtins/int/usub.carbon b/toolchain/check/testdata/builtins/int/usub.carbon index 662d33f36fbac..c4413c9c50142 100644 --- a/toolchain/check/testdata/builtins/int/usub.carbon +++ b/toolchain/check/testdata/builtins/int/usub.carbon @@ -14,8 +14,8 @@ fn Sub(a: i32, b: i32) -> i32 = "int.usub"; -var arr: [i32; Sub(3, 2)]; -let arr_p: [i32; 1]* = &arr; +var arr: array(i32, Sub(3, 2)); +let arr_p: array(i32, 1)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Sub(a, b); diff --git a/toolchain/check/testdata/builtins/int/xor.carbon b/toolchain/check/testdata/builtins/int/xor.carbon index 5471c38e8b83f..9a1f2237ea25a 100644 --- a/toolchain/check/testdata/builtins/int/xor.carbon +++ b/toolchain/check/testdata/builtins/int/xor.carbon @@ -14,8 +14,8 @@ fn Xor(a: i32, b: i32) -> i32 = "int.xor"; -var arr: [i32; Xor(12, 10)]; -let arr_p: [i32; 6]* = &arr; +var arr: array(i32, Xor(12, 10)); +let arr_p: array(i32, 6)* = &arr; fn RuntimeCallIsValid(a: i32, b: i32) -> i32 { return Xor(a, b); diff --git a/toolchain/check/testdata/deduce/array.carbon b/toolchain/check/testdata/deduce/array.carbon index f0a3ee5726f16..ac8e2785d6380 100644 --- a/toolchain/check/testdata/deduce/array.carbon +++ b/toolchain/check/testdata/deduce/array.carbon @@ -14,10 +14,10 @@ library "[[@TEST_NAME]]"; class C {} -fn F[T:! type](a: [T; 3]) -> T { return a[0]; } +fn F[T:! type](a: array(T, 3)) -> T { return a[0]; } fn G() -> C { - var a: [C; 3] = ({}, {}, {}); + var a: array(C, 3) = ({}, {}, {}); return F(a); } @@ -27,10 +27,10 @@ library "[[@TEST_NAME]]"; class C {} -fn F[N:! Core.IntLiteral()](a: [C; N]) -> i32 { return N; } +fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; } fn G() -> i32 { - var a: [C; 3] = ({}, {}, {}); + var a: array(C, 3) = ({}, {}, {}); return F(a); } @@ -40,10 +40,10 @@ library "[[@TEST_NAME]]"; class C {} -fn F[T:! type, N:! Core.IntLiteral()](a: [T; N]) {} +fn F[T:! type, N:! Core.IntLiteral()](a: array(T, N)) {} fn G() { - var a: [C; 3] = ({}, {}, {}); + var a: array(C, 3) = ({}, {}, {}); F(a); } @@ -53,11 +53,11 @@ library "[[@TEST_NAME]]"; class C {} -fn F[T:! type](a: [T; 2]) -> T { return a[0]; } +fn F[T:! type](a: array(T, 2)) -> T { return a[0]; } fn G() -> C { // TODO: We succeed at deducing T here but fail to convert. Is this the right behavior? - var a: [C; 3] = ({}, {}, {}); + var a: array(C, 3) = ({}, {}, {}); // CHECK:STDERR: fail_bound_mismatch.carbon:[[@LINE+10]]:12: error: cannot implicitly convert from `[C; 3]` to `[C; 2]` [ImplicitAsConversionFailure] // CHECK:STDERR: return F(a); // CHECK:STDERR: ^ @@ -65,8 +65,8 @@ fn G() -> C { // CHECK:STDERR: return F(a); // CHECK:STDERR: ^ // CHECK:STDERR: fail_bound_mismatch.carbon:[[@LINE-11]]:16: note: initializing function parameter [InCallToFunctionParam] - // CHECK:STDERR: fn F[T:! type](a: [T; 2]) -> T { return a[0]; } - // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fn F[T:! type](a: array(T, 2)) -> T { return a[0]; } + // CHECK:STDERR: ^~~~~~~~~~~~~~ // CHECK:STDERR: return F(a); } @@ -78,11 +78,11 @@ library "[[@TEST_NAME]]"; class C {} class D {} -fn F[N:! Core.IntLiteral()](a: [C; N]) -> i32 { return N; } +fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; } fn G() -> i32 { // TODO: We succeed at deducing N here but fail to convert. Is this the right behavior? - var a: [D; 3] = ({}, {}, {}); + var a: array(D, 3) = ({}, {}, {}); // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+10]]:12: error: cannot implicitly convert from `[D; 3]` to `[C; 3]` [ImplicitAsConversionFailure] // CHECK:STDERR: return F(a); // CHECK:STDERR: ^ @@ -90,8 +90,8 @@ fn G() -> i32 { // CHECK:STDERR: return F(a); // CHECK:STDERR: ^ // CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE-11]]:29: note: initializing function parameter [InCallToFunctionParam] - // CHECK:STDERR: fn F[N:! Core.IntLiteral()](a: [C; N]) -> i32 { return N; } - // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fn F[N:! Core.IntLiteral()](a: array(C, N)) -> i32 { return N; } + // CHECK:STDERR: ^~~~~~~~~~~~~~ // CHECK:STDERR: return F(a); } @@ -102,10 +102,10 @@ library "[[@TEST_NAME]]"; class C {} -fn F[N:! i32](a: [C; N]) -> i32 { return N; } +fn F[N:! i32](a: array(C, N)) -> i32 { return N; } fn G() -> i32 { - var a: [C; 3] = ({}, {}, {}); + var a: array(C, 3) = ({}, {}, {}); // TODO: This fails because the array bound in `F` is effectively // `N.(ImplicitAs(IntLiteral).Convert)()` // which we can't deduce through. We should decide if we want to support @@ -115,8 +115,8 @@ fn G() -> i32 { // CHECK:STDERR: return F(a); // CHECK:STDERR: ^~~~ // CHECK:STDERR: fail_bound_type_mismatch.carbon:[[@LINE-12]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: fn F[N:! i32](a: [C; N]) -> i32 { return N; } - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fn F[N:! i32](a: array(C, N)) -> i32 { return N; } + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: return F(a); } @@ -181,21 +181,21 @@ fn G() -> i32 { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc6_6.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc6_6.1, runtime_param [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_24.2 (%array_type.743) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_24.2 (%array_type.743) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_29.2 (%array_type.743) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_29.2 (%array_type.743) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: %return.patt: @F.%T.loc6_6.2 (%T) = return_slot_pattern // CHECK:STDOUT: %return.param_patt: @F.%T.loc6_6.2 (%T) = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %T.ref.loc6_30: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] +// CHECK:STDOUT: %T.ref.loc6_35: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc6_24.2 (%array_type.743) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_24: type = splice_block %array_type.loc6_24.1 [symbolic = %array_type.loc6_24.2 (constants.%array_type.743)] { -// CHECK:STDOUT: %T.ref.loc6_20: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] +// CHECK:STDOUT: %a.param: @F.%array_type.loc6_29.2 (%array_type.743) = value_param runtime_param0 +// CHECK:STDOUT: %.loc6_29: type = splice_block %array_type.loc6_29.1 [symbolic = %array_type.loc6_29.2 (constants.%array_type.743)] { +// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %array_type.loc6_24.1: type = array_type %int_3, %T [symbolic = %array_type.loc6_24.2 (constants.%array_type.743)] +// CHECK:STDOUT: %array_type.loc6_29.1: type = array_type %int_3, %T [symbolic = %array_type.loc6_29.2 (constants.%array_type.743)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc6_24.2 (%array_type.743) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc6_29.2 (%array_type.743) = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref @F.%T.loc6_6.2 (%T) = out_param runtime_param1 // CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = return_slot %return.param // CHECK:STDOUT: } @@ -220,15 +220,15 @@ fn G() -> i32 { // CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) { // CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc6_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %array_type.loc6_24.2: type = array_type constants.%int_3, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_24.2 (constants.%array_type.743)] +// CHECK:STDOUT: %array_type.loc6_29.2: type = array_type constants.%int_3, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_29.2 (constants.%array_type.743)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc6_27: = require_complete_type @F.%T.loc6_6.2 (%T) [symbolic = %require_complete.loc6_27 (constants.%require_complete.4ae)] -// CHECK:STDOUT: %require_complete.loc6_17: = require_complete_type @F.%array_type.loc6_24.2 (%array_type.743) [symbolic = %require_complete.loc6_17 (constants.%require_complete.06f)] +// CHECK:STDOUT: %require_complete.loc6_32: = require_complete_type @F.%T.loc6_6.2 (%T) [symbolic = %require_complete.loc6_32 (constants.%require_complete.4ae)] +// CHECK:STDOUT: %require_complete.loc6_17: = require_complete_type @F.%array_type.loc6_29.2 (%array_type.743) [symbolic = %require_complete.loc6_17 (constants.%require_complete.06f)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type](%a.param_patt: @F.%array_type.loc6_24.2 (%array_type.743)) -> @F.%T.loc6_6.2 (%T) { +// CHECK:STDOUT: fn[%T.param_patt: type](%a.param_patt: @F.%array_type.loc6_29.2 (%array_type.743)) -> @F.%T.loc6_6.2 (%T) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_24.2 (%array_type.743) = name_ref a, %a +// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_29.2 (%array_type.743) = name_ref a, %a // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -236,12 +236,12 @@ fn G() -> i32 { // CHECK:STDOUT: %bound_method: = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_43.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_43.2: %i32 = converted %int_0, %.loc6_43.1 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_44.1: ref @F.%array_type.loc6_24.2 (%array_type.743) = value_as_ref %a.ref -// CHECK:STDOUT: %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43.2 -// CHECK:STDOUT: %.loc6_44.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_44.2 -// CHECK:STDOUT: return %.loc6_44.3 +// CHECK:STDOUT: %.loc6_48.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_48.2: %i32 = converted %int_0, %.loc6_48.1 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_49.1: ref @F.%array_type.loc6_29.2 (%array_type.743) = value_as_ref %a.ref +// CHECK:STDOUT: %.loc6_49.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_49.1, %.loc6_48.2 +// CHECK:STDOUT: %.loc6_49.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_49.2 +// CHECK:STDOUT: return %.loc6_49.3 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -252,26 +252,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc9_3.1: %array_type.002 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.002 = var a -// CHECK:STDOUT: %.loc9_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_30.1: %tuple.type = tuple_literal (%.loc9_21.1, %.loc9_25.1, %.loc9_29.1) +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_35.1: %tuple.type = tuple_literal (%.loc9_26.1, %.loc9_30.1, %.loc9_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc9_30.2: ref %C = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc9_21.2: init %C = class_init (), %.loc9_30.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.3: init %C = converted %.loc9_21.1, %.loc9_21.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.2: ref %C = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc9_26.2: init %C = class_init (), %.loc9_35.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.3: init %C = converted %.loc9_26.1, %.loc9_26.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc9_30.4: ref %C = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc9_25.2: init %C = class_init (), %.loc9_30.4 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.5: init %C = converted %.loc9_25.1, %.loc9_25.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.4: ref %C = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc9_30.2: init %C = class_init (), %.loc9_35.4 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.5: init %C = converted %.loc9_30.1, %.loc9_30.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc9_30.6: ref %C = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc9_29.2: init %C = class_init (), %.loc9_30.6 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.7: init %C = converted %.loc9_29.1, %.loc9_29.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.8: init %array_type.002 = array_init (%.loc9_30.3, %.loc9_30.5, %.loc9_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_30.1, %.loc9_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_35.6: ref %C = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc9_34.2: init %C = class_init (), %.loc9_35.6 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.7: init %C = converted %.loc9_34.1, %.loc9_34.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.8: init %array_type.002 = array_init (%.loc9_35.3, %.loc9_35.5, %.loc9_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_35.1, %.loc9_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc9_3.2 -// CHECK:STDOUT: %.loc9_15: type = splice_block %array_type [concrete = constants.%array_type.002] { +// CHECK:STDOUT: %.loc9_20: type = splice_block %array_type [concrete = constants.%array_type.002] { // CHECK:STDOUT: %C.ref.loc9: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] // CHECK:STDOUT: %array_type: type = array_type %int_3, %C [concrete = constants.%array_type.002] @@ -289,16 +289,16 @@ fn G() -> i32 { // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc6_6.2 => constants.%T // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%T -// CHECK:STDOUT: %array_type.loc6_24.2 => constants.%array_type.743 +// CHECK:STDOUT: %array_type.loc6_29.2 => constants.%array_type.743 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%C) { // CHECK:STDOUT: %T.loc6_6.2 => constants.%C // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%C -// CHECK:STDOUT: %array_type.loc6_24.2 => constants.%array_type.002 +// CHECK:STDOUT: %array_type.loc6_29.2 => constants.%array_type.002 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc6_27 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc6_32 => constants.%complete_type.357 // CHECK:STDOUT: %require_complete.loc6_17 => constants.%complete_type.dd1 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -368,8 +368,8 @@ fn G() -> i32 { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %N.patt.loc6_6.1: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)] // CHECK:STDOUT: %N.param_patt: Core.IntLiteral = value_param_pattern %N.patt.loc6_6.1, runtime_param [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_37.2 (%array_type.6a2) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_37.2 (%array_type.6a2) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_42.2 (%array_type.6a2) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_42.2 (%array_type.6a2) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { @@ -384,13 +384,13 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc6_26.3: type = converted %int_literal.make_type, %.loc6_26.2 [concrete = Core.IntLiteral] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc6_6.1: Core.IntLiteral = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc6_6.2 (constants.%N)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc6_37.2 (%array_type.6a2) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_37: type = splice_block %array_type.loc6_37.1 [symbolic = %array_type.loc6_37.2 (constants.%array_type.6a2)] { +// CHECK:STDOUT: %a.param: @F.%array_type.loc6_42.2 (%array_type.6a2) = value_param runtime_param0 +// CHECK:STDOUT: %.loc6_42: type = splice_block %array_type.loc6_42.1 [symbolic = %array_type.loc6_42.2 (constants.%array_type.6a2)] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %N.ref.loc6_36: Core.IntLiteral = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)] -// CHECK:STDOUT: %array_type.loc6_37.1: type = array_type %N.ref.loc6_36, %C [symbolic = %array_type.loc6_37.2 (constants.%array_type.6a2)] +// CHECK:STDOUT: %N.ref.loc6_41: Core.IntLiteral = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)] +// CHECK:STDOUT: %array_type.loc6_42.1: type = array_type %N.ref.loc6_41, %C [symbolic = %array_type.loc6_42.2 (constants.%array_type.6a2)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc6_37.2 (%array_type.6a2) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc6_42.2 (%array_type.6a2) = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } @@ -416,24 +416,24 @@ fn G() -> i32 { // CHECK:STDOUT: generic fn @F(%N.loc6_6.1: Core.IntLiteral) { // CHECK:STDOUT: %N.loc6_6.2: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.2 (constants.%N)] // CHECK:STDOUT: %N.patt.loc6_6.2: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt)] -// CHECK:STDOUT: %array_type.loc6_37.2: type = array_type %N.loc6_6.2, %C [symbolic = %array_type.loc6_37.2 (constants.%array_type.6a2)] +// CHECK:STDOUT: %array_type.loc6_42.2: type = array_type %N.loc6_6.2, %C [symbolic = %array_type.loc6_42.2 (constants.%array_type.6a2)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_37.2 (%array_type.6a2) [symbolic = %require_complete (constants.%require_complete.d82)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_42.2 (%array_type.6a2) [symbolic = %require_complete (constants.%require_complete.d82)] // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc6_6.2, constants.%Convert.956 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.2(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn.122)] -// CHECK:STDOUT: %int.convert_checked.loc6_57.2: init %i32 = call %Convert.specific_fn(%N.loc6_6.2) [symbolic = %int.convert_checked.loc6_57.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %int.convert_checked.loc6_62.2: init %i32 = call %Convert.specific_fn(%N.loc6_6.2) [symbolic = %int.convert_checked.loc6_62.2 (constants.%int.convert_checked)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc6_37.2 (%array_type.6a2)) -> %i32 { +// CHECK:STDOUT: fn[%N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc6_42.2 (%array_type.6a2)) -> %i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc6_56: Core.IntLiteral = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)] +// CHECK:STDOUT: %N.ref.loc6_61: Core.IntLiteral = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N)] // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc6_56, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] +// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc6_61, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn.122)] -// CHECK:STDOUT: %int.convert_checked.loc6_57.1: init %i32 = call %specific_fn(%N.ref.loc6_56) [symbolic = %int.convert_checked.loc6_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc6_57.1: %i32 = value_of_initializer %int.convert_checked.loc6_57.1 [symbolic = %int.convert_checked.loc6_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc6_57.2: %i32 = converted %N.ref.loc6_56, %.loc6_57.1 [symbolic = %int.convert_checked.loc6_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: return %.loc6_57.2 +// CHECK:STDOUT: %int.convert_checked.loc6_62.1: init %i32 = call %specific_fn(%N.ref.loc6_61) [symbolic = %int.convert_checked.loc6_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc6_62.1: %i32 = value_of_initializer %int.convert_checked.loc6_62.1 [symbolic = %int.convert_checked.loc6_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc6_62.2: %i32 = converted %N.ref.loc6_61, %.loc6_62.1 [symbolic = %int.convert_checked.loc6_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: return %.loc6_62.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -444,26 +444,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc9_3.1: %array_type.002 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.002 = var a -// CHECK:STDOUT: %.loc9_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_30.1: %tuple.type = tuple_literal (%.loc9_21.1, %.loc9_25.1, %.loc9_29.1) +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_35.1: %tuple.type = tuple_literal (%.loc9_26.1, %.loc9_30.1, %.loc9_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc9_30.2: ref %C = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc9_21.2: init %C = class_init (), %.loc9_30.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.3: init %C = converted %.loc9_21.1, %.loc9_21.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.2: ref %C = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc9_26.2: init %C = class_init (), %.loc9_35.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.3: init %C = converted %.loc9_26.1, %.loc9_26.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc9_30.4: ref %C = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc9_25.2: init %C = class_init (), %.loc9_30.4 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.5: init %C = converted %.loc9_25.1, %.loc9_25.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.4: ref %C = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc9_30.2: init %C = class_init (), %.loc9_35.4 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.5: init %C = converted %.loc9_30.1, %.loc9_30.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc9_30.6: ref %C = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc9_29.2: init %C = class_init (), %.loc9_30.6 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.7: init %C = converted %.loc9_29.1, %.loc9_29.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.8: init %array_type.002 = array_init (%.loc9_30.3, %.loc9_30.5, %.loc9_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_30.1, %.loc9_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_35.6: ref %C = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc9_34.2: init %C = class_init (), %.loc9_35.6 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.7: init %C = converted %.loc9_34.1, %.loc9_34.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.8: init %array_type.002 = array_init (%.loc9_35.3, %.loc9_35.5, %.loc9_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_35.1, %.loc9_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc9_3.2 -// CHECK:STDOUT: %.loc9_15: type = splice_block %array_type [concrete = constants.%array_type.002] { +// CHECK:STDOUT: %.loc9_20: type = splice_block %array_type [concrete = constants.%array_type.002] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %array_type: type = array_type %int_3, %C [concrete = constants.%array_type.002] @@ -482,19 +482,19 @@ fn G() -> i32 { // CHECK:STDOUT: specific @F(constants.%N) { // CHECK:STDOUT: %N.loc6_6.2 => constants.%N // CHECK:STDOUT: %N.patt.loc6_6.2 => constants.%N -// CHECK:STDOUT: %array_type.loc6_37.2 => constants.%array_type.6a2 +// CHECK:STDOUT: %array_type.loc6_42.2 => constants.%array_type.6a2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%int_3.1ba) { // CHECK:STDOUT: %N.loc6_6.2 => constants.%int_3.1ba // CHECK:STDOUT: %N.patt.loc6_6.2 => constants.%int_3.1ba -// CHECK:STDOUT: %array_type.loc6_37.2 => constants.%array_type.002 +// CHECK:STDOUT: %array_type.loc6_42.2 => constants.%array_type.002 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type.dd1 // CHECK:STDOUT: %Convert.bound => constants.%Convert.bound.b30 // CHECK:STDOUT: %Convert.specific_fn => constants.%Convert.specific_fn.b42 -// CHECK:STDOUT: %int.convert_checked.loc6_57.2 => constants.%int_3.822 +// CHECK:STDOUT: %int.convert_checked.loc6_62.2 => constants.%int_3.822 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- type_and_bound.carbon @@ -551,8 +551,8 @@ fn G() -> i32 { // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc6_6.1, runtime_param [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] // CHECK:STDOUT: %N.patt.loc6_16.1: Core.IntLiteral = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc6_16.2 (constants.%N.patt)] // CHECK:STDOUT: %N.param_patt: Core.IntLiteral = value_param_pattern %N.patt.loc6_16.1, runtime_param [symbolic = %N.patt.loc6_16.2 (constants.%N.patt)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_47.2 (%array_type.bb5) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_47.2 (%array_type.bb5) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_52.2 (%array_type.bb5) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_52.2 (%array_type.bb5) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)] @@ -565,13 +565,13 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc6_36.3: type = converted %int_literal.make_type, %.loc6_36.2 [concrete = Core.IntLiteral] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc6_16.1: Core.IntLiteral = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc6_16.2 (constants.%N)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc6_47.2 (%array_type.bb5) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_47: type = splice_block %array_type.loc6_47.1 [symbolic = %array_type.loc6_47.2 (constants.%array_type.bb5)] { +// CHECK:STDOUT: %a.param: @F.%array_type.loc6_52.2 (%array_type.bb5) = value_param runtime_param0 +// CHECK:STDOUT: %.loc6_52: type = splice_block %array_type.loc6_52.1 [symbolic = %array_type.loc6_52.2 (constants.%array_type.bb5)] { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %N.ref: Core.IntLiteral = name_ref N, %N.loc6_16.1 [symbolic = %N.loc6_16.2 (constants.%N)] -// CHECK:STDOUT: %array_type.loc6_47.1: type = array_type %N.ref, %T [symbolic = %array_type.loc6_47.2 (constants.%array_type.bb5)] +// CHECK:STDOUT: %array_type.loc6_52.1: type = array_type %N.ref, %T [symbolic = %array_type.loc6_52.2 (constants.%array_type.bb5)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc6_47.2 (%array_type.bb5) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc6_52.2 (%array_type.bb5) = bind_name a, %a.param // CHECK:STDOUT: } // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } @@ -589,12 +589,12 @@ fn G() -> i32 { // CHECK:STDOUT: %T.patt.loc6_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] // CHECK:STDOUT: %N.loc6_16.2: Core.IntLiteral = bind_symbolic_name N, 1 [symbolic = %N.loc6_16.2 (constants.%N)] // CHECK:STDOUT: %N.patt.loc6_16.2: Core.IntLiteral = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc6_16.2 (constants.%N.patt)] -// CHECK:STDOUT: %array_type.loc6_47.2: type = array_type %N.loc6_16.2, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_47.2 (constants.%array_type.bb5)] +// CHECK:STDOUT: %array_type.loc6_52.2: type = array_type %N.loc6_16.2, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_52.2 (constants.%array_type.bb5)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_47.2 (%array_type.bb5) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_52.2 (%array_type.bb5) [symbolic = %require_complete (constants.%require_complete)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type, %N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc6_47.2 (%array_type.bb5)) { +// CHECK:STDOUT: fn[%T.param_patt: type, %N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc6_52.2 (%array_type.bb5)) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -607,26 +607,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc9_3.1: %array_type.002 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.002 = var a -// CHECK:STDOUT: %.loc9_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_30.1: %tuple.type = tuple_literal (%.loc9_21.1, %.loc9_25.1, %.loc9_29.1) +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_35.1: %tuple.type = tuple_literal (%.loc9_26.1, %.loc9_30.1, %.loc9_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc9_30.2: ref %C = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc9_21.2: init %C = class_init (), %.loc9_30.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.3: init %C = converted %.loc9_21.1, %.loc9_21.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.2: ref %C = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc9_26.2: init %C = class_init (), %.loc9_35.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.3: init %C = converted %.loc9_26.1, %.loc9_26.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc9_30.4: ref %C = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc9_25.2: init %C = class_init (), %.loc9_30.4 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.5: init %C = converted %.loc9_25.1, %.loc9_25.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.4: ref %C = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc9_30.2: init %C = class_init (), %.loc9_35.4 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.5: init %C = converted %.loc9_30.1, %.loc9_30.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc9_30.6: ref %C = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc9_29.2: init %C = class_init (), %.loc9_30.6 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.7: init %C = converted %.loc9_29.1, %.loc9_29.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.8: init %array_type.002 = array_init (%.loc9_30.3, %.loc9_30.5, %.loc9_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_30.1, %.loc9_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_35.6: ref %C = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc9_34.2: init %C = class_init (), %.loc9_35.6 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.7: init %C = converted %.loc9_34.1, %.loc9_34.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.8: init %array_type.002 = array_init (%.loc9_35.3, %.loc9_35.5, %.loc9_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_35.1, %.loc9_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc9_3.2 -// CHECK:STDOUT: %.loc9_15: type = splice_block %array_type [concrete = constants.%array_type.002] { +// CHECK:STDOUT: %.loc9_20: type = splice_block %array_type [concrete = constants.%array_type.002] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] // CHECK:STDOUT: %array_type: type = array_type %int_3, %C [concrete = constants.%array_type.002] @@ -645,7 +645,7 @@ fn G() -> i32 { // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%T // CHECK:STDOUT: %N.loc6_16.2 => constants.%N // CHECK:STDOUT: %N.patt.loc6_16.2 => constants.%N -// CHECK:STDOUT: %array_type.loc6_47.2 => constants.%array_type.bb5 +// CHECK:STDOUT: %array_type.loc6_52.2 => constants.%array_type.bb5 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%C, constants.%int_3) { @@ -653,7 +653,7 @@ fn G() -> i32 { // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%C // CHECK:STDOUT: %N.loc6_16.2 => constants.%int_3 // CHECK:STDOUT: %N.patt.loc6_16.2 => constants.%int_3 -// CHECK:STDOUT: %array_type.loc6_47.2 => constants.%array_type.002 +// CHECK:STDOUT: %array_type.loc6_52.2 => constants.%array_type.002 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type.dd1 @@ -720,21 +720,21 @@ fn G() -> i32 { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc6_6.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc6_6.1, runtime_param [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_24.2 (%array_type.9d4) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_24.2 (%array_type.9d4) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_29.2 (%array_type.9d4) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_29.2 (%array_type.9d4) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: %return.patt: @F.%T.loc6_6.2 (%T) = return_slot_pattern // CHECK:STDOUT: %return.param_patt: @F.%T.loc6_6.2 (%T) = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %T.ref.loc6_30: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] +// CHECK:STDOUT: %T.ref.loc6_35: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc6_24.2 (%array_type.9d4) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_24: type = splice_block %array_type.loc6_24.1 [symbolic = %array_type.loc6_24.2 (constants.%array_type.9d4)] { -// CHECK:STDOUT: %T.ref.loc6_20: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] +// CHECK:STDOUT: %a.param: @F.%array_type.loc6_29.2 (%array_type.9d4) = value_param runtime_param0 +// CHECK:STDOUT: %.loc6_29: type = splice_block %array_type.loc6_29.1 [symbolic = %array_type.loc6_29.2 (constants.%array_type.9d4)] { +// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %array_type.loc6_24.1: type = array_type %int_2, %T [symbolic = %array_type.loc6_24.2 (constants.%array_type.9d4)] +// CHECK:STDOUT: %array_type.loc6_29.1: type = array_type %int_2, %T [symbolic = %array_type.loc6_29.2 (constants.%array_type.9d4)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc6_24.2 (%array_type.9d4) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc6_29.2 (%array_type.9d4) = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref @F.%T.loc6_6.2 (%T) = out_param runtime_param1 // CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = return_slot %return.param // CHECK:STDOUT: } @@ -759,15 +759,15 @@ fn G() -> i32 { // CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) { // CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc6_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %array_type.loc6_24.2: type = array_type constants.%int_2, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_24.2 (constants.%array_type.9d4)] +// CHECK:STDOUT: %array_type.loc6_29.2: type = array_type constants.%int_2, @F.%T.loc6_6.2 (%T) [symbolic = %array_type.loc6_29.2 (constants.%array_type.9d4)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc6_27: = require_complete_type @F.%T.loc6_6.2 (%T) [symbolic = %require_complete.loc6_27 (constants.%require_complete.4ae)] -// CHECK:STDOUT: %require_complete.loc6_17: = require_complete_type @F.%array_type.loc6_24.2 (%array_type.9d4) [symbolic = %require_complete.loc6_17 (constants.%require_complete.d11)] +// CHECK:STDOUT: %require_complete.loc6_32: = require_complete_type @F.%T.loc6_6.2 (%T) [symbolic = %require_complete.loc6_32 (constants.%require_complete.4ae)] +// CHECK:STDOUT: %require_complete.loc6_17: = require_complete_type @F.%array_type.loc6_29.2 (%array_type.9d4) [symbolic = %require_complete.loc6_17 (constants.%require_complete.d11)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type](%a.param_patt: @F.%array_type.loc6_24.2 (%array_type.9d4)) -> @F.%T.loc6_6.2 (%T) { +// CHECK:STDOUT: fn[%T.param_patt: type](%a.param_patt: @F.%array_type.loc6_29.2 (%array_type.9d4)) -> @F.%T.loc6_6.2 (%T) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_24.2 (%array_type.9d4) = name_ref a, %a +// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_29.2 (%array_type.9d4) = name_ref a, %a // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -775,12 +775,12 @@ fn G() -> i32 { // CHECK:STDOUT: %bound_method: = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_43.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_43.2: %i32 = converted %int_0, %.loc6_43.1 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc6_44.1: ref @F.%array_type.loc6_24.2 (%array_type.9d4) = value_as_ref %a.ref -// CHECK:STDOUT: %.loc6_44.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_44.1, %.loc6_43.2 -// CHECK:STDOUT: %.loc6_44.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_44.2 -// CHECK:STDOUT: return %.loc6_44.3 +// CHECK:STDOUT: %.loc6_48.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_48.2: %i32 = converted %int_0, %.loc6_48.1 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_49.1: ref @F.%array_type.loc6_29.2 (%array_type.9d4) = value_as_ref %a.ref +// CHECK:STDOUT: %.loc6_49.2: ref @F.%T.loc6_6.2 (%T) = array_index %.loc6_49.1, %.loc6_48.2 +// CHECK:STDOUT: %.loc6_49.3: @F.%T.loc6_6.2 (%T) = bind_value %.loc6_49.2 +// CHECK:STDOUT: return %.loc6_49.3 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -791,26 +791,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc10_3.1: %array_type.002 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.002 = var a -// CHECK:STDOUT: %.loc10_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc10_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc10_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc10_30.1: %tuple.type = tuple_literal (%.loc10_21.1, %.loc10_25.1, %.loc10_29.1) +// CHECK:STDOUT: %.loc10_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc10_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc10_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc10_35.1: %tuple.type = tuple_literal (%.loc10_26.1, %.loc10_30.1, %.loc10_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc10_30.2: ref %C = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc10_21.2: init %C = class_init (), %.loc10_30.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc10_30.3: init %C = converted %.loc10_21.1, %.loc10_21.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.2: ref %C = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc10_26.2: init %C = class_init (), %.loc10_35.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.3: init %C = converted %.loc10_26.1, %.loc10_26.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc10_30.4: ref %C = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc10_25.2: init %C = class_init (), %.loc10_30.4 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc10_30.5: init %C = converted %.loc10_25.1, %.loc10_25.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.4: ref %C = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc10_30.2: init %C = class_init (), %.loc10_35.4 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.5: init %C = converted %.loc10_30.1, %.loc10_30.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc10_30.6: ref %C = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc10_29.2: init %C = class_init (), %.loc10_30.6 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc10_30.7: init %C = converted %.loc10_29.1, %.loc10_29.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc10_30.8: init %array_type.002 = array_init (%.loc10_30.3, %.loc10_30.5, %.loc10_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc10_3.2: init %array_type.002 = converted %.loc10_30.1, %.loc10_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc10_35.6: ref %C = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc10_34.2: init %C = class_init (), %.loc10_35.6 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.7: init %C = converted %.loc10_34.1, %.loc10_34.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc10_35.8: init %array_type.002 = array_init (%.loc10_35.3, %.loc10_35.5, %.loc10_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc10_3.2: init %array_type.002 = converted %.loc10_35.1, %.loc10_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc10_3.2 -// CHECK:STDOUT: %.loc10_15: type = splice_block %array_type [concrete = constants.%array_type.002] { +// CHECK:STDOUT: %.loc10_20: type = splice_block %array_type [concrete = constants.%array_type.002] { // CHECK:STDOUT: %C.ref.loc10: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] // CHECK:STDOUT: %array_type: type = array_type %int_3, %C [concrete = constants.%array_type.002] @@ -828,16 +828,16 @@ fn G() -> i32 { // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc6_6.2 => constants.%T // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%T -// CHECK:STDOUT: %array_type.loc6_24.2 => constants.%array_type.9d4 +// CHECK:STDOUT: %array_type.loc6_29.2 => constants.%array_type.9d4 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%C) { // CHECK:STDOUT: %T.loc6_6.2 => constants.%C // CHECK:STDOUT: %T.patt.loc6_6.2 => constants.%C -// CHECK:STDOUT: %array_type.loc6_24.2 => constants.%array_type.15a +// CHECK:STDOUT: %array_type.loc6_29.2 => constants.%array_type.15a // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc6_27 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc6_32 => constants.%complete_type.357 // CHECK:STDOUT: %require_complete.loc6_17 => constants.%complete_type.8eb // CHECK:STDOUT: } // CHECK:STDOUT: @@ -911,8 +911,8 @@ fn G() -> i32 { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %N.patt.loc7_6.1: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc7_6.2 (constants.%N.patt)] // CHECK:STDOUT: %N.param_patt: Core.IntLiteral = value_param_pattern %N.patt.loc7_6.1, runtime_param [symbolic = %N.patt.loc7_6.2 (constants.%N.patt)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc7_37.2 (%array_type.6a2) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc7_37.2 (%array_type.6a2) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc7_42.2 (%array_type.6a2) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc7_42.2 (%array_type.6a2) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { @@ -927,13 +927,13 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc7_26.3: type = converted %int_literal.make_type, %.loc7_26.2 [concrete = Core.IntLiteral] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc7_6.1: Core.IntLiteral = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc7_6.2 (constants.%N)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc7_37.2 (%array_type.6a2) = value_param runtime_param0 -// CHECK:STDOUT: %.loc7_37: type = splice_block %array_type.loc7_37.1 [symbolic = %array_type.loc7_37.2 (constants.%array_type.6a2)] { +// CHECK:STDOUT: %a.param: @F.%array_type.loc7_42.2 (%array_type.6a2) = value_param runtime_param0 +// CHECK:STDOUT: %.loc7_42: type = splice_block %array_type.loc7_42.1 [symbolic = %array_type.loc7_42.2 (constants.%array_type.6a2)] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %N.ref.loc7_36: Core.IntLiteral = name_ref N, %N.loc7_6.1 [symbolic = %N.loc7_6.2 (constants.%N)] -// CHECK:STDOUT: %array_type.loc7_37.1: type = array_type %N.ref.loc7_36, %C [symbolic = %array_type.loc7_37.2 (constants.%array_type.6a2)] +// CHECK:STDOUT: %N.ref.loc7_41: Core.IntLiteral = name_ref N, %N.loc7_6.1 [symbolic = %N.loc7_6.2 (constants.%N)] +// CHECK:STDOUT: %array_type.loc7_42.1: type = array_type %N.ref.loc7_41, %C [symbolic = %array_type.loc7_42.2 (constants.%array_type.6a2)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc7_37.2 (%array_type.6a2) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc7_42.2 (%array_type.6a2) = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } @@ -967,24 +967,24 @@ fn G() -> i32 { // CHECK:STDOUT: generic fn @F(%N.loc7_6.1: Core.IntLiteral) { // CHECK:STDOUT: %N.loc7_6.2: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc7_6.2 (constants.%N)] // CHECK:STDOUT: %N.patt.loc7_6.2: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc7_6.2 (constants.%N.patt)] -// CHECK:STDOUT: %array_type.loc7_37.2: type = array_type %N.loc7_6.2, %C [symbolic = %array_type.loc7_37.2 (constants.%array_type.6a2)] +// CHECK:STDOUT: %array_type.loc7_42.2: type = array_type %N.loc7_6.2, %C [symbolic = %array_type.loc7_42.2 (constants.%array_type.6a2)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc7_37.2 (%array_type.6a2) [symbolic = %require_complete (constants.%require_complete.d82)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc7_42.2 (%array_type.6a2) [symbolic = %require_complete (constants.%require_complete.d82)] // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc7_6.2, constants.%Convert.956 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.2(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn.122)] -// CHECK:STDOUT: %int.convert_checked.loc7_57.2: init %i32 = call %Convert.specific_fn(%N.loc7_6.2) [symbolic = %int.convert_checked.loc7_57.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %int.convert_checked.loc7_62.2: init %i32 = call %Convert.specific_fn(%N.loc7_6.2) [symbolic = %int.convert_checked.loc7_62.2 (constants.%int.convert_checked)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc7_37.2 (%array_type.6a2)) -> %i32 { +// CHECK:STDOUT: fn[%N.param_patt: Core.IntLiteral](%a.param_patt: @F.%array_type.loc7_42.2 (%array_type.6a2)) -> %i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc7_56: Core.IntLiteral = name_ref N, %N.loc7_6.1 [symbolic = %N.loc7_6.2 (constants.%N)] +// CHECK:STDOUT: %N.ref.loc7_61: Core.IntLiteral = name_ref N, %N.loc7_6.1 [symbolic = %N.loc7_6.2 (constants.%N)] // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc7_56, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] +// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc7_61, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound.41f)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn.122)] -// CHECK:STDOUT: %int.convert_checked.loc7_57.1: init %i32 = call %specific_fn(%N.ref.loc7_56) [symbolic = %int.convert_checked.loc7_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc7_57.1: %i32 = value_of_initializer %int.convert_checked.loc7_57.1 [symbolic = %int.convert_checked.loc7_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc7_57.2: %i32 = converted %N.ref.loc7_56, %.loc7_57.1 [symbolic = %int.convert_checked.loc7_57.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: return %.loc7_57.2 +// CHECK:STDOUT: %int.convert_checked.loc7_62.1: init %i32 = call %specific_fn(%N.ref.loc7_61) [symbolic = %int.convert_checked.loc7_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc7_62.1: %i32 = value_of_initializer %int.convert_checked.loc7_62.1 [symbolic = %int.convert_checked.loc7_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc7_62.2: %i32 = converted %N.ref.loc7_61, %.loc7_62.1 [symbolic = %int.convert_checked.loc7_62.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: return %.loc7_62.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -995,26 +995,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc11_3.1: %array_type.fe4 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.fe4 = var a -// CHECK:STDOUT: %.loc11_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc11_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc11_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc11_30.1: %tuple.type = tuple_literal (%.loc11_21.1, %.loc11_25.1, %.loc11_29.1) +// CHECK:STDOUT: %.loc11_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_35.1: %tuple.type = tuple_literal (%.loc11_26.1, %.loc11_30.1, %.loc11_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_30.2: ref %D = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc11_21.2: init %D = class_init (), %.loc11_30.2 [concrete = constants.%D.val] -// CHECK:STDOUT: %.loc11_30.3: init %D = converted %.loc11_21.1, %.loc11_21.2 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.2: ref %D = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc11_26.2: init %D = class_init (), %.loc11_35.2 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.3: init %D = converted %.loc11_26.1, %.loc11_26.2 [concrete = constants.%D.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc11_30.4: ref %D = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc11_25.2: init %D = class_init (), %.loc11_30.4 [concrete = constants.%D.val] -// CHECK:STDOUT: %.loc11_30.5: init %D = converted %.loc11_25.1, %.loc11_25.2 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.4: ref %D = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc11_30.2: init %D = class_init (), %.loc11_35.4 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.5: init %D = converted %.loc11_30.1, %.loc11_30.2 [concrete = constants.%D.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc11_30.6: ref %D = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc11_29.2: init %D = class_init (), %.loc11_30.6 [concrete = constants.%D.val] -// CHECK:STDOUT: %.loc11_30.7: init %D = converted %.loc11_29.1, %.loc11_29.2 [concrete = constants.%D.val] -// CHECK:STDOUT: %.loc11_30.8: init %array_type.fe4 = array_init (%.loc11_30.3, %.loc11_30.5, %.loc11_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_3.2: init %array_type.fe4 = converted %.loc11_30.1, %.loc11_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_35.6: ref %D = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc11_34.2: init %D = class_init (), %.loc11_35.6 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.7: init %D = converted %.loc11_34.1, %.loc11_34.2 [concrete = constants.%D.val] +// CHECK:STDOUT: %.loc11_35.8: init %array_type.fe4 = array_init (%.loc11_35.3, %.loc11_35.5, %.loc11_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_3.2: init %array_type.fe4 = converted %.loc11_35.1, %.loc11_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc11_3.2 -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type.fe4] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type.fe4] { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %array_type: type = array_type %int_3, %D [concrete = constants.%array_type.fe4] @@ -1033,19 +1033,19 @@ fn G() -> i32 { // CHECK:STDOUT: specific @F(constants.%N) { // CHECK:STDOUT: %N.loc7_6.2 => constants.%N // CHECK:STDOUT: %N.patt.loc7_6.2 => constants.%N -// CHECK:STDOUT: %array_type.loc7_37.2 => constants.%array_type.6a2 +// CHECK:STDOUT: %array_type.loc7_42.2 => constants.%array_type.6a2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%int_3.1ba) { // CHECK:STDOUT: %N.loc7_6.2 => constants.%int_3.1ba // CHECK:STDOUT: %N.patt.loc7_6.2 => constants.%int_3.1ba -// CHECK:STDOUT: %array_type.loc7_37.2 => constants.%array_type.002 +// CHECK:STDOUT: %array_type.loc7_42.2 => constants.%array_type.002 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type.dd1 // CHECK:STDOUT: %Convert.bound => constants.%Convert.bound.b30 // CHECK:STDOUT: %Convert.specific_fn => constants.%Convert.specific_fn.b42 -// CHECK:STDOUT: %int.convert_checked.loc7_57.2 => constants.%int_3.822 +// CHECK:STDOUT: %int.convert_checked.loc7_62.2 => constants.%int_3.822 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_bound_type_mismatch.carbon @@ -1105,32 +1105,32 @@ fn G() -> i32 { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %N.patt.loc6_6.1: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.8e2)] // CHECK:STDOUT: %N.param_patt: %i32 = value_param_pattern %N.patt.loc6_6.1, runtime_param [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.8e2)] -// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_23.2 (%array_type.c13) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_23.2 (%array_type.c13) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%array_type.loc6_28.2 (%array_type.c13) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%array_type.loc6_28.2 (%array_type.c13) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %int_32.loc6_29: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc6_29: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc6_34: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc6_34: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.param: %i32 = value_param runtime_param // CHECK:STDOUT: %.loc6_10: type = splice_block %i32.loc6_10 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32.loc6_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc6_6.1: %i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc6_6.2 (constants.%N.51e)] -// CHECK:STDOUT: %a.param: @F.%array_type.loc6_23.2 (%array_type.c13) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_23: type = splice_block %array_type.loc6_23.1 [symbolic = %array_type.loc6_23.2 (constants.%array_type.c13)] { +// CHECK:STDOUT: %a.param: @F.%array_type.loc6_28.2 (%array_type.c13) = value_param runtime_param0 +// CHECK:STDOUT: %.loc6_28: type = splice_block %array_type.loc6_28.1 [symbolic = %array_type.loc6_28.2 (constants.%array_type.c13)] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %N.ref.loc6_22: %i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.51e)] +// CHECK:STDOUT: %N.ref.loc6_27: %i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.51e)] // CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] -// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc6_22, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)] +// CHECK:STDOUT: %bound_method: = bound_method %N.ref.loc6_27, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc6_22.1: init Core.IntLiteral = call %specific_fn(%N.ref.loc6_22) [symbolic = %int.convert_checked.loc6_22.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc6_22.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc6_22.1 [symbolic = %int.convert_checked.loc6_22.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc6_22.2: Core.IntLiteral = converted %N.ref.loc6_22, %.loc6_22.1 [symbolic = %int.convert_checked.loc6_22.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc6_23.1: type = array_type %.loc6_22.2, %C [symbolic = %array_type.loc6_23.2 (constants.%array_type.c13)] +// CHECK:STDOUT: %int.convert_checked.loc6_27.1: init Core.IntLiteral = call %specific_fn(%N.ref.loc6_27) [symbolic = %int.convert_checked.loc6_27.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc6_27.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc6_27.1 [symbolic = %int.convert_checked.loc6_27.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc6_27.2: Core.IntLiteral = converted %N.ref.loc6_27, %.loc6_27.1 [symbolic = %int.convert_checked.loc6_27.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc6_28.1: type = array_type %.loc6_27.2, %C [symbolic = %array_type.loc6_28.2 (constants.%array_type.c13)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%array_type.loc6_23.2 (%array_type.c13) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%array_type.loc6_28.2 (%array_type.c13) = bind_name a, %a.param // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } @@ -1158,16 +1158,16 @@ fn G() -> i32 { // CHECK:STDOUT: %N.patt.loc6_6.2: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_6.2 (constants.%N.patt.8e2)] // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc6_6.2, constants.%Convert.960 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc6_22.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc6_6.2) [symbolic = %int.convert_checked.loc6_22.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc6_23.2: type = array_type %int.convert_checked.loc6_22.2, %C [symbolic = %array_type.loc6_23.2 (constants.%array_type.c13)] +// CHECK:STDOUT: %int.convert_checked.loc6_27.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc6_6.2) [symbolic = %int.convert_checked.loc6_27.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc6_28.2: type = array_type %int.convert_checked.loc6_27.2, %C [symbolic = %array_type.loc6_28.2 (constants.%array_type.c13)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_23.2 (%array_type.c13) [symbolic = %require_complete (constants.%require_complete.303)] +// CHECK:STDOUT: %require_complete: = require_complete_type @F.%array_type.loc6_28.2 (%array_type.c13) [symbolic = %require_complete (constants.%require_complete.303)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%N.param_patt: %i32](%a.param_patt: @F.%array_type.loc6_23.2 (%array_type.c13)) -> %i32 { +// CHECK:STDOUT: fn[%N.param_patt: %i32](%a.param_patt: @F.%array_type.loc6_28.2 (%array_type.c13)) -> %i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc6_42: %i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.51e)] -// CHECK:STDOUT: return %N.ref.loc6_42 +// CHECK:STDOUT: %N.ref.loc6_47: %i32 = name_ref N, %N.loc6_6.1 [symbolic = %N.loc6_6.2 (constants.%N.51e)] +// CHECK:STDOUT: return %N.ref.loc6_47 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1178,26 +1178,26 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc9_3.1: %array_type.002 = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type.002 = var a -// CHECK:STDOUT: %.loc9_21.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_25.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_29.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_30.1: %tuple.type = tuple_literal (%.loc9_21.1, %.loc9_25.1, %.loc9_29.1) +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_30.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_34.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_35.1: %tuple.type = tuple_literal (%.loc9_26.1, %.loc9_30.1, %.loc9_34.1) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc9_30.2: ref %C = array_index %a.var, %int_0 -// CHECK:STDOUT: %.loc9_21.2: init %C = class_init (), %.loc9_30.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.3: init %C = converted %.loc9_21.1, %.loc9_21.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.2: ref %C = array_index %a.var, %int_0 +// CHECK:STDOUT: %.loc9_26.2: init %C = class_init (), %.loc9_35.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.3: init %C = converted %.loc9_26.1, %.loc9_26.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc9_30.4: ref %C = array_index %a.var, %int_1 -// CHECK:STDOUT: %.loc9_25.2: init %C = class_init (), %.loc9_30.4 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.5: init %C = converted %.loc9_25.1, %.loc9_25.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.4: ref %C = array_index %a.var, %int_1 +// CHECK:STDOUT: %.loc9_30.2: init %C = class_init (), %.loc9_35.4 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.5: init %C = converted %.loc9_30.1, %.loc9_30.2 [concrete = constants.%C.val] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc9_30.6: ref %C = array_index %a.var, %int_2 -// CHECK:STDOUT: %.loc9_29.2: init %C = class_init (), %.loc9_30.6 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.7: init %C = converted %.loc9_29.1, %.loc9_29.2 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_30.8: init %array_type.002 = array_init (%.loc9_30.3, %.loc9_30.5, %.loc9_30.7) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_30.1, %.loc9_30.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_35.6: ref %C = array_index %a.var, %int_2 +// CHECK:STDOUT: %.loc9_34.2: init %C = class_init (), %.loc9_35.6 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.7: init %C = converted %.loc9_34.1, %.loc9_34.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc9_35.8: init %array_type.002 = array_init (%.loc9_35.3, %.loc9_35.5, %.loc9_35.7) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc9_3.2: init %array_type.002 = converted %.loc9_35.1, %.loc9_35.8 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc9_3.2 -// CHECK:STDOUT: %.loc9_15: type = splice_block %array_type [concrete = constants.%array_type.002] { +// CHECK:STDOUT: %.loc9_20: type = splice_block %array_type [concrete = constants.%array_type.002] { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] // CHECK:STDOUT: %array_type: type = array_type %int_3, %C [concrete = constants.%array_type.002] @@ -1213,7 +1213,7 @@ fn G() -> i32 { // CHECK:STDOUT: %N.patt.loc6_6.2 => constants.%N.51e // CHECK:STDOUT: %Convert.bound => constants.%Convert.bound // CHECK:STDOUT: %Convert.specific_fn => constants.%Convert.specific_fn -// CHECK:STDOUT: %int.convert_checked.loc6_22.2 => constants.%int.convert_checked -// CHECK:STDOUT: %array_type.loc6_23.2 => constants.%array_type.c13 +// CHECK:STDOUT: %int.convert_checked.loc6_27.2 => constants.%int.convert_checked +// CHECK:STDOUT: %array_type.loc6_28.2 => constants.%array_type.c13 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/eval/aggregate.carbon b/toolchain/check/testdata/eval/aggregate.carbon index 10501d7b1296c..bfda06f3a8866 100644 --- a/toolchain/check/testdata/eval/aggregate.carbon +++ b/toolchain/check/testdata/eval/aggregate.carbon @@ -12,9 +12,9 @@ var tuple_copy: (i32, i32) = (1, 2) as (i32, i32); var struct_copy: {.a: i32, .b: i32, .c: i32} = {.c = 3, .b = 2, .a = 1} as {.b: i32, .a: i32, .c: i32}; -var tuple_index: [i32; 1] = (0,) as [i32; (5, 7, 1, 9).2]; +var tuple_index: array(i32, 1) = (0,) as array(i32, (5, 7, 1, 9).2); -var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b]; +var struct_access: array(i32, 1) = (0,) as array(i32, {.a = 3, .b = 1}.b); // CHECK:STDOUT: --- aggregate.carbon // CHECK:STDOUT: @@ -117,7 +117,7 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b]; // CHECK:STDOUT: %.loc15_1: %array_type = var_pattern %tuple_index.patt // CHECK:STDOUT: } // CHECK:STDOUT: %tuple_index.var: ref %array_type = var tuple_index -// CHECK:STDOUT: %.loc15_25: type = splice_block %array_type.loc15 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc15_30: type = splice_block %array_type.loc15 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1.loc15: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -129,7 +129,7 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b]; // CHECK:STDOUT: %.loc17_1: %array_type = var_pattern %struct_access.patt // CHECK:STDOUT: } // CHECK:STDOUT: %struct_access.var: ref %array_type = var struct_access -// CHECK:STDOUT: %.loc17_27: type = splice_block %array_type.loc17 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc17_32: type = splice_block %array_type.loc17 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1.loc17: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -215,55 +215,55 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b]; // CHECK:STDOUT: %.loc13_73.11: init %struct_type.a.b.c = struct_init (%.loc13_73.4, %.loc13_73.7, %.loc13_73.10) to file.%struct_copy.var [concrete = constants.%struct.cff] // CHECK:STDOUT: %.loc13_1: init %struct_type.a.b.c = converted %.loc13_73.1, %.loc13_73.11 [concrete = constants.%struct.cff] // CHECK:STDOUT: assign file.%struct_copy.var, %.loc13_1 -// CHECK:STDOUT: %int_0.loc15_30: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc15_32.1: %tuple.type.985 = tuple_literal (%int_0.loc15_30) +// CHECK:STDOUT: %int_0.loc15_35: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc15_37.1: %tuple.type.985 = tuple_literal (%int_0.loc15_35) // CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5] // CHECK:STDOUT: %int_7: Core.IntLiteral = int_value 7 [concrete = constants.%int_7] // CHECK:STDOUT: %int_1.loc15: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9] -// CHECK:STDOUT: %.loc15_54.1: %tuple.type.d46 = tuple_literal (%int_5, %int_7, %int_1.loc15, %int_9) +// CHECK:STDOUT: %.loc15_64.1: %tuple.type.d46 = tuple_literal (%int_5, %int_7, %int_1.loc15, %int_9) // CHECK:STDOUT: %int_2.loc15: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %tuple.loc15: %tuple.type.d46 = tuple_value (%int_5, %int_7, %int_1.loc15, %int_9) [concrete = constants.%tuple.869] -// CHECK:STDOUT: %.loc15_54.2: %tuple.type.d46 = converted %.loc15_54.1, %tuple.loc15 [concrete = constants.%tuple.869] -// CHECK:STDOUT: %tuple.elem2: Core.IntLiteral = tuple_access %.loc15_54.2, element2 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc15_64.2: %tuple.type.d46 = converted %.loc15_64.1, %tuple.loc15 [concrete = constants.%tuple.869] +// CHECK:STDOUT: %tuple.elem2: Core.IntLiteral = tuple_access %.loc15_64.2, element2 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %array_type.loc15: type = array_type %tuple.elem2, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: %impl.elem0.loc15: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc15: = bound_method %int_0.loc15_30, %impl.elem0.loc15 [concrete = constants.%Convert.bound.d04] +// CHECK:STDOUT: %bound_method.loc15: = bound_method %int_0.loc15_35, %impl.elem0.loc15 [concrete = constants.%Convert.bound.d04] // CHECK:STDOUT: %specific_fn.loc15: = specific_function %bound_method.loc15, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.d62] -// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %specific_fn.loc15(%int_0.loc15_30) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc15_32.2: init %i32 = converted %int_0.loc15_30, %int.convert_checked.loc15 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %specific_fn.loc15(%int_0.loc15_35) [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc15_37.2: init %i32 = converted %int_0.loc15_35, %int.convert_checked.loc15 [concrete = constants.%int_0.6a9] // CHECK:STDOUT: %.loc15_1: ref %array_type = splice_block file.%tuple_index.var {} -// CHECK:STDOUT: %int_0.loc15_32: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc15_32.3: ref %i32 = array_index %.loc15_1, %int_0.loc15_32 -// CHECK:STDOUT: %.loc15_32.4: init %i32 = initialize_from %.loc15_32.2 to %.loc15_32.3 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc15_32.5: init %array_type = array_init (%.loc15_32.4) to %.loc15_1 [concrete = constants.%array] -// CHECK:STDOUT: %.loc15_34: init %array_type = converted %.loc15_32.1, %.loc15_32.5 [concrete = constants.%array] -// CHECK:STDOUT: assign file.%tuple_index.var, %.loc15_34 -// CHECK:STDOUT: %int_0.loc17_32: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc17_34.1: %tuple.type.985 = tuple_literal (%int_0.loc17_32) +// CHECK:STDOUT: %int_0.loc15_37: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc15_37.3: ref %i32 = array_index %.loc15_1, %int_0.loc15_37 +// CHECK:STDOUT: %.loc15_37.4: init %i32 = initialize_from %.loc15_37.2 to %.loc15_37.3 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc15_37.5: init %array_type = array_init (%.loc15_37.4) to %.loc15_1 [concrete = constants.%array] +// CHECK:STDOUT: %.loc15_39: init %array_type = converted %.loc15_37.1, %.loc15_37.5 [concrete = constants.%array] +// CHECK:STDOUT: assign file.%tuple_index.var, %.loc15_39 +// CHECK:STDOUT: %int_0.loc17_37: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc17_39.1: %tuple.type.985 = tuple_literal (%int_0.loc17_37) // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc17: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %int_1.loc17: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc17_60.1: %struct_type.a.b = struct_literal (%int_3.loc17, %int_1.loc17) +// CHECK:STDOUT: %.loc17_70.1: %struct_type.a.b = struct_literal (%int_3.loc17, %int_1.loc17) // CHECK:STDOUT: %struct.loc17: %struct_type.a.b = struct_value (%int_3.loc17, %int_1.loc17) [concrete = constants.%struct.a81] -// CHECK:STDOUT: %.loc17_60.2: %struct_type.a.b = converted %.loc17_60.1, %struct.loc17 [concrete = constants.%struct.a81] -// CHECK:STDOUT: %.loc17_61: Core.IntLiteral = struct_access %.loc17_60.2, element1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %array_type.loc17: type = array_type %.loc17_61, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %.loc17_70.2: %struct_type.a.b = converted %.loc17_70.1, %struct.loc17 [concrete = constants.%struct.a81] +// CHECK:STDOUT: %.loc17_71: Core.IntLiteral = struct_access %.loc17_70.2, element1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %array_type.loc17: type = array_type %.loc17_71, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: %impl.elem0.loc17: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17: = bound_method %int_0.loc17_32, %impl.elem0.loc17 [concrete = constants.%Convert.bound.d04] +// CHECK:STDOUT: %bound_method.loc17: = bound_method %int_0.loc17_37, %impl.elem0.loc17 [concrete = constants.%Convert.bound.d04] // CHECK:STDOUT: %specific_fn.loc17: = specific_function %bound_method.loc17, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.d62] -// CHECK:STDOUT: %int.convert_checked.loc17: init %i32 = call %specific_fn.loc17(%int_0.loc17_32) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc17_34.2: init %i32 = converted %int_0.loc17_32, %int.convert_checked.loc17 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %int.convert_checked.loc17: init %i32 = call %specific_fn.loc17(%int_0.loc17_37) [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc17_39.2: init %i32 = converted %int_0.loc17_37, %int.convert_checked.loc17 [concrete = constants.%int_0.6a9] // CHECK:STDOUT: %.loc17_1: ref %array_type = splice_block file.%struct_access.var {} -// CHECK:STDOUT: %int_0.loc17_34: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc17_34.3: ref %i32 = array_index %.loc17_1, %int_0.loc17_34 -// CHECK:STDOUT: %.loc17_34.4: init %i32 = initialize_from %.loc17_34.2 to %.loc17_34.3 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc17_34.5: init %array_type = array_init (%.loc17_34.4) to %.loc17_1 [concrete = constants.%array] -// CHECK:STDOUT: %.loc17_36: init %array_type = converted %.loc17_34.1, %.loc17_34.5 [concrete = constants.%array] -// CHECK:STDOUT: assign file.%struct_access.var, %.loc17_36 +// CHECK:STDOUT: %int_0.loc17_39: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc17_39.3: ref %i32 = array_index %.loc17_1, %int_0.loc17_39 +// CHECK:STDOUT: %.loc17_39.4: init %i32 = initialize_from %.loc17_39.2 to %.loc17_39.3 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc17_39.5: init %array_type = array_init (%.loc17_39.4) to %.loc17_1 [concrete = constants.%array] +// CHECK:STDOUT: %.loc17_41: init %array_type = converted %.loc17_39.1, %.loc17_39.5 [concrete = constants.%array] +// CHECK:STDOUT: assign file.%struct_access.var, %.loc17_41 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/eval/fail_aggregate.carbon b/toolchain/check/testdata/eval/fail_aggregate.carbon index 4f0435ae23954..19e118429f9c4 100644 --- a/toolchain/check/testdata/eval/fail_aggregate.carbon +++ b/toolchain/check/testdata/eval/fail_aggregate.carbon @@ -10,11 +10,11 @@ // TODO: This creates an array temporary, which we don't yet support evaluating. -// CHECK:STDERR: fail_aggregate.carbon:[[@LINE+4]]:43: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]]; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_aggregate.carbon:[[@LINE+4]]:53: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: var array_index: array(i32, 1) = (0,) as array(i32, ((5, 7, 1, 9) as array(i32, 4))[2]); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: -var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]]; +var array_index: array(i32, 1) = (0,) as array(i32, ((5, 7, 1, 9) as array(i32, 4))[2]); // CHECK:STDOUT: --- fail_aggregate.carbon // CHECK:STDOUT: @@ -78,7 +78,7 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]]; // CHECK:STDOUT: %.loc17_1: %array_type.0cb = var_pattern %array_index.patt // CHECK:STDOUT: } // CHECK:STDOUT: %array_index.var: ref %array_type.0cb = var array_index -// CHECK:STDOUT: %.loc17_25: type = splice_block %array_type [concrete = constants.%array_type.0cb] { +// CHECK:STDOUT: %.loc17_30: type = splice_block %array_type [concrete = constants.%array_type.0cb] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -89,66 +89,66 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_0.loc17_30: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc17_32: %tuple.type.985 = tuple_literal (%int_0.loc17_30) -// CHECK:STDOUT: %int_32.loc17_38: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_38: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_0.loc17_35: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] +// CHECK:STDOUT: %.loc17_37: %tuple.type.985 = tuple_literal (%int_0.loc17_35) +// CHECK:STDOUT: %int_32.loc17_48: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_48: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] // CHECK:STDOUT: %int_7: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] -// CHECK:STDOUT: %int_1.loc17_51: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_1.loc17_61: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9.988] -// CHECK:STDOUT: %.loc17_55.1: %tuple.type.d46 = tuple_literal (%int_5, %int_7, %int_1.loc17_51, %int_9) -// CHECK:STDOUT: %int_32.loc17_61: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_61: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc17_65.1: %tuple.type.d46 = tuple_literal (%int_5, %int_7, %int_1.loc17_61, %int_9) +// CHECK:STDOUT: %int_32.loc17_76: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_76: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] // CHECK:STDOUT: %array_type: type = array_type %int_4, %i32 [concrete = constants.%array_type.f32] -// CHECK:STDOUT: %impl.elem0.loc17_55.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_55.1: = bound_method %int_5, %impl.elem0.loc17_55.1 [concrete = constants.%Convert.bound.4e6] -// CHECK:STDOUT: %specific_fn.loc17_55.1: = specific_function %bound_method.loc17_55.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.ba9] -// CHECK:STDOUT: %int.convert_checked.loc17_55.1: init %i32 = call %specific_fn.loc17_55.1(%int_5) [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc17_55.2: init %i32 = converted %int_5, %int.convert_checked.loc17_55.1 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc17_55.3: ref %array_type.f32 = temporary_storage -// CHECK:STDOUT: %int_0.loc17_55: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc17_55.4: ref %i32 = array_index %.loc17_55.3, %int_0.loc17_55 -// CHECK:STDOUT: %.loc17_55.5: init %i32 = initialize_from %.loc17_55.2 to %.loc17_55.4 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %impl.elem0.loc17_55.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_55.2: = bound_method %int_7, %impl.elem0.loc17_55.2 [concrete = constants.%Convert.bound.208] -// CHECK:STDOUT: %specific_fn.loc17_55.2: = specific_function %bound_method.loc17_55.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c12] -// CHECK:STDOUT: %int.convert_checked.loc17_55.2: init %i32 = call %specific_fn.loc17_55.2(%int_7) [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %.loc17_55.6: init %i32 = converted %int_7, %int.convert_checked.loc17_55.2 [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %int_1.loc17_55: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc17_55.7: ref %i32 = array_index %.loc17_55.3, %int_1.loc17_55 -// CHECK:STDOUT: %.loc17_55.8: init %i32 = initialize_from %.loc17_55.6 to %.loc17_55.7 [concrete = constants.%int_7.0b1] -// CHECK:STDOUT: %impl.elem0.loc17_55.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_55.3: = bound_method %int_1.loc17_51, %impl.elem0.loc17_55.3 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc17_55.3: = specific_function %bound_method.loc17_55.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc17_55.3: init %i32 = call %specific_fn.loc17_55.3(%int_1.loc17_51) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc17_55.9: init %i32 = converted %int_1.loc17_51, %int.convert_checked.loc17_55.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %int_2.loc17_55: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc17_55.10: ref %i32 = array_index %.loc17_55.3, %int_2.loc17_55 -// CHECK:STDOUT: %.loc17_55.11: init %i32 = initialize_from %.loc17_55.9 to %.loc17_55.10 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc17_55.4: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_55.4: = bound_method %int_9, %impl.elem0.loc17_55.4 [concrete = constants.%Convert.bound.9e2] -// CHECK:STDOUT: %specific_fn.loc17_55.4: = specific_function %bound_method.loc17_55.4, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b02] -// CHECK:STDOUT: %int.convert_checked.loc17_55.4: init %i32 = call %specific_fn.loc17_55.4(%int_9) [concrete = constants.%int_9.f88] -// CHECK:STDOUT: %.loc17_55.12: init %i32 = converted %int_9, %int.convert_checked.loc17_55.4 [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %impl.elem0.loc17_65.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_65.1: = bound_method %int_5, %impl.elem0.loc17_65.1 [concrete = constants.%Convert.bound.4e6] +// CHECK:STDOUT: %specific_fn.loc17_65.1: = specific_function %bound_method.loc17_65.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.ba9] +// CHECK:STDOUT: %int.convert_checked.loc17_65.1: init %i32 = call %specific_fn.loc17_65.1(%int_5) [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc17_65.2: init %i32 = converted %int_5, %int.convert_checked.loc17_65.1 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc17_65.3: ref %array_type.f32 = temporary_storage +// CHECK:STDOUT: %int_0.loc17_65: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] +// CHECK:STDOUT: %.loc17_65.4: ref %i32 = array_index %.loc17_65.3, %int_0.loc17_65 +// CHECK:STDOUT: %.loc17_65.5: init %i32 = initialize_from %.loc17_65.2 to %.loc17_65.4 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %impl.elem0.loc17_65.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_65.2: = bound_method %int_7, %impl.elem0.loc17_65.2 [concrete = constants.%Convert.bound.208] +// CHECK:STDOUT: %specific_fn.loc17_65.2: = specific_function %bound_method.loc17_65.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c12] +// CHECK:STDOUT: %int.convert_checked.loc17_65.2: init %i32 = call %specific_fn.loc17_65.2(%int_7) [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %.loc17_65.6: init %i32 = converted %int_7, %int.convert_checked.loc17_65.2 [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %int_1.loc17_65: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc17_65.7: ref %i32 = array_index %.loc17_65.3, %int_1.loc17_65 +// CHECK:STDOUT: %.loc17_65.8: init %i32 = initialize_from %.loc17_65.6 to %.loc17_65.7 [concrete = constants.%int_7.0b1] +// CHECK:STDOUT: %impl.elem0.loc17_65.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_65.3: = bound_method %int_1.loc17_61, %impl.elem0.loc17_65.3 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc17_65.3: = specific_function %bound_method.loc17_65.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc17_65.3: init %i32 = call %specific_fn.loc17_65.3(%int_1.loc17_61) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc17_65.9: init %i32 = converted %int_1.loc17_61, %int.convert_checked.loc17_65.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int_2.loc17_65: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc17_65.10: ref %i32 = array_index %.loc17_65.3, %int_2.loc17_65 +// CHECK:STDOUT: %.loc17_65.11: init %i32 = initialize_from %.loc17_65.9 to %.loc17_65.10 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc17_65.4: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_65.4: = bound_method %int_9, %impl.elem0.loc17_65.4 [concrete = constants.%Convert.bound.9e2] +// CHECK:STDOUT: %specific_fn.loc17_65.4: = specific_function %bound_method.loc17_65.4, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b02] +// CHECK:STDOUT: %int.convert_checked.loc17_65.4: init %i32 = call %specific_fn.loc17_65.4(%int_9) [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %.loc17_65.12: init %i32 = converted %int_9, %int.convert_checked.loc17_65.4 [concrete = constants.%int_9.f88] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc17_55.13: ref %i32 = array_index %.loc17_55.3, %int_3 -// CHECK:STDOUT: %.loc17_55.14: init %i32 = initialize_from %.loc17_55.12 to %.loc17_55.13 [concrete = constants.%int_9.f88] -// CHECK:STDOUT: %.loc17_55.15: init %array_type.f32 = array_init (%.loc17_55.5, %.loc17_55.8, %.loc17_55.11, %.loc17_55.14) to %.loc17_55.3 [concrete = constants.%array] -// CHECK:STDOUT: %.loc17_57.1: init %array_type.f32 = converted %.loc17_55.1, %.loc17_55.15 [concrete = constants.%array] -// CHECK:STDOUT: %int_2.loc17_70: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc17_57.2: ref %array_type.f32 = temporary %.loc17_55.3, %.loc17_57.1 -// CHECK:STDOUT: %int_32.loc17_71: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_71: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %impl.elem0.loc17_70: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc17_70: = bound_method %int_2.loc17_70, %impl.elem0.loc17_70 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc17_70: = specific_function %bound_method.loc17_70, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc17_70: init %i32 = call %specific_fn.loc17_70(%int_2.loc17_70) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc17_70.1: %i32 = value_of_initializer %int.convert_checked.loc17_70 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc17_70.2: %i32 = converted %int_2.loc17_70, %.loc17_70.1 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc17_71.1: ref %i32 = array_index %.loc17_57.2, %.loc17_70.2 -// CHECK:STDOUT: %.loc17_71.2: %i32 = bind_value %.loc17_71.1 +// CHECK:STDOUT: %.loc17_65.13: ref %i32 = array_index %.loc17_65.3, %int_3 +// CHECK:STDOUT: %.loc17_65.14: init %i32 = initialize_from %.loc17_65.12 to %.loc17_65.13 [concrete = constants.%int_9.f88] +// CHECK:STDOUT: %.loc17_65.15: init %array_type.f32 = array_init (%.loc17_65.5, %.loc17_65.8, %.loc17_65.11, %.loc17_65.14) to %.loc17_65.3 [concrete = constants.%array] +// CHECK:STDOUT: %.loc17_67.1: init %array_type.f32 = converted %.loc17_65.1, %.loc17_65.15 [concrete = constants.%array] +// CHECK:STDOUT: %int_2.loc17_85: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc17_67.2: ref %array_type.f32 = temporary %.loc17_65.3, %.loc17_67.1 +// CHECK:STDOUT: %int_32.loc17_86: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_86: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %impl.elem0.loc17_85: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc17_85: = bound_method %int_2.loc17_85, %impl.elem0.loc17_85 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc17_85: = specific_function %bound_method.loc17_85, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc17_85: init %i32 = call %specific_fn.loc17_85(%int_2.loc17_85) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc17_85.1: %i32 = value_of_initializer %int.convert_checked.loc17_85 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc17_85.2: %i32 = converted %int_2.loc17_85, %.loc17_85.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc17_86.1: ref %i32 = array_index %.loc17_67.2, %.loc17_85.2 +// CHECK:STDOUT: %.loc17_86.2: %i32 = bind_value %.loc17_86.1 // CHECK:STDOUT: assign file.%array_index.var, // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/eval/symbolic.carbon b/toolchain/check/testdata/eval/symbolic.carbon index 2122e05072143..38eb9e6b065df 100644 --- a/toolchain/check/testdata/eval/symbolic.carbon +++ b/toolchain/check/testdata/eval/symbolic.carbon @@ -12,11 +12,11 @@ fn F(T:! type) { var u: (T*, const T); var v: {.a: T}; - var w: [T; 5]; + var w: array(T, 5); } fn G(N:! i32) { - var k: [i32; N]; + var k: array(i32, N); } // CHECK:STDOUT: --- symbolic.carbon @@ -103,8 +103,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %require_complete.loc13: = require_complete_type @F.%tuple.type (%tuple.type.4f2) [symbolic = %require_complete.loc13 (constants.%require_complete.155)] // CHECK:STDOUT: %struct_type.a.loc14_16.2: type = struct_type {.a: @F.%T.loc12_6.2 (%T)} [symbolic = %struct_type.a.loc14_16.2 (constants.%struct_type.a)] // CHECK:STDOUT: %require_complete.loc14: = require_complete_type @F.%struct_type.a.loc14_16.2 (%struct_type.a) [symbolic = %require_complete.loc14 (constants.%require_complete.28a)] -// CHECK:STDOUT: %array_type.loc15_15.2: type = array_type constants.%int_5, @F.%T.loc12_6.2 (%T) [symbolic = %array_type.loc15_15.2 (constants.%array_type.ec2)] -// CHECK:STDOUT: %require_complete.loc15: = require_complete_type @F.%array_type.loc15_15.2 (%array_type.ec2) [symbolic = %require_complete.loc15 (constants.%require_complete.fe1)] +// CHECK:STDOUT: %array_type.loc15_20.2: type = array_type constants.%int_5, @F.%T.loc12_6.2 (%T) [symbolic = %array_type.loc15_20.2 (constants.%array_type.ec2)] +// CHECK:STDOUT: %require_complete.loc15: = require_complete_type @F.%array_type.loc15_20.2 (%array_type.ec2) [symbolic = %require_complete.loc15 (constants.%require_complete.fe1)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%T.param_patt: type) { // CHECK:STDOUT: !entry: @@ -133,16 +133,16 @@ fn G(N:! i32) { // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref @F.%struct_type.a.loc14_16.2 (%struct_type.a) = bind_name v, %v.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %w.patt: @F.%array_type.loc15_15.2 (%array_type.ec2) = binding_pattern w -// CHECK:STDOUT: %.loc15_3: @F.%array_type.loc15_15.2 (%array_type.ec2) = var_pattern %w.patt +// CHECK:STDOUT: %w.patt: @F.%array_type.loc15_20.2 (%array_type.ec2) = binding_pattern w +// CHECK:STDOUT: %.loc15_3: @F.%array_type.loc15_20.2 (%array_type.ec2) = var_pattern %w.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %w.var: ref @F.%array_type.loc15_15.2 (%array_type.ec2) = var w -// CHECK:STDOUT: %.loc15_15: type = splice_block %array_type.loc15_15.1 [symbolic = %array_type.loc15_15.2 (constants.%array_type.ec2)] { +// CHECK:STDOUT: %w.var: ref @F.%array_type.loc15_20.2 (%array_type.ec2) = var w +// CHECK:STDOUT: %.loc15_20: type = splice_block %array_type.loc15_20.1 [symbolic = %array_type.loc15_20.2 (constants.%array_type.ec2)] { // CHECK:STDOUT: %T.ref.loc15: type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5] -// CHECK:STDOUT: %array_type.loc15_15.1: type = array_type %int_5, %T [symbolic = %array_type.loc15_15.2 (constants.%array_type.ec2)] +// CHECK:STDOUT: %array_type.loc15_20.1: type = array_type %int_5, %T [symbolic = %array_type.loc15_20.2 (constants.%array_type.ec2)] // CHECK:STDOUT: } -// CHECK:STDOUT: %w: ref @F.%array_type.loc15_15.2 (%array_type.ec2) = bind_name w, %w.var +// CHECK:STDOUT: %w: ref @F.%array_type.loc15_20.2 (%array_type.ec2) = bind_name w, %w.var // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -154,30 +154,30 @@ fn G(N:! i32) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc18_6.2, constants.%Convert.960 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc19_16.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc18_6.2) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc19_17.2: type = array_type %int.convert_checked.loc19_16.2, %i32 [symbolic = %array_type.loc19_17.2 (constants.%array_type.b04)] -// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc19_17.2 (%array_type.b04) [symbolic = %require_complete (constants.%require_complete.9dc)] +// CHECK:STDOUT: %int.convert_checked.loc19_21.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc18_6.2) [symbolic = %int.convert_checked.loc19_21.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc19_22.2: type = array_type %int.convert_checked.loc19_21.2, %i32 [symbolic = %array_type.loc19_22.2 (constants.%array_type.b04)] +// CHECK:STDOUT: %require_complete: = require_complete_type @G.%array_type.loc19_22.2 (%array_type.b04) [symbolic = %require_complete (constants.%require_complete.9dc)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%N.param_patt: %i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %k.patt: @G.%array_type.loc19_17.2 (%array_type.b04) = binding_pattern k -// CHECK:STDOUT: %.loc19_3: @G.%array_type.loc19_17.2 (%array_type.b04) = var_pattern %k.patt +// CHECK:STDOUT: %k.patt: @G.%array_type.loc19_22.2 (%array_type.b04) = binding_pattern k +// CHECK:STDOUT: %.loc19_3: @G.%array_type.loc19_22.2 (%array_type.b04) = var_pattern %k.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %k.var: ref @G.%array_type.loc19_17.2 (%array_type.b04) = var k -// CHECK:STDOUT: %.loc19_17: type = splice_block %array_type.loc19_17.1 [symbolic = %array_type.loc19_17.2 (constants.%array_type.b04)] { +// CHECK:STDOUT: %k.var: ref @G.%array_type.loc19_22.2 (%array_type.b04) = var k +// CHECK:STDOUT: %.loc19_22: type = splice_block %array_type.loc19_22.1 [symbolic = %array_type.loc19_22.2 (constants.%array_type.b04)] { // CHECK:STDOUT: %int_32.loc19: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc19: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc18_6.1 [symbolic = %N.loc18_6.2 (constants.%N.51e)] // CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] // CHECK:STDOUT: %bound_method: = bound_method %N.ref, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc19_16.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc19_16.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_16.1 [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc19_16.2: Core.IntLiteral = converted %N.ref, %.loc19_16.1 [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc19_17.1: type = array_type %.loc19_16.2, %i32 [symbolic = %array_type.loc19_17.2 (constants.%array_type.b04)] +// CHECK:STDOUT: %int.convert_checked.loc19_21.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc19_21.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc19_21.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_21.1 [symbolic = %int.convert_checked.loc19_21.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc19_21.2: Core.IntLiteral = converted %N.ref, %.loc19_21.1 [symbolic = %int.convert_checked.loc19_21.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc19_22.1: type = array_type %.loc19_21.2, %i32 [symbolic = %array_type.loc19_22.2 (constants.%array_type.b04)] // CHECK:STDOUT: } -// CHECK:STDOUT: %k: ref @G.%array_type.loc19_17.2 (%array_type.b04) = bind_name k, %k.var +// CHECK:STDOUT: %k: ref @G.%array_type.loc19_22.2 (%array_type.b04) = bind_name k, %k.var // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/builtin/call.carbon b/toolchain/check/testdata/function/builtin/call.carbon index dd81153bd79f8..5a7e368a2c503 100644 --- a/toolchain/check/testdata/function/builtin/call.carbon +++ b/toolchain/check/testdata/function/builtin/call.carbon @@ -10,7 +10,7 @@ fn Add(a: i32, b: i32) -> i32 = "int.sadd"; -var arr: [i32; Add(1, 2)]; +var arr: array(i32, Add(1, 2)); fn RuntimeCall(a: i32, b: i32) -> i32 { return Add(a, b); @@ -101,34 +101,34 @@ fn RuntimeCall(a: i32, b: i32) -> i32 { // CHECK:STDOUT: %.loc13_1: %array_type = var_pattern %arr.patt // CHECK:STDOUT: } // CHECK:STDOUT: %arr.var: ref %array_type = var arr -// CHECK:STDOUT: %.loc13_25: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc13_30: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Add.ref: %Add.type.b1f = name_ref Add, %Add.decl [concrete = constants.%Add] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %impl.elem0.loc13_20: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc13_20: = bound_method %int_1, %impl.elem0.loc13_20 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc13_20: = specific_function %bound_method.loc13_20, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc13_20: init %i32 = call %specific_fn.loc13_20(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc13_20.1: %i32 = value_of_initializer %int.convert_checked.loc13_20 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc13_20.2: %i32 = converted %int_1, %.loc13_20.1 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc13_23: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc13_23: = bound_method %int_2, %impl.elem0.loc13_23 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc13_23: = specific_function %bound_method.loc13_23, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc13_23: init %i32 = call %specific_fn.loc13_23(%int_2) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc13_23.1: %i32 = value_of_initializer %int.convert_checked.loc13_23 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc13_23.2: %i32 = converted %int_2, %.loc13_23.1 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int.sadd: init %i32 = call %Add.ref(%.loc13_20.2, %.loc13_23.2) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %impl.elem0.loc13_24: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] -// CHECK:STDOUT: %bound_method.loc13_24: = bound_method %int.sadd, %impl.elem0.loc13_24 [concrete = constants.%Convert.bound.2d6] -// CHECK:STDOUT: %specific_fn.loc13_24: = specific_function %bound_method.loc13_24, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] -// CHECK:STDOUT: %.loc13_24.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc13_24.2: %i32 = converted %int.sadd, %.loc13_24.1 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int.convert_checked.loc13_24: init Core.IntLiteral = call %specific_fn.loc13_24(%.loc13_24.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc13_24.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc13_24 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc13_24.4: Core.IntLiteral = converted %int.sadd, %.loc13_24.3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type: type = array_type %.loc13_24.4, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %impl.elem0.loc13_25: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc13_25: = bound_method %int_1, %impl.elem0.loc13_25 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc13_25: = specific_function %bound_method.loc13_25, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc13_25: init %i32 = call %specific_fn.loc13_25(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc13_25.1: %i32 = value_of_initializer %int.convert_checked.loc13_25 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc13_25.2: %i32 = converted %int_1, %.loc13_25.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc13_28: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc13_28: = bound_method %int_2, %impl.elem0.loc13_28 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc13_28: = specific_function %bound_method.loc13_28, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc13_28: init %i32 = call %specific_fn.loc13_28(%int_2) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc13_28.1: %i32 = value_of_initializer %int.convert_checked.loc13_28 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc13_28.2: %i32 = converted %int_2, %.loc13_28.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int.sadd: init %i32 = call %Add.ref(%.loc13_25.2, %.loc13_28.2) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %impl.elem0.loc13_29: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] +// CHECK:STDOUT: %bound_method.loc13_29: = bound_method %int.sadd, %impl.elem0.loc13_29 [concrete = constants.%Convert.bound.2d6] +// CHECK:STDOUT: %specific_fn.loc13_29: = specific_function %bound_method.loc13_29, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] +// CHECK:STDOUT: %.loc13_29.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc13_29.2: %i32 = converted %int.sadd, %.loc13_29.1 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int.convert_checked.loc13_29: init Core.IntLiteral = call %specific_fn.loc13_29(%.loc13_29.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc13_29.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc13_29 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc13_29.4: Core.IntLiteral = converted %int.sadd, %.loc13_29.3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type: type = array_type %.loc13_29.4, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %arr: ref %array_type = bind_name arr, %arr.var // CHECK:STDOUT: %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [concrete = constants.%RuntimeCall] { diff --git a/toolchain/check/testdata/function/builtin/method.carbon b/toolchain/check/testdata/function/builtin/method.carbon index 63a6f7c9313da..40505171ab0a7 100644 --- a/toolchain/check/testdata/function/builtin/method.carbon +++ b/toolchain/check/testdata/function/builtin/method.carbon @@ -16,7 +16,7 @@ impl i32 as I { fn F[self: i32](other: i32) -> i32 = "int.sadd"; } -var arr: [i32; (1 as i32).(I.F)(2)]; +var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: --- method.carbon // CHECK:STDOUT: @@ -101,39 +101,39 @@ var arr: [i32; (1 as i32).(I.F)(2)]; // CHECK:STDOUT: %.loc19_1: %array_type = var_pattern %arr.patt // CHECK:STDOUT: } // CHECK:STDOUT: %arr.var: ref %array_type = var arr -// CHECK:STDOUT: %.loc19_35: type = splice_block %array_type [concrete = constants.%array_type] { -// CHECK:STDOUT: %int_32.loc19_11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc19_11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc19_40: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %int_32.loc19_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc19_16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_32.loc19_22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc19_22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %impl.elem0.loc19_19: %.214 = impl_witness_access constants.%impl_witness.882, element0 [concrete = constants.%Convert.197] -// CHECK:STDOUT: %bound_method.loc19_19: = bound_method %int_1, %impl.elem0.loc19_19 [concrete = constants.%Convert.bound.c1b] -// CHECK:STDOUT: %specific_fn.loc19_19: = specific_function %bound_method.loc19_19, @Convert.5(constants.%int_32) [concrete = constants.%Convert.specific_fn.f9a] -// CHECK:STDOUT: %int.convert_checked.loc19_19: init %i32 = call %specific_fn.loc19_19(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc19_19.1: %i32 = value_of_initializer %int.convert_checked.loc19_19 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc19_19.2: %i32 = converted %int_1, %.loc19_19.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int_32.loc19_27: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc19_27: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %impl.elem0.loc19_24: %.214 = impl_witness_access constants.%impl_witness.882, element0 [concrete = constants.%Convert.197] +// CHECK:STDOUT: %bound_method.loc19_24: = bound_method %int_1, %impl.elem0.loc19_24 [concrete = constants.%Convert.bound.c1b] +// CHECK:STDOUT: %specific_fn.loc19_24: = specific_function %bound_method.loc19_24, @Convert.5(constants.%int_32) [concrete = constants.%Convert.specific_fn.f9a] +// CHECK:STDOUT: %int.convert_checked.loc19_24: init %i32 = call %specific_fn.loc19_24(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc19_24.1: %i32 = value_of_initializer %int.convert_checked.loc19_24 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc19_24.2: %i32 = converted %int_1, %.loc19_24.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %I.ref: type = name_ref I, %I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [concrete = constants.%assoc0.a5e] -// CHECK:STDOUT: %impl.elem0.loc19_26: %.c3e = impl_witness_access constants.%impl_witness.da7, element0 [concrete = constants.%F.9ec] -// CHECK:STDOUT: %bound_method.loc19_26: = bound_method %.loc19_19.2, %impl.elem0.loc19_26 [concrete = constants.%F.bound] +// CHECK:STDOUT: %impl.elem0.loc19_31: %.c3e = impl_witness_access constants.%impl_witness.da7, element0 [concrete = constants.%F.9ec] +// CHECK:STDOUT: %bound_method.loc19_31: = bound_method %.loc19_24.2, %impl.elem0.loc19_31 [concrete = constants.%F.bound] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %impl.elem0.loc19_33: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc19_33: = bound_method %int_2, %impl.elem0.loc19_33 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc19_33: = specific_function %bound_method.loc19_33, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc19_33: init %i32 = call %specific_fn.loc19_33(%int_2) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc19_33.1: %i32 = value_of_initializer %int.convert_checked.loc19_33 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc19_33.2: %i32 = converted %int_2, %.loc19_33.1 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int.sadd: init %i32 = call %bound_method.loc19_26(%.loc19_19.2, %.loc19_33.2) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %impl.elem0.loc19_34: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] -// CHECK:STDOUT: %bound_method.loc19_34: = bound_method %int.sadd, %impl.elem0.loc19_34 [concrete = constants.%Convert.bound.2d6] -// CHECK:STDOUT: %specific_fn.loc19_34: = specific_function %bound_method.loc19_34, @Convert.4(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] -// CHECK:STDOUT: %.loc19_34.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc19_34.2: %i32 = converted %int.sadd, %.loc19_34.1 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int.convert_checked.loc19_34: init Core.IntLiteral = call %specific_fn.loc19_34(%.loc19_34.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc19_34.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_34 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc19_34.4: Core.IntLiteral = converted %int.sadd, %.loc19_34.3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type: type = array_type %.loc19_34.4, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %impl.elem0.loc19_38: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc19_38: = bound_method %int_2, %impl.elem0.loc19_38 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc19_38: = specific_function %bound_method.loc19_38, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc19_38: init %i32 = call %specific_fn.loc19_38(%int_2) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc19_38.1: %i32 = value_of_initializer %int.convert_checked.loc19_38 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc19_38.2: %i32 = converted %int_2, %.loc19_38.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int.sadd: init %i32 = call %bound_method.loc19_31(%.loc19_24.2, %.loc19_38.2) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %impl.elem0.loc19_39: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] +// CHECK:STDOUT: %bound_method.loc19_39: = bound_method %int.sadd, %impl.elem0.loc19_39 [concrete = constants.%Convert.bound.2d6] +// CHECK:STDOUT: %specific_fn.loc19_39: = specific_function %bound_method.loc19_39, @Convert.4(constants.%int_32) [concrete = constants.%Convert.specific_fn.377] +// CHECK:STDOUT: %.loc19_39.1: %i32 = value_of_initializer %int.sadd [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc19_39.2: %i32 = converted %int.sadd, %.loc19_39.1 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int.convert_checked.loc19_39: init Core.IntLiteral = call %specific_fn.loc19_39(%.loc19_39.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc19_39.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_39 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc19_39.4: Core.IntLiteral = converted %int.sadd, %.loc19_39.3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type: type = array_type %.loc19_39.4, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %arr: ref %array_type = bind_name arr, %arr.var // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon b/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon index 168945f036aa5..dacbe3f1669fc 100644 --- a/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon +++ b/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon @@ -47,7 +47,7 @@ impl i32 as ImplicitAs(IntLiteral()) { import Core; -var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32)); +var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: --- core.carbon // CHECK:STDOUT: @@ -711,42 +711,42 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc4_1: %array_type = var_pattern %arr.patt // CHECK:STDOUT: } // CHECK:STDOUT: %arr.var: ref %array_type = var arr -// CHECK:STDOUT: %.loc4_39: type = splice_block %array_type [concrete = constants.%array_type] { -// CHECK:STDOUT: %int_32.loc4_11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %int.make_type_signed.loc4_11: init type = call constants.%Int(%int_32.loc4_11) [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_44: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %int_32.loc4_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %int.make_type_signed.loc4_16: init type = call constants.%Int(%int_32.loc4_16) [concrete = constants.%i32.builtin] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_32.loc4_22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %int.make_type_signed.loc4_22: init type = call constants.%Int(%int_32.loc4_22) [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_22.1: type = value_of_initializer %int.make_type_signed.loc4_22 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_22.2: type = converted %int.make_type_signed.loc4_22, %.loc4_22.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %impl.elem0.loc4_19: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] -// CHECK:STDOUT: %bound_method.loc4_19: = bound_method %int_1, %impl.elem0.loc4_19 [concrete = constants.%Convert.bound.b34] -// CHECK:STDOUT: %int.convert_checked.loc4_19: init %i32.builtin = call %bound_method.loc4_19(%int_1) [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %.loc4_19.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_19 [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %.loc4_19.2: %i32.builtin = converted %int_1, %.loc4_19.1 [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %int_32.loc4_27: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %int.make_type_signed.loc4_27: init type = call constants.%Int(%int_32.loc4_27) [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_27.1: type = value_of_initializer %int.make_type_signed.loc4_27 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_27.2: type = converted %int.make_type_signed.loc4_27, %.loc4_27.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %impl.elem0.loc4_24: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] +// CHECK:STDOUT: %bound_method.loc4_24: = bound_method %int_1, %impl.elem0.loc4_24 [concrete = constants.%Convert.bound.b34] +// CHECK:STDOUT: %int.convert_checked.loc4_24: init %i32.builtin = call %bound_method.loc4_24(%int_1) [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %.loc4_24.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_24 [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %.loc4_24.2: %i32.builtin = converted %int_1, %.loc4_24.1 [concrete = constants.%int_1.f38] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_32.loc4_35: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %int.make_type_signed.loc4_35: init type = call constants.%Int(%int_32.loc4_35) [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_35.1: type = value_of_initializer %int.make_type_signed.loc4_35 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_35.2: type = converted %int.make_type_signed.loc4_35, %.loc4_35.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %impl.elem0.loc4_32: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] -// CHECK:STDOUT: %bound_method.loc4_32: = bound_method %int_2, %impl.elem0.loc4_32 [concrete = constants.%Convert.bound.324] -// CHECK:STDOUT: %int.convert_checked.loc4_32: init %i32.builtin = call %bound_method.loc4_32(%int_2) [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %.loc4_32.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_32 [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %.loc4_32.2: %i32.builtin = converted %int_2, %.loc4_32.1 [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %impl.elem0.loc4_27.1: %.7c2 = impl_witness_access constants.%impl_witness.bd0, element0 [concrete = constants.%Op.0e2] -// CHECK:STDOUT: %bound_method.loc4_27.1: = bound_method %.loc4_19.2, %impl.elem0.loc4_27.1 [concrete = constants.%Op.bound.393] -// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %bound_method.loc4_27.1(%.loc4_19.2, %.loc4_32.2) [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_11.1: type = value_of_initializer %int.make_type_signed.loc4_11 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_11.2: type = converted %int.make_type_signed.loc4_11, %.loc4_11.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %impl.elem0.loc4_27.2: %.38f = impl_witness_access constants.%impl_witness.8f3, element0 [concrete = constants.%Convert.b32] -// CHECK:STDOUT: %bound_method.loc4_27.2: = bound_method %int.sadd, %impl.elem0.loc4_27.2 [concrete = constants.%Convert.bound.65a] -// CHECK:STDOUT: %.loc4_27.1: %i32.builtin = value_of_initializer %int.sadd [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_27.2: %i32.builtin = converted %int.sadd, %.loc4_27.1 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %int.convert_checked.loc4_27: init Core.IntLiteral = call %bound_method.loc4_27.2(%.loc4_27.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc4_27.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_27 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc4_27.4: Core.IntLiteral = converted %int.sadd, %.loc4_27.3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type: type = array_type %.loc4_27.4, %i32.builtin [concrete = constants.%array_type] +// CHECK:STDOUT: %int_32.loc4_40: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %int.make_type_signed.loc4_40: init type = call constants.%Int(%int_32.loc4_40) [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_40.1: type = value_of_initializer %int.make_type_signed.loc4_40 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_40.2: type = converted %int.make_type_signed.loc4_40, %.loc4_40.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %impl.elem0.loc4_37: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] +// CHECK:STDOUT: %bound_method.loc4_37: = bound_method %int_2, %impl.elem0.loc4_37 [concrete = constants.%Convert.bound.324] +// CHECK:STDOUT: %int.convert_checked.loc4_37: init %i32.builtin = call %bound_method.loc4_37(%int_2) [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %.loc4_37.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_37 [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %.loc4_37.2: %i32.builtin = converted %int_2, %.loc4_37.1 [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %impl.elem0.loc4_32.1: %.7c2 = impl_witness_access constants.%impl_witness.bd0, element0 [concrete = constants.%Op.0e2] +// CHECK:STDOUT: %bound_method.loc4_32.1: = bound_method %.loc4_24.2, %impl.elem0.loc4_32.1 [concrete = constants.%Op.bound.393] +// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %bound_method.loc4_32.1(%.loc4_24.2, %.loc4_37.2) [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_16.1: type = value_of_initializer %int.make_type_signed.loc4_16 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_16.2: type = converted %int.make_type_signed.loc4_16, %.loc4_16.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %impl.elem0.loc4_32.2: %.38f = impl_witness_access constants.%impl_witness.8f3, element0 [concrete = constants.%Convert.b32] +// CHECK:STDOUT: %bound_method.loc4_32.2: = bound_method %int.sadd, %impl.elem0.loc4_32.2 [concrete = constants.%Convert.bound.65a] +// CHECK:STDOUT: %.loc4_32.1: %i32.builtin = value_of_initializer %int.sadd [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_32.2: %i32.builtin = converted %int.sadd, %.loc4_32.1 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %int.convert_checked.loc4_32: init Core.IntLiteral = call %bound_method.loc4_32.2(%.loc4_32.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc4_32.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_32 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc4_32.4: Core.IntLiteral = converted %int.sadd, %.loc4_32.3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type: type = array_type %.loc4_32.4, %i32.builtin [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %arr: ref %array_type = bind_name arr, %arr.var // CHECK:STDOUT: } @@ -855,51 +855,51 @@ var arr: [i32; (1 as i32) + (2 as i32)] = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_3.loc4_44: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %int_4.loc4_47: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] -// CHECK:STDOUT: %int_3.loc4_51: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %int_32.loc4_56: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %int.make_type_signed.loc4_56: init type = call constants.%Int(%int_32.loc4_56) [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_56.1: type = value_of_initializer %int.make_type_signed.loc4_56 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_56.2: type = converted %int.make_type_signed.loc4_56, %.loc4_56.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %impl.elem0.loc4_53: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] -// CHECK:STDOUT: %bound_method.loc4_53: = bound_method %int_3.loc4_51, %impl.elem0.loc4_53 [concrete = constants.%Convert.bound.94d] -// CHECK:STDOUT: %int.convert_checked.loc4_53: init %i32.builtin = call %bound_method.loc4_53(%int_3.loc4_51) [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_53.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_53 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_53.2: %i32.builtin = converted %int_3.loc4_51, %.loc4_53.1 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %int_4.loc4_64: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] -// CHECK:STDOUT: %int_32.loc4_69: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %int.make_type_signed.loc4_69: init type = call constants.%Int(%int_32.loc4_69) [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_69.1: type = value_of_initializer %int.make_type_signed.loc4_69 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_69.2: type = converted %int.make_type_signed.loc4_69, %.loc4_69.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %impl.elem0.loc4_66: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] -// CHECK:STDOUT: %bound_method.loc4_66: = bound_method %int_4.loc4_64, %impl.elem0.loc4_66 [concrete = constants.%Convert.bound.8fc] -// CHECK:STDOUT: %int.convert_checked.loc4_66: init %i32.builtin = call %bound_method.loc4_66(%int_4.loc4_64) [concrete = constants.%int_4.4f1] -// CHECK:STDOUT: %.loc4_66.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_66 [concrete = constants.%int_4.4f1] -// CHECK:STDOUT: %.loc4_66.2: %i32.builtin = converted %int_4.loc4_64, %.loc4_66.1 [concrete = constants.%int_4.4f1] -// CHECK:STDOUT: %impl.elem0.loc4_61: %.7c2 = impl_witness_access constants.%impl_witness.bd0, element0 [concrete = constants.%Op.0e2] -// CHECK:STDOUT: %bound_method.loc4_61: = bound_method %.loc4_53.2, %impl.elem0.loc4_61 [concrete = constants.%Op.bound.423] -// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %bound_method.loc4_61(%.loc4_53.2, %.loc4_66.2) [concrete = constants.%int_7] -// CHECK:STDOUT: %.loc4_73.1: %tuple.type = tuple_literal (%int_3.loc4_44, %int_4.loc4_47, %int.sadd) -// CHECK:STDOUT: %impl.elem0.loc4_73.1: %.624 = impl_witness_access constants.%impl_witness.39c, element0 [concrete = constants.%Convert.cb5] -// CHECK:STDOUT: %bound_method.loc4_73.1: = bound_method %int_3.loc4_44, %impl.elem0.loc4_73.1 [concrete = constants.%Convert.bound.b6b] -// CHECK:STDOUT: %int.convert_checked.loc4_73.1: init %i32.builtin = call %bound_method.loc4_73.1(%int_3.loc4_44) [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_73.2: init %i32.builtin = converted %int_3.loc4_44, %int.convert_checked.loc4_73.1 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %int_3.loc4_49: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %int_4.loc4_52: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] +// CHECK:STDOUT: %int_3.loc4_56: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %int_32.loc4_61: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %int.make_type_signed.loc4_61: init type = call constants.%Int(%int_32.loc4_61) [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_61.1: type = value_of_initializer %int.make_type_signed.loc4_61 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_61.2: type = converted %int.make_type_signed.loc4_61, %.loc4_61.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %impl.elem0.loc4_58: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] +// CHECK:STDOUT: %bound_method.loc4_58: = bound_method %int_3.loc4_56, %impl.elem0.loc4_58 [concrete = constants.%Convert.bound.94d] +// CHECK:STDOUT: %int.convert_checked.loc4_58: init %i32.builtin = call %bound_method.loc4_58(%int_3.loc4_56) [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_58.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_58 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_58.2: %i32.builtin = converted %int_3.loc4_56, %.loc4_58.1 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %int_4.loc4_69: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] +// CHECK:STDOUT: %int_32.loc4_74: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %int.make_type_signed.loc4_74: init type = call constants.%Int(%int_32.loc4_74) [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_74.1: type = value_of_initializer %int.make_type_signed.loc4_74 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_74.2: type = converted %int.make_type_signed.loc4_74, %.loc4_74.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %impl.elem0.loc4_71: %.dc4 = impl_witness_access constants.%impl_witness.d9b, element0 [concrete = constants.%Convert.5bc] +// CHECK:STDOUT: %bound_method.loc4_71: = bound_method %int_4.loc4_69, %impl.elem0.loc4_71 [concrete = constants.%Convert.bound.8fc] +// CHECK:STDOUT: %int.convert_checked.loc4_71: init %i32.builtin = call %bound_method.loc4_71(%int_4.loc4_69) [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %.loc4_71.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_71 [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %.loc4_71.2: %i32.builtin = converted %int_4.loc4_69, %.loc4_71.1 [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %impl.elem0.loc4_66: %.7c2 = impl_witness_access constants.%impl_witness.bd0, element0 [concrete = constants.%Op.0e2] +// CHECK:STDOUT: %bound_method.loc4_66: = bound_method %.loc4_58.2, %impl.elem0.loc4_66 [concrete = constants.%Op.bound.423] +// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %bound_method.loc4_66(%.loc4_58.2, %.loc4_71.2) [concrete = constants.%int_7] +// CHECK:STDOUT: %.loc4_78.1: %tuple.type = tuple_literal (%int_3.loc4_49, %int_4.loc4_52, %int.sadd) +// CHECK:STDOUT: %impl.elem0.loc4_78.1: %.624 = impl_witness_access constants.%impl_witness.39c, element0 [concrete = constants.%Convert.cb5] +// CHECK:STDOUT: %bound_method.loc4_78.1: = bound_method %int_3.loc4_49, %impl.elem0.loc4_78.1 [concrete = constants.%Convert.bound.b6b] +// CHECK:STDOUT: %int.convert_checked.loc4_78.1: init %i32.builtin = call %bound_method.loc4_78.1(%int_3.loc4_49) [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_78.2: init %i32.builtin = converted %int_3.loc4_49, %int.convert_checked.loc4_78.1 [concrete = constants.%int_3.a0f] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc4_73.3: ref %i32.builtin = array_index file.%arr.var, %int_0 -// CHECK:STDOUT: %.loc4_73.4: init %i32.builtin = initialize_from %.loc4_73.2 to %.loc4_73.3 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %impl.elem0.loc4_73.2: %.624 = impl_witness_access constants.%impl_witness.39c, element0 [concrete = constants.%Convert.cb5] -// CHECK:STDOUT: %bound_method.loc4_73.2: = bound_method %int_4.loc4_47, %impl.elem0.loc4_73.2 [concrete = constants.%Convert.bound.626] -// CHECK:STDOUT: %int.convert_checked.loc4_73.2: init %i32.builtin = call %bound_method.loc4_73.2(%int_4.loc4_47) [concrete = constants.%int_4.4f1] -// CHECK:STDOUT: %.loc4_73.5: init %i32.builtin = converted %int_4.loc4_47, %int.convert_checked.loc4_73.2 [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %.loc4_78.3: ref %i32.builtin = array_index file.%arr.var, %int_0 +// CHECK:STDOUT: %.loc4_78.4: init %i32.builtin = initialize_from %.loc4_78.2 to %.loc4_78.3 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %impl.elem0.loc4_78.2: %.624 = impl_witness_access constants.%impl_witness.39c, element0 [concrete = constants.%Convert.cb5] +// CHECK:STDOUT: %bound_method.loc4_78.2: = bound_method %int_4.loc4_52, %impl.elem0.loc4_78.2 [concrete = constants.%Convert.bound.626] +// CHECK:STDOUT: %int.convert_checked.loc4_78.2: init %i32.builtin = call %bound_method.loc4_78.2(%int_4.loc4_52) [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %.loc4_78.5: init %i32.builtin = converted %int_4.loc4_52, %int.convert_checked.loc4_78.2 [concrete = constants.%int_4.4f1] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc4_73.6: ref %i32.builtin = array_index file.%arr.var, %int_1 -// CHECK:STDOUT: %.loc4_73.7: init %i32.builtin = initialize_from %.loc4_73.5 to %.loc4_73.6 [concrete = constants.%int_4.4f1] +// CHECK:STDOUT: %.loc4_78.6: ref %i32.builtin = array_index file.%arr.var, %int_1 +// CHECK:STDOUT: %.loc4_78.7: init %i32.builtin = initialize_from %.loc4_78.5 to %.loc4_78.6 [concrete = constants.%int_4.4f1] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc4_73.8: ref %i32.builtin = array_index file.%arr.var, %int_2 -// CHECK:STDOUT: %.loc4_73.9: init %i32.builtin = initialize_from %int.sadd to %.loc4_73.8 [concrete = constants.%int_7] -// CHECK:STDOUT: %.loc4_73.10: init %array_type = array_init (%.loc4_73.4, %.loc4_73.7, %.loc4_73.9) to file.%arr.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc4_1: init %array_type = converted %.loc4_73.1, %.loc4_73.10 [concrete = constants.%array] +// CHECK:STDOUT: %.loc4_78.8: ref %i32.builtin = array_index file.%arr.var, %int_2 +// CHECK:STDOUT: %.loc4_78.9: init %i32.builtin = initialize_from %int.sadd to %.loc4_78.8 [concrete = constants.%int_7] +// CHECK:STDOUT: %.loc4_78.10: init %array_type = array_init (%.loc4_78.4, %.loc4_78.7, %.loc4_78.9) to file.%arr.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc4_1: init %array_type = converted %.loc4_78.1, %.loc4_78.10 [concrete = constants.%array] // CHECK:STDOUT: assign file.%arr.var, %.loc4_1 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/builtin/no_prelude/import.carbon b/toolchain/check/testdata/function/builtin/no_prelude/import.carbon index 07e98bae44fa8..d9740c3f796d6 100644 --- a/toolchain/check/testdata/function/builtin/no_prelude/import.carbon +++ b/toolchain/check/testdata/function/builtin/no_prelude/import.carbon @@ -25,7 +25,7 @@ fn TestAdd(a: i32, b: i32) -> i32 = "int.sadd"; import Core library "core"; -var arr: [i32; Core.AsIntLiteral(Core.TestAdd(Core.AsI32(1), Core.AsI32(2)))] = (Core.AsI32(1), Core.AsI32(2), Core.AsI32(3)); +var arr: array(i32, Core.AsIntLiteral(Core.TestAdd(Core.AsI32(1), Core.AsI32(2)))) = (Core.AsI32(1), Core.AsI32(2), Core.AsI32(3)); // CHECK:STDOUT: --- core.carbon // CHECK:STDOUT: @@ -210,34 +210,34 @@ var arr: [i32; Core.AsIntLiteral(Core.TestAdd(Core.AsI32(1), Core.AsI32(2)))] = // CHECK:STDOUT: %.loc4_1: %array_type = var_pattern %arr.patt // CHECK:STDOUT: } // CHECK:STDOUT: %arr.var: ref %array_type = var arr -// CHECK:STDOUT: %.loc4_77: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc4_82: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%int_32) [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %Core.ref.loc4_16: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %Core.ref.loc4_21: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %AsIntLiteral.ref: %AsIntLiteral.type = name_ref AsIntLiteral, imports.%Core.AsIntLiteral [concrete = constants.%AsIntLiteral] -// CHECK:STDOUT: %Core.ref.loc4_34: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %Core.ref.loc4_39: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %TestAdd.ref: %TestAdd.type = name_ref TestAdd, imports.%Core.TestAdd [concrete = constants.%TestAdd] -// CHECK:STDOUT: %Core.ref.loc4_47: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %AsI32.ref.loc4_51: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] +// CHECK:STDOUT: %Core.ref.loc4_52: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %AsI32.ref.loc4_56: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int.convert_checked.loc4_59: init %i32.builtin = call %AsI32.ref.loc4_51(%int_1) [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %Core.ref.loc4_62: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %AsI32.ref.loc4_66: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] +// CHECK:STDOUT: %int.convert_checked.loc4_64: init %i32.builtin = call %AsI32.ref.loc4_56(%int_1) [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %Core.ref.loc4_67: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %AsI32.ref.loc4_71: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int.convert_checked.loc4_74: init %i32.builtin = call %AsI32.ref.loc4_66(%int_2) [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %.loc4_59.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_59 [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %.loc4_59.2: %i32.builtin = converted %int.convert_checked.loc4_59, %.loc4_59.1 [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %.loc4_74.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_74 [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %.loc4_74.2: %i32.builtin = converted %int.convert_checked.loc4_74, %.loc4_74.1 [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %TestAdd.ref(%.loc4_59.2, %.loc4_74.2) [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_75.1: %i32.builtin = value_of_initializer %int.sadd [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_75.2: %i32.builtin = converted %int.sadd, %.loc4_75.1 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %int.convert_checked.loc4_76: init Core.IntLiteral = call %AsIntLiteral.ref(%.loc4_75.2) [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc4_11.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_11.2: type = converted %int.make_type_signed, %.loc4_11.1 [concrete = constants.%i32.builtin] -// CHECK:STDOUT: %.loc4_76.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_76 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc4_76.2: Core.IntLiteral = converted %int.convert_checked.loc4_76, %.loc4_76.1 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type: type = array_type %.loc4_76.2, %i32.builtin [concrete = constants.%array_type] +// CHECK:STDOUT: %int.convert_checked.loc4_79: init %i32.builtin = call %AsI32.ref.loc4_71(%int_2) [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %.loc4_64.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_64 [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %.loc4_64.2: %i32.builtin = converted %int.convert_checked.loc4_64, %.loc4_64.1 [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %.loc4_79.1: %i32.builtin = value_of_initializer %int.convert_checked.loc4_79 [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %.loc4_79.2: %i32.builtin = converted %int.convert_checked.loc4_79, %.loc4_79.1 [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %int.sadd: init %i32.builtin = call %TestAdd.ref(%.loc4_64.2, %.loc4_79.2) [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_80.1: %i32.builtin = value_of_initializer %int.sadd [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_80.2: %i32.builtin = converted %int.sadd, %.loc4_80.1 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %int.convert_checked.loc4_81: init Core.IntLiteral = call %AsIntLiteral.ref(%.loc4_80.2) [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc4_16.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_16.2: type = converted %int.make_type_signed, %.loc4_16.1 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %.loc4_81.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc4_81 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc4_81.2: Core.IntLiteral = converted %int.convert_checked.loc4_81, %.loc4_81.1 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type: type = array_type %.loc4_81.2, %i32.builtin [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %arr: ref %array_type = bind_name arr, %arr.var // CHECK:STDOUT: } @@ -252,30 +252,30 @@ var arr: [i32; Core.AsIntLiteral(Core.TestAdd(Core.AsI32(1), Core.AsI32(2)))] = // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Core.ref.loc4_82: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %AsI32.ref.loc4_86: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] -// CHECK:STDOUT: %int_1.loc4_93: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int.convert_checked.loc4_94: init %i32.builtin = call %AsI32.ref.loc4_86(%int_1.loc4_93) [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %Core.ref.loc4_97: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %AsI32.ref.loc4_101: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] -// CHECK:STDOUT: %int_2.loc4_108: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int.convert_checked.loc4_109: init %i32.builtin = call %AsI32.ref.loc4_101(%int_2.loc4_108) [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %Core.ref.loc4_112: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %AsI32.ref.loc4_116: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] +// CHECK:STDOUT: %Core.ref.loc4_87: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %AsI32.ref.loc4_91: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] +// CHECK:STDOUT: %int_1.loc4_98: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int.convert_checked.loc4_99: init %i32.builtin = call %AsI32.ref.loc4_91(%int_1.loc4_98) [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %Core.ref.loc4_102: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %AsI32.ref.loc4_106: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] +// CHECK:STDOUT: %int_2.loc4_113: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int.convert_checked.loc4_114: init %i32.builtin = call %AsI32.ref.loc4_106(%int_2.loc4_113) [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %Core.ref.loc4_117: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %AsI32.ref.loc4_121: %AsI32.type = name_ref AsI32, imports.%Core.AsI32 [concrete = constants.%AsI32] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %int.convert_checked.loc4_124: init %i32.builtin = call %AsI32.ref.loc4_116(%int_3) [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_125.1: %tuple.type = tuple_literal (%int.convert_checked.loc4_94, %int.convert_checked.loc4_109, %int.convert_checked.loc4_124) +// CHECK:STDOUT: %int.convert_checked.loc4_129: init %i32.builtin = call %AsI32.ref.loc4_121(%int_3) [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_130.1: %tuple.type = tuple_literal (%int.convert_checked.loc4_99, %int.convert_checked.loc4_114, %int.convert_checked.loc4_129) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc4_125.2: ref %i32.builtin = array_index file.%arr.var, %int_0 -// CHECK:STDOUT: %.loc4_125.3: init %i32.builtin = initialize_from %int.convert_checked.loc4_94 to %.loc4_125.2 [concrete = constants.%int_1.f38] -// CHECK:STDOUT: %int_1.loc4_125: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc4_125.4: ref %i32.builtin = array_index file.%arr.var, %int_1.loc4_125 -// CHECK:STDOUT: %.loc4_125.5: init %i32.builtin = initialize_from %int.convert_checked.loc4_109 to %.loc4_125.4 [concrete = constants.%int_2.5a1] -// CHECK:STDOUT: %int_2.loc4_125: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc4_125.6: ref %i32.builtin = array_index file.%arr.var, %int_2.loc4_125 -// CHECK:STDOUT: %.loc4_125.7: init %i32.builtin = initialize_from %int.convert_checked.loc4_124 to %.loc4_125.6 [concrete = constants.%int_3.a0f] -// CHECK:STDOUT: %.loc4_125.8: init %array_type = array_init (%.loc4_125.3, %.loc4_125.5, %.loc4_125.7) to file.%arr.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc4_1: init %array_type = converted %.loc4_125.1, %.loc4_125.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc4_130.2: ref %i32.builtin = array_index file.%arr.var, %int_0 +// CHECK:STDOUT: %.loc4_130.3: init %i32.builtin = initialize_from %int.convert_checked.loc4_99 to %.loc4_130.2 [concrete = constants.%int_1.f38] +// CHECK:STDOUT: %int_1.loc4_130: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc4_130.4: ref %i32.builtin = array_index file.%arr.var, %int_1.loc4_130 +// CHECK:STDOUT: %.loc4_130.5: init %i32.builtin = initialize_from %int.convert_checked.loc4_114 to %.loc4_130.4 [concrete = constants.%int_2.5a1] +// CHECK:STDOUT: %int_2.loc4_130: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc4_130.6: ref %i32.builtin = array_index file.%arr.var, %int_2.loc4_130 +// CHECK:STDOUT: %.loc4_130.7: init %i32.builtin = initialize_from %int.convert_checked.loc4_129 to %.loc4_130.6 [concrete = constants.%int_3.a0f] +// CHECK:STDOUT: %.loc4_130.8: init %array_type = array_init (%.loc4_130.3, %.loc4_130.5, %.loc4_130.7) to file.%arr.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc4_1: init %array_type = converted %.loc4_130.1, %.loc4_130.8 [concrete = constants.%array] // CHECK:STDOUT: assign file.%arr.var, %.loc4_1 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon b/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon index 7d160ebe42ed0..9e27d38b916ab 100644 --- a/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon +++ b/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon @@ -8,11 +8,11 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/declaration/fail_param_in_type.carbon -// CHECK:STDERR: fail_param_in_type.carbon:[[@LINE+4]]:23: error: array bound is not a constant [InvalidArrayExpr] -// CHECK:STDERR: fn F(n: i32, a: [i32; n]*); -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_param_in_type.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr] +// CHECK:STDERR: fn F(n: i32, a: array(i32, n)*); +// CHECK:STDERR: ^ // CHECK:STDERR: -fn F(n: i32, a: [i32; n]*); +fn F(n: i32, a: array(i32, n)*); // CHECK:STDOUT: --- fail_param_in_type.carbon // CHECK:STDOUT: @@ -50,9 +50,9 @@ fn F(n: i32, a: [i32; n]*); // CHECK:STDOUT: } // CHECK:STDOUT: %n: %i32 = bind_name n, %n.param // CHECK:STDOUT: %a.param: = value_param runtime_param1 -// CHECK:STDOUT: %.loc15_25: type = splice_block %ptr [concrete = ] { -// CHECK:STDOUT: %int_32.loc15_18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc15_18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc15_30: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %int_32.loc15_23: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc15_23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %n.ref: %i32 = name_ref n, %n // CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/generic/param_in_type.carbon b/toolchain/check/testdata/function/generic/param_in_type.carbon index e93dbd3d84053..8900f918571dc 100644 --- a/toolchain/check/testdata/function/generic/param_in_type.carbon +++ b/toolchain/check/testdata/function/generic/param_in_type.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/param_in_type.carbon -fn F(N:! i32, a: [i32; N]*); +fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: --- param_in_type.carbon // CHECK:STDOUT: @@ -51,8 +51,8 @@ fn F(N:! i32, a: [i32; N]*); // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %N.patt.loc11_6.1: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc11_6.2 (constants.%N.patt.8e2)] // CHECK:STDOUT: %N.param_patt: %i32 = value_param_pattern %N.patt.loc11_6.1, runtime_param [symbolic = %N.patt.loc11_6.2 (constants.%N.patt.8e2)] -// CHECK:STDOUT: %a.patt: @F.%ptr.loc11_26.2 (%ptr) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%ptr.loc11_26.2 (%ptr) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.patt: @F.%ptr.loc11_31.2 (%ptr) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%ptr.loc11_31.2 (%ptr) = value_param_pattern %a.patt, runtime_param0 // CHECK:STDOUT: } { // CHECK:STDOUT: %N.param: %i32 = value_param runtime_param // CHECK:STDOUT: %.loc11_10: type = splice_block %i32.loc11_10 [concrete = constants.%i32] { @@ -60,21 +60,21 @@ fn F(N:! i32, a: [i32; N]*); // CHECK:STDOUT: %i32.loc11_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc11_6.1: %i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc11_6.2 (constants.%N.51e)] -// CHECK:STDOUT: %a.param: @F.%ptr.loc11_26.2 (%ptr) = value_param runtime_param0 -// CHECK:STDOUT: %.loc11_26: type = splice_block %ptr.loc11_26.1 [symbolic = %ptr.loc11_26.2 (constants.%ptr)] { -// CHECK:STDOUT: %int_32.loc11_19: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc11_19: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %a.param: @F.%ptr.loc11_31.2 (%ptr) = value_param runtime_param0 +// CHECK:STDOUT: %.loc11_31: type = splice_block %ptr.loc11_31.1 [symbolic = %ptr.loc11_31.2 (constants.%ptr)] { +// CHECK:STDOUT: %int_32.loc11_24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc11_24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc11_6.1 [symbolic = %N.loc11_6.2 (constants.%N.51e)] // CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [concrete = constants.%Convert.960] // CHECK:STDOUT: %bound_method: = bound_method %N.ref, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc11_24.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc11_24.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc11_24.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc11_24.1 [symbolic = %int.convert_checked.loc11_24.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %.loc11_24.2: Core.IntLiteral = converted %N.ref, %.loc11_24.1 [symbolic = %int.convert_checked.loc11_24.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc11_25.1: type = array_type %.loc11_24.2, %i32 [symbolic = %array_type.loc11_25.2 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc11_26.1: type = ptr_type %array_type [symbolic = %ptr.loc11_26.2 (constants.%ptr)] +// CHECK:STDOUT: %int.convert_checked.loc11_29.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc11_29.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc11_29.1 [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %.loc11_29.2: Core.IntLiteral = converted %N.ref, %.loc11_29.1 [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc11_30.1: type = array_type %.loc11_29.2, %i32 [symbolic = %array_type.loc11_30.2 (constants.%array_type)] +// CHECK:STDOUT: %ptr.loc11_31.1: type = ptr_type %array_type [symbolic = %ptr.loc11_31.2 (constants.%ptr)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%ptr.loc11_26.2 (%ptr) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%ptr.loc11_31.2 (%ptr) = bind_name a, %a.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -83,11 +83,11 @@ fn F(N:! i32, a: [i32; N]*); // CHECK:STDOUT: %N.patt.loc11_6.2: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc11_6.2 (constants.%N.patt.8e2)] // CHECK:STDOUT: %Convert.bound: = bound_method %N.loc11_6.2, constants.%Convert.960 [symbolic = %Convert.bound (constants.%Convert.bound)] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)] -// CHECK:STDOUT: %int.convert_checked.loc11_24.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc11_6.2) [symbolic = %int.convert_checked.loc11_24.2 (constants.%int.convert_checked)] -// CHECK:STDOUT: %array_type.loc11_25.2: type = array_type %int.convert_checked.loc11_24.2, %i32 [symbolic = %array_type.loc11_25.2 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc11_26.2: type = ptr_type @F.%array_type.loc11_25.2 (%array_type) [symbolic = %ptr.loc11_26.2 (constants.%ptr)] +// CHECK:STDOUT: %int.convert_checked.loc11_29.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc11_6.2) [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] +// CHECK:STDOUT: %array_type.loc11_30.2: type = array_type %int.convert_checked.loc11_29.2, %i32 [symbolic = %array_type.loc11_30.2 (constants.%array_type)] +// CHECK:STDOUT: %ptr.loc11_31.2: type = ptr_type @F.%array_type.loc11_30.2 (%array_type) [symbolic = %ptr.loc11_31.2 (constants.%ptr)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%N.param_patt: %i32, %a.param_patt: @F.%ptr.loc11_26.2 (%ptr)); +// CHECK:STDOUT: fn(%N.param_patt: %i32, %a.param_patt: @F.%ptr.loc11_31.2 (%ptr)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%N.51e) { @@ -95,8 +95,8 @@ fn F(N:! i32, a: [i32; N]*); // CHECK:STDOUT: %N.patt.loc11_6.2 => constants.%N.51e // CHECK:STDOUT: %Convert.bound => constants.%Convert.bound // CHECK:STDOUT: %Convert.specific_fn => constants.%Convert.specific_fn -// CHECK:STDOUT: %int.convert_checked.loc11_24.2 => constants.%int.convert_checked -// CHECK:STDOUT: %array_type.loc11_25.2 => constants.%array_type -// CHECK:STDOUT: %ptr.loc11_26.2 => constants.%ptr +// CHECK:STDOUT: %int.convert_checked.loc11_29.2 => constants.%int.convert_checked +// CHECK:STDOUT: %array_type.loc11_30.2 => constants.%array_type +// CHECK:STDOUT: %ptr.loc11_31.2 => constants.%ptr // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/generic/return_slot.carbon b/toolchain/check/testdata/function/generic/return_slot.carbon index 9059b60b0d1e2..de413df133507 100644 --- a/toolchain/check/testdata/function/generic/return_slot.carbon +++ b/toolchain/check/testdata/function/generic/return_slot.carbon @@ -12,7 +12,7 @@ class Wrap(T:! type) { fn Make() -> T { return Make(); } } -class C { var arr: [i32; 100]; } +class C { var arr: array(i32, 100); } fn G() { var a: i32 = Wrap(i32).Make(); diff --git a/toolchain/check/testdata/if_expr/basic.carbon b/toolchain/check/testdata/if_expr/basic.carbon index f3b14049e26e9..734a1e68ac92e 100644 --- a/toolchain/check/testdata/if_expr/basic.carbon +++ b/toolchain/check/testdata/if_expr/basic.carbon @@ -9,7 +9,7 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/if_expr/basic.carbon fn F(b: bool, n: i32, m: i32) -> i32 { - var x: [i32; 1] = (0,); + var x: array(i32, 1) = (0,); return if b then x[m] else x[n]; } @@ -98,20 +98,20 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: %.loc12_3.1: %array_type = var_pattern %x.patt // CHECK:STDOUT: } // CHECK:STDOUT: %x.var: ref %array_type = var x -// CHECK:STDOUT: %int_0.loc12_22: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc12_24.1: %tuple.type = tuple_literal (%int_0.loc12_22) +// CHECK:STDOUT: %int_0.loc12_27: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc12_29.1: %tuple.type = tuple_literal (%int_0.loc12_27) // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method: = bound_method %int_0.loc12_22, %impl.elem0 [concrete = constants.%Convert.bound] +// CHECK:STDOUT: %bound_method: = bound_method %int_0.loc12_27, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0.loc12_22) [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc12_24.2: init %i32 = converted %int_0.loc12_22, %int.convert_checked [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %int_0.loc12_24: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc12_24.3: ref %i32 = array_index %x.var, %int_0.loc12_24 -// CHECK:STDOUT: %.loc12_24.4: init %i32 = initialize_from %.loc12_24.2 to %.loc12_24.3 [concrete = constants.%int_0.6a9] -// CHECK:STDOUT: %.loc12_24.5: init %array_type = array_init (%.loc12_24.4) to %x.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc12_3.2: init %array_type = converted %.loc12_24.1, %.loc12_24.5 [concrete = constants.%array] +// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0.loc12_27) [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc12_29.2: init %i32 = converted %int_0.loc12_27, %int.convert_checked [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %int_0.loc12_29: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %.loc12_29.3: ref %i32 = array_index %x.var, %int_0.loc12_29 +// CHECK:STDOUT: %.loc12_29.4: init %i32 = initialize_from %.loc12_29.2 to %.loc12_29.3 [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc12_29.5: init %array_type = array_init (%.loc12_29.4) to %x.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc12_3.2: init %array_type = converted %.loc12_29.1, %.loc12_29.5 [concrete = constants.%array] // CHECK:STDOUT: assign %x.var, %.loc12_3.2 -// CHECK:STDOUT: %.loc12_17: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc12_22: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc12: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index 37f4cf449bfbf..ed69f1d5d6e7f 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -62,10 +62,10 @@ impl C as I where .V = () {} library "[[@TEST_NAME]]"; interface I(N:! Core.IntLiteral()) { - // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+3]]:12: error: array bound of -1 is negative [ArrayBoundNegative] - // CHECK:STDERR: let V:! [Self; N]; - // CHECK:STDERR: ^~~~ - let V:! [Self; N]; + // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+3]]:17: error: array bound of -1 is negative [ArrayBoundNegative] + // CHECK:STDERR: let V:! array(Self, N); + // CHECK:STDERR: ^~~~ + let V:! array(Self, N); } // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+4]]:24: note: in `V` used here [ResolvingSpecificHere] diff --git a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon index d2141c819e10e..4f7df849a7641 100644 --- a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon +++ b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon @@ -185,32 +185,32 @@ class FDifferentParamName { } interface SelfNested { - fn F(x: (Self*, {.x: Self, .y: i32})) -> [Self; 4]; + fn F(x: (Self*, {.x: Self, .y: i32})) -> array(Self, 4); } class SelfNestedBadParam { impl as SelfNested { // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE+7]]:10: error: type `(SelfNestedBadParam*, {.x: i32, .y: i32})` of parameter 1 in redeclaration differs from previous parameter type `(SelfNestedBadParam*, {.x: SelfNestedBadParam, .y: i32})` [RedeclParamDiffersType] - // CHECK:STDERR: fn F(x: (SelfNestedBadParam*, {.x: i32, .y: i32})) -> [SelfNestedBadParam; 4]; + // CHECK:STDERR: fn F(x: (SelfNestedBadParam*, {.x: i32, .y: i32})) -> array(SelfNestedBadParam, 4); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE-8]]:8: note: previous declaration's corresponding parameter here [RedeclParamPrevious] - // CHECK:STDERR: fn F(x: (Self*, {.x: Self, .y: i32})) -> [Self; 4]; + // CHECK:STDERR: fn F(x: (Self*, {.x: Self, .y: i32})) -> array(Self, 4); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - fn F(x: (SelfNestedBadParam*, {.x: i32, .y: i32})) -> [SelfNestedBadParam; 4]; + fn F(x: (SelfNestedBadParam*, {.x: i32, .y: i32})) -> array(SelfNestedBadParam, 4); } } class SelfNestedBadReturnType { impl as SelfNested { // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE+7]]:5: error: function redeclaration differs because return type is `[SelfNestedBadParam; 4]` [FunctionRedeclReturnTypeDiffers] - // CHECK:STDERR: fn F(x: (SelfNestedBadReturnType*, {.x: SelfNestedBadReturnType, .y: i32})) -> [SelfNestedBadParam; 4]; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fn F(x: (SelfNestedBadReturnType*, {.x: SelfNestedBadReturnType, .y: i32})) -> array(SelfNestedBadParam, 4); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE-21]]:3: note: previously declared with return type `[SelfNestedBadReturnType; 4]` [FunctionRedeclReturnTypePrevious] - // CHECK:STDERR: fn F(x: (Self*, {.x: Self, .y: i32})) -> [Self; 4]; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fn F(x: (Self*, {.x: Self, .y: i32})) -> array(Self, 4); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - fn F(x: (SelfNestedBadReturnType*, {.x: SelfNestedBadReturnType, .y: i32})) -> [SelfNestedBadParam; 4]; + fn F(x: (SelfNestedBadReturnType*, {.x: SelfNestedBadReturnType, .y: i32})) -> array(SelfNestedBadParam, 4); } } @@ -437,14 +437,14 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %F.decl: %F.type.6ed = fn_decl @F.13 [concrete = constants.%F.998] { // CHECK:STDOUT: %x.patt: @F.13.%tuple.type (%tuple.type.229) = binding_pattern x // CHECK:STDOUT: %x.param_patt: @F.13.%tuple.type (%tuple.type.229) = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: %return.patt: @F.13.%array_type.loc188_52.1 (%array_type.873) = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: @F.13.%array_type.loc188_52.1 (%array_type.873) = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: @F.13.%array_type.loc188_57.1 (%array_type.873) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @F.13.%array_type.loc188_57.1 (%array_type.873) = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.ref.loc188_45: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.2ff)] +// CHECK:STDOUT: %Self.ref.loc188_50: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.2ff)] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] -// CHECK:STDOUT: %Self.as_type.loc188_45: type = facet_access_type %Self.ref.loc188_45 [symbolic = %Self.as_type.loc188_16.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc188_45: type = converted %Self.ref.loc188_45, %Self.as_type.loc188_45 [symbolic = %Self.as_type.loc188_16.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %array_type.loc188_52.2: type = array_type %int_4, %Self.as_type [symbolic = %array_type.loc188_52.1 (constants.%array_type.873)] +// CHECK:STDOUT: %Self.as_type.loc188_50: type = facet_access_type %Self.ref.loc188_50 [symbolic = %Self.as_type.loc188_16.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %.loc188_50: type = converted %Self.ref.loc188_50, %Self.as_type.loc188_50 [symbolic = %Self.as_type.loc188_16.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %array_type.loc188_57.2: type = array_type %int_4, %Self.as_type [symbolic = %array_type.loc188_57.1 (constants.%array_type.873)] // CHECK:STDOUT: %x.param: @F.13.%tuple.type (%tuple.type.229) = value_param runtime_param0 // CHECK:STDOUT: %.loc188_38.1: type = splice_block %.loc188_38.3 [symbolic = %tuple.type (constants.%tuple.type.229)] { // CHECK:STDOUT: %Self.ref.loc188_12: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.2ff)] @@ -461,8 +461,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %.loc188_38.3: type = converted %.loc188_38.2, constants.%tuple.type.229 [symbolic = %tuple.type (constants.%tuple.type.229)] // CHECK:STDOUT: } // CHECK:STDOUT: %x: @F.13.%tuple.type (%tuple.type.229) = bind_name x, %x.param -// CHECK:STDOUT: %return.param: ref @F.13.%array_type.loc188_52.1 (%array_type.873) = out_param runtime_param1 -// CHECK:STDOUT: %return: ref @F.13.%array_type.loc188_52.1 (%array_type.873) = return_slot %return.param +// CHECK:STDOUT: %return.param: ref @F.13.%array_type.loc188_57.1 (%array_type.873) = out_param runtime_param1 +// CHECK:STDOUT: %return: ref @F.13.%array_type.loc188_57.1 (%array_type.873) = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %SelfNested.assoc_type = assoc_entity element0, %F.decl [concrete = constants.%assoc0.a58] // CHECK:STDOUT: @@ -764,7 +764,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %return.patt: %array_type.a41 = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %array_type.a41 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %SelfNestedBadParam.ref.loc200_60: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] +// CHECK:STDOUT: %SelfNestedBadParam.ref.loc200_65: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] // CHECK:STDOUT: %array_type: type = array_type %int_4, %SelfNestedBadParam [concrete = constants.%array_type.a41] // CHECK:STDOUT: %x.param: %tuple.type.a7d = value_param runtime_param0 @@ -1075,9 +1075,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %ptr.loc188_16.1: type = ptr_type @F.13.%Self.as_type.loc188_16.1 (%Self.as_type) [symbolic = %ptr.loc188_16.1 (constants.%ptr.e87)] // CHECK:STDOUT: %struct_type.x.y.loc188_37.1: type = struct_type {.x: @F.13.%Self.as_type.loc188_16.1 (%Self.as_type), .y: %i32} [symbolic = %struct_type.x.y.loc188_37.1 (constants.%struct_type.x.y.81e)] // CHECK:STDOUT: %tuple.type: type = tuple_type (@F.13.%ptr.loc188_16.1 (%ptr.e87), @F.13.%struct_type.x.y.loc188_37.1 (%struct_type.x.y.81e)) [symbolic = %tuple.type (constants.%tuple.type.229)] -// CHECK:STDOUT: %array_type.loc188_52.1: type = array_type constants.%int_4, @F.13.%Self.as_type.loc188_16.1 (%Self.as_type) [symbolic = %array_type.loc188_52.1 (constants.%array_type.873)] +// CHECK:STDOUT: %array_type.loc188_57.1: type = array_type constants.%int_4, @F.13.%Self.as_type.loc188_16.1 (%Self.as_type) [symbolic = %array_type.loc188_57.1 (constants.%array_type.873)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: @F.13.%tuple.type (%tuple.type.229)) -> @F.13.%array_type.loc188_52.1 (%array_type.873); +// CHECK:STDOUT: fn(%x.param_patt: @F.13.%tuple.type (%tuple.type.229)) -> @F.13.%array_type.loc188_57.1 (%array_type.873); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F.14(%x.param_patt: %tuple.type.a7d) -> %array_type.a41; @@ -1114,7 +1114,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %ptr.loc188_16.1 => constants.%ptr.e87 // CHECK:STDOUT: %struct_type.x.y.loc188_37.1 => constants.%struct_type.x.y.81e // CHECK:STDOUT: %tuple.type => constants.%tuple.type.229 -// CHECK:STDOUT: %array_type.loc188_52.1 => constants.%array_type.873 +// CHECK:STDOUT: %array_type.loc188_57.1 => constants.%array_type.873 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F.13(constants.%SelfNested.facet.61c) { @@ -1123,7 +1123,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %ptr.loc188_16.1 => constants.%ptr.4cd // CHECK:STDOUT: %struct_type.x.y.loc188_37.1 => constants.%struct_type.x.y.a89 // CHECK:STDOUT: %tuple.type => constants.%tuple.type.9c9 -// CHECK:STDOUT: %array_type.loc188_52.1 => constants.%array_type.a41 +// CHECK:STDOUT: %array_type.loc188_57.1 => constants.%array_type.a41 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F.13(constants.%SelfNested.facet.01f) { @@ -1132,6 +1132,6 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %ptr.loc188_16.1 => constants.%ptr.612 // CHECK:STDOUT: %struct_type.x.y.loc188_37.1 => constants.%struct_type.x.y.ac5 // CHECK:STDOUT: %tuple.type => constants.%tuple.type.eb9 -// CHECK:STDOUT: %array_type.loc188_52.1 => constants.%array_type.126 +// CHECK:STDOUT: %array_type.loc188_57.1 => constants.%array_type.126 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon index 48d71a52426da..1e63545e1f43a 100644 --- a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon @@ -69,18 +69,18 @@ library "[[@TEST_NAME]]"; interface I { let N:! i32; - // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+7]]:32: error: cannot implicitly convert from `` to `Core.IntLiteral` [ImplicitAsConversionFailure] - // CHECK:STDERR: fn F[self: Self]() -> [bool; N]; - // CHECK:STDERR: ^ - // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+4]]:32: note: type `` does not implement interface `Core.ImplicitAs(Core.IntLiteral)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: fn F[self: Self]() -> [bool; N]; - // CHECK:STDERR: ^ + // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+7]]:37: error: cannot implicitly convert from `` to `Core.IntLiteral` [ImplicitAsConversionFailure] + // CHECK:STDERR: fn F[self: Self]() -> array(bool, N); + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_todo_associated_int_in_array.carbon:[[@LINE+4]]:37: note: type `` does not implement interface `Core.ImplicitAs(Core.IntLiteral)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: fn F[self: Self]() -> array(bool, N); + // CHECK:STDERR: ^ // CHECK:STDERR: - fn F[self: Self]() -> [bool; N]; + fn F[self: Self]() -> array(bool, N); } impl () as I where .N = 2 { - fn F[self: Self]() -> [bool; 2] { return (true, false); } + fn F[self: Self]() -> array(bool, 2) { return (true, false); } } // CHECK:STDOUT: --- fail_todo_associated_type_in_signature.carbon @@ -549,9 +549,9 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } { // CHECK:STDOUT: %bool.make_type: init type = call constants.%Bool() [concrete = bool] // CHECK:STDOUT: %N.ref: %I.assoc_type = name_ref N, @N.%assoc0 [concrete = constants.%assoc0.73c] -// CHECK:STDOUT: %.loc12_26.1: type = value_of_initializer %bool.make_type [concrete = bool] -// CHECK:STDOUT: %.loc12_26.2: type = converted %bool.make_type, %.loc12_26.1 [concrete = bool] -// CHECK:STDOUT: %.loc12_32: Core.IntLiteral = converted %N.ref, [concrete = ] +// CHECK:STDOUT: %.loc12_31.1: type = value_of_initializer %bool.make_type [concrete = bool] +// CHECK:STDOUT: %.loc12_31.2: type = converted %bool.make_type, %.loc12_31.1 [concrete = bool] +// CHECK:STDOUT: %.loc12_37: Core.IntLiteral = converted %N.ref, [concrete = ] // CHECK:STDOUT: %array_type: type = array_type , bool [concrete = ] // CHECK:STDOUT: %self.param: @F.1.%Self.as_type.loc12_14.1 (%Self.as_type.b70) = value_param runtime_param0 // CHECK:STDOUT: %.loc12_14.1: type = splice_block %.loc12_14.2 [symbolic = %Self.as_type.loc12_14.1 (constants.%Self.as_type.b70)] { @@ -585,8 +585,8 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } { // CHECK:STDOUT: %bool.make_type: init type = call constants.%Bool() [concrete = bool] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc16_26.1: type = value_of_initializer %bool.make_type [concrete = bool] -// CHECK:STDOUT: %.loc16_26.2: type = converted %bool.make_type, %.loc16_26.1 [concrete = bool] +// CHECK:STDOUT: %.loc16_31.1: type = value_of_initializer %bool.make_type [concrete = bool] +// CHECK:STDOUT: %.loc16_31.2: type = converted %bool.make_type, %.loc16_31.1 [concrete = bool] // CHECK:STDOUT: %array_type: type = array_type %int_2, bool [concrete = constants.%array_type] // CHECK:STDOUT: %self.param: %empty_tuple.type = value_param runtime_param0 // CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.44.%.loc15_7.2 [concrete = constants.%empty_tuple.type] @@ -611,16 +611,16 @@ impl () as I where .N = 2 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true] // CHECK:STDOUT: %false: bool = bool_literal false [concrete = constants.%false] -// CHECK:STDOUT: %.loc16_56.1: %tuple.type = tuple_literal (%true, %false) +// CHECK:STDOUT: %.loc16_61.1: %tuple.type = tuple_literal (%true, %false) // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc16_56.2: ref bool = array_index %return, %int_0 -// CHECK:STDOUT: %.loc16_56.3: init bool = initialize_from %true to %.loc16_56.2 [concrete = constants.%true] +// CHECK:STDOUT: %.loc16_61.2: ref bool = array_index %return, %int_0 +// CHECK:STDOUT: %.loc16_61.3: init bool = initialize_from %true to %.loc16_61.2 [concrete = constants.%true] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc16_56.4: ref bool = array_index %return, %int_1 -// CHECK:STDOUT: %.loc16_56.5: init bool = initialize_from %false to %.loc16_56.4 [concrete = constants.%false] -// CHECK:STDOUT: %.loc16_56.6: init %array_type = array_init (%.loc16_56.3, %.loc16_56.5) to %return [concrete = constants.%array] -// CHECK:STDOUT: %.loc16_57: init %array_type = converted %.loc16_56.1, %.loc16_56.6 [concrete = constants.%array] -// CHECK:STDOUT: return %.loc16_57 to %return +// CHECK:STDOUT: %.loc16_61.4: ref bool = array_index %return, %int_1 +// CHECK:STDOUT: %.loc16_61.5: init bool = initialize_from %false to %.loc16_61.4 [concrete = constants.%false] +// CHECK:STDOUT: %.loc16_61.6: init %array_type = array_init (%.loc16_61.3, %.loc16_61.5) to %return [concrete = constants.%array] +// CHECK:STDOUT: %.loc16_62: init %array_type = converted %.loc16_61.1, %.loc16_61.6 [concrete = constants.%array] +// CHECK:STDOUT: return %.loc16_62 to %return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%Self.826) {} diff --git a/toolchain/check/testdata/index/array_element_access.carbon b/toolchain/check/testdata/index/array_element_access.carbon index ada810ece5765..f2c8a2d1c0263 100644 --- a/toolchain/check/testdata/index/array_element_access.carbon +++ b/toolchain/check/testdata/index/array_element_access.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/array_element_access.carbon -var a: [i32; 2] = (12, 24); +var a: array(i32, 2) = (12, 24); var b: i32 = 1; var c: i32 = a[0]; var d: i32 = a[b]; @@ -70,7 +70,7 @@ var d: i32 = a[b]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] @@ -113,25 +113,25 @@ var d: i32 = a[b]; // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_12: Core.IntLiteral = int_value 12 [concrete = constants.%int_12.6a3] // CHECK:STDOUT: %int_24: Core.IntLiteral = int_value 24 [concrete = constants.%int_24.e3c] -// CHECK:STDOUT: %.loc11_26.1: %tuple.type = tuple_literal (%int_12, %int_24) -// CHECK:STDOUT: %impl.elem0.loc11_26.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_26.1: = bound_method %int_12, %impl.elem0.loc11_26.1 [concrete = constants.%Convert.bound.221] -// CHECK:STDOUT: %specific_fn.loc11_26.1: = specific_function %bound_method.loc11_26.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.9a9] -// CHECK:STDOUT: %int.convert_checked.loc11_26.1: init %i32 = call %specific_fn.loc11_26.1(%int_12) [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_26.2: init %i32 = converted %int_12, %int.convert_checked.loc11_26.1 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_31.1: %tuple.type = tuple_literal (%int_12, %int_24) +// CHECK:STDOUT: %impl.elem0.loc11_31.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_31.1: = bound_method %int_12, %impl.elem0.loc11_31.1 [concrete = constants.%Convert.bound.221] +// CHECK:STDOUT: %specific_fn.loc11_31.1: = specific_function %bound_method.loc11_31.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.9a9] +// CHECK:STDOUT: %int.convert_checked.loc11_31.1: init %i32 = call %specific_fn.loc11_31.1(%int_12) [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_31.2: init %i32 = converted %int_12, %int.convert_checked.loc11_31.1 [concrete = constants.%int_12.1e1] // CHECK:STDOUT: %int_0.loc11: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc11_26.3: ref %i32 = array_index file.%a.var, %int_0.loc11 -// CHECK:STDOUT: %.loc11_26.4: init %i32 = initialize_from %.loc11_26.2 to %.loc11_26.3 [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %impl.elem0.loc11_26.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_26.2: = bound_method %int_24, %impl.elem0.loc11_26.2 [concrete = constants.%Convert.bound.ef4] -// CHECK:STDOUT: %specific_fn.loc11_26.2: = specific_function %bound_method.loc11_26.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c4e] -// CHECK:STDOUT: %int.convert_checked.loc11_26.2: init %i32 = call %specific_fn.loc11_26.2(%int_24) [concrete = constants.%int_24.365] -// CHECK:STDOUT: %.loc11_26.5: init %i32 = converted %int_24, %int.convert_checked.loc11_26.2 [concrete = constants.%int_24.365] +// CHECK:STDOUT: %.loc11_31.3: ref %i32 = array_index file.%a.var, %int_0.loc11 +// CHECK:STDOUT: %.loc11_31.4: init %i32 = initialize_from %.loc11_31.2 to %.loc11_31.3 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %impl.elem0.loc11_31.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_31.2: = bound_method %int_24, %impl.elem0.loc11_31.2 [concrete = constants.%Convert.bound.ef4] +// CHECK:STDOUT: %specific_fn.loc11_31.2: = specific_function %bound_method.loc11_31.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.c4e] +// CHECK:STDOUT: %int.convert_checked.loc11_31.2: init %i32 = call %specific_fn.loc11_31.2(%int_24) [concrete = constants.%int_24.365] +// CHECK:STDOUT: %.loc11_31.5: init %i32 = converted %int_24, %int.convert_checked.loc11_31.2 [concrete = constants.%int_24.365] // CHECK:STDOUT: %int_1.loc11: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc11_26.6: ref %i32 = array_index file.%a.var, %int_1.loc11 -// CHECK:STDOUT: %.loc11_26.7: init %i32 = initialize_from %.loc11_26.5 to %.loc11_26.6 [concrete = constants.%int_24.365] -// CHECK:STDOUT: %.loc11_26.8: init %array_type = array_init (%.loc11_26.4, %.loc11_26.7) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_26.1, %.loc11_26.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_31.6: ref %i32 = array_index file.%a.var, %int_1.loc11 +// CHECK:STDOUT: %.loc11_31.7: init %i32 = initialize_from %.loc11_31.5 to %.loc11_31.6 [concrete = constants.%int_24.365] +// CHECK:STDOUT: %.loc11_31.8: init %array_type = array_init (%.loc11_31.4, %.loc11_31.7) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_31.1, %.loc11_31.8 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %int_1.loc12: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %impl.elem0.loc12: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] diff --git a/toolchain/check/testdata/index/expr_category.carbon b/toolchain/check/testdata/index/expr_category.carbon index 72196929e970e..a9067947c07fe 100644 --- a/toolchain/check/testdata/index/expr_category.carbon +++ b/toolchain/check/testdata/index/expr_category.carbon @@ -8,18 +8,18 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/expr_category.carbon -fn F() -> [i32; 3]; +fn F() -> array(i32, 3); -fn G(b: [i32; 3]) { - var a: [i32; 3] = (1, 2, 3); +fn G(b: array(i32, 3)) { + var a: array(i32, 3) = (1, 2, 3); // Indexing a durable array reference gives a durable reference. var pa: i32* = &a[0]; a[0] = 4; } -fn ValueBinding(b: [i32; 3]) { - var a: [i32; 3] = (1, 2, 3); +fn ValueBinding(b: array(i32, 3)) { + var a: array(i32, 3) = (1, 2, 3); // Index but don't do anything else so we can check that a value binding is // produced when appropriate. @@ -137,42 +137,42 @@ fn ValueBinding(b: [i32; 3]) { // CHECK:STDOUT: %.loc14_3.1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %int_1.loc14_22: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc14_25: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_3.loc14_28: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc14_29.1: %tuple.type = tuple_literal (%int_1.loc14_22, %int_2.loc14_25, %int_3.loc14_28) -// CHECK:STDOUT: %impl.elem0.loc14_29.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_29.1: = bound_method %int_1.loc14_22, %impl.elem0.loc14_29.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc14_29.1: = specific_function %bound_method.loc14_29.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc14_29.1: init %i32 = call %specific_fn.loc14_29.1(%int_1.loc14_22) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_29.2: init %i32 = converted %int_1.loc14_22, %int.convert_checked.loc14_29.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int_1.loc14_27: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc14_30: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_3.loc14_33: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc14_34.1: %tuple.type = tuple_literal (%int_1.loc14_27, %int_2.loc14_30, %int_3.loc14_33) +// CHECK:STDOUT: %impl.elem0.loc14_34.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_34.1: = bound_method %int_1.loc14_27, %impl.elem0.loc14_34.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc14_34.1: = specific_function %bound_method.loc14_34.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc14_34.1: init %i32 = call %specific_fn.loc14_34.1(%int_1.loc14_27) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc14_34.2: init %i32 = converted %int_1.loc14_27, %int.convert_checked.loc14_34.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0.loc14: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc14_29.3: ref %i32 = array_index %a.var, %int_0.loc14 -// CHECK:STDOUT: %.loc14_29.4: init %i32 = initialize_from %.loc14_29.2 to %.loc14_29.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc14_29.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_29.2: = bound_method %int_2.loc14_25, %impl.elem0.loc14_29.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc14_29.2: = specific_function %bound_method.loc14_29.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc14_29.2: init %i32 = call %specific_fn.loc14_29.2(%int_2.loc14_25) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc14_29.5: init %i32 = converted %int_2.loc14_25, %int.convert_checked.loc14_29.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc14_29: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc14_29.6: ref %i32 = array_index %a.var, %int_1.loc14_29 -// CHECK:STDOUT: %.loc14_29.7: init %i32 = initialize_from %.loc14_29.5 to %.loc14_29.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc14_29.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc14_29.3: = bound_method %int_3.loc14_28, %impl.elem0.loc14_29.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc14_29.3: = specific_function %bound_method.loc14_29.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc14_29.3: init %i32 = call %specific_fn.loc14_29.3(%int_3.loc14_28) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc14_29.8: init %i32 = converted %int_3.loc14_28, %int.convert_checked.loc14_29.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc14_29: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc14_29.9: ref %i32 = array_index %a.var, %int_2.loc14_29 -// CHECK:STDOUT: %.loc14_29.10: init %i32 = initialize_from %.loc14_29.8 to %.loc14_29.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc14_29.11: init %array_type = array_init (%.loc14_29.4, %.loc14_29.7, %.loc14_29.10) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %.loc14_29.1, %.loc14_29.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc14_34.3: ref %i32 = array_index %a.var, %int_0.loc14 +// CHECK:STDOUT: %.loc14_34.4: init %i32 = initialize_from %.loc14_34.2 to %.loc14_34.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc14_34.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_34.2: = bound_method %int_2.loc14_30, %impl.elem0.loc14_34.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc14_34.2: = specific_function %bound_method.loc14_34.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc14_34.2: init %i32 = call %specific_fn.loc14_34.2(%int_2.loc14_30) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc14_34.5: init %i32 = converted %int_2.loc14_30, %int.convert_checked.loc14_34.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc14_34: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc14_34.6: ref %i32 = array_index %a.var, %int_1.loc14_34 +// CHECK:STDOUT: %.loc14_34.7: init %i32 = initialize_from %.loc14_34.5 to %.loc14_34.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc14_34.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc14_34.3: = bound_method %int_3.loc14_33, %impl.elem0.loc14_34.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc14_34.3: = specific_function %bound_method.loc14_34.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc14_34.3: init %i32 = call %specific_fn.loc14_34.3(%int_3.loc14_33) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc14_34.8: init %i32 = converted %int_3.loc14_33, %int.convert_checked.loc14_34.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc14_34: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc14_34.9: ref %i32 = array_index %a.var, %int_2.loc14_34 +// CHECK:STDOUT: %.loc14_34.10: init %i32 = initialize_from %.loc14_34.8 to %.loc14_34.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc14_34.11: init %array_type = array_init (%.loc14_34.4, %.loc14_34.7, %.loc14_34.10) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc14_3.2: init %array_type = converted %.loc14_34.1, %.loc14_34.11 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc14_3.2 -// CHECK:STDOUT: %.loc14_17: type = splice_block %array_type.loc14 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc14_22: type = splice_block %array_type.loc14 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_3.loc14_16: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type.loc14: type = array_type %int_3.loc14_16, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %int_3.loc14_21: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type.loc14: type = array_type %int_3.loc14_21, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %array_type = bind_name a, %a.var // CHECK:STDOUT: name_binding_decl { @@ -227,42 +227,42 @@ fn ValueBinding(b: [i32; 3]) { // CHECK:STDOUT: %.loc22_3.1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %int_1.loc22_22: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2.loc22_25: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_3.loc22_28: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc22_29.1: %tuple.type = tuple_literal (%int_1.loc22_22, %int_2.loc22_25, %int_3.loc22_28) -// CHECK:STDOUT: %impl.elem0.loc22_29.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc22_29.1: = bound_method %int_1.loc22_22, %impl.elem0.loc22_29.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc22_29.1: = specific_function %bound_method.loc22_29.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] -// CHECK:STDOUT: %int.convert_checked.loc22_29.1: init %i32 = call %specific_fn.loc22_29.1(%int_1.loc22_22) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc22_29.2: init %i32 = converted %int_1.loc22_22, %int.convert_checked.loc22_29.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int_1.loc22_27: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc22_30: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_3.loc22_33: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc22_34.1: %tuple.type = tuple_literal (%int_1.loc22_27, %int_2.loc22_30, %int_3.loc22_33) +// CHECK:STDOUT: %impl.elem0.loc22_34.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc22_34.1: = bound_method %int_1.loc22_27, %impl.elem0.loc22_34.1 [concrete = constants.%Convert.bound.ab5] +// CHECK:STDOUT: %specific_fn.loc22_34.1: = specific_function %bound_method.loc22_34.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c] +// CHECK:STDOUT: %int.convert_checked.loc22_34.1: init %i32 = call %specific_fn.loc22_34.1(%int_1.loc22_27) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc22_34.2: init %i32 = converted %int_1.loc22_27, %int.convert_checked.loc22_34.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %int_0.loc22: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] -// CHECK:STDOUT: %.loc22_29.3: ref %i32 = array_index %a.var, %int_0.loc22 -// CHECK:STDOUT: %.loc22_29.4: init %i32 = initialize_from %.loc22_29.2 to %.loc22_29.3 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc22_29.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc22_29.2: = bound_method %int_2.loc22_25, %impl.elem0.loc22_29.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc22_29.2: = specific_function %bound_method.loc22_29.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] -// CHECK:STDOUT: %int.convert_checked.loc22_29.2: init %i32 = call %specific_fn.loc22_29.2(%int_2.loc22_25) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc22_29.5: init %i32 = converted %int_2.loc22_25, %int.convert_checked.loc22_29.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %int_1.loc22_29: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %.loc22_29.6: ref %i32 = array_index %a.var, %int_1.loc22_29 -// CHECK:STDOUT: %.loc22_29.7: init %i32 = initialize_from %.loc22_29.5 to %.loc22_29.6 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc22_29.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc22_29.3: = bound_method %int_3.loc22_28, %impl.elem0.loc22_29.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc22_29.3: = specific_function %bound_method.loc22_29.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] -// CHECK:STDOUT: %int.convert_checked.loc22_29.3: init %i32 = call %specific_fn.loc22_29.3(%int_3.loc22_28) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc22_29.8: init %i32 = converted %int_3.loc22_28, %int.convert_checked.loc22_29.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %int_2.loc22_29: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %.loc22_29.9: ref %i32 = array_index %a.var, %int_2.loc22_29 -// CHECK:STDOUT: %.loc22_29.10: init %i32 = initialize_from %.loc22_29.8 to %.loc22_29.9 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc22_29.11: init %array_type = array_init (%.loc22_29.4, %.loc22_29.7, %.loc22_29.10) to %a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc22_3.2: init %array_type = converted %.loc22_29.1, %.loc22_29.11 [concrete = constants.%array] +// CHECK:STDOUT: %.loc22_34.3: ref %i32 = array_index %a.var, %int_0.loc22 +// CHECK:STDOUT: %.loc22_34.4: init %i32 = initialize_from %.loc22_34.2 to %.loc22_34.3 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc22_34.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc22_34.2: = bound_method %int_2.loc22_30, %impl.elem0.loc22_34.2 [concrete = constants.%Convert.bound.ef9] +// CHECK:STDOUT: %specific_fn.loc22_34.2: = specific_function %bound_method.loc22_34.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787] +// CHECK:STDOUT: %int.convert_checked.loc22_34.2: init %i32 = call %specific_fn.loc22_34.2(%int_2.loc22_30) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc22_34.5: init %i32 = converted %int_2.loc22_30, %int.convert_checked.loc22_34.2 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %int_1.loc22_34: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc22_34.6: ref %i32 = array_index %a.var, %int_1.loc22_34 +// CHECK:STDOUT: %.loc22_34.7: init %i32 = initialize_from %.loc22_34.5 to %.loc22_34.6 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc22_34.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc22_34.3: = bound_method %int_3.loc22_33, %impl.elem0.loc22_34.3 [concrete = constants.%Convert.bound.b30] +// CHECK:STDOUT: %specific_fn.loc22_34.3: = specific_function %bound_method.loc22_34.3, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.b42] +// CHECK:STDOUT: %int.convert_checked.loc22_34.3: init %i32 = call %specific_fn.loc22_34.3(%int_3.loc22_33) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc22_34.8: init %i32 = converted %int_3.loc22_33, %int.convert_checked.loc22_34.3 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %int_2.loc22_34: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc22_34.9: ref %i32 = array_index %a.var, %int_2.loc22_34 +// CHECK:STDOUT: %.loc22_34.10: init %i32 = initialize_from %.loc22_34.8 to %.loc22_34.9 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc22_34.11: init %array_type = array_init (%.loc22_34.4, %.loc22_34.7, %.loc22_34.10) to %a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc22_3.2: init %array_type = converted %.loc22_34.1, %.loc22_34.11 [concrete = constants.%array] // CHECK:STDOUT: assign %a.var, %.loc22_3.2 -// CHECK:STDOUT: %.loc22_17: type = splice_block %array_type.loc22 [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc22_22: type = splice_block %array_type.loc22 [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_3.loc22_16: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %array_type.loc22: type = array_type %int_3.loc22_16, %i32 [concrete = constants.%array_type] +// CHECK:STDOUT: %int_3.loc22_21: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %array_type.loc22: type = array_type %int_3.loc22_21, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %array_type = bind_name a, %a.var // CHECK:STDOUT: %a.ref: ref %array_type = name_ref a, %a diff --git a/toolchain/check/testdata/index/fail_array_large_index.carbon b/toolchain/check/testdata/index/fail_array_large_index.carbon index 7f330810ca796..0f2eb9bf8c2c6 100644 --- a/toolchain/check/testdata/index/fail_array_large_index.carbon +++ b/toolchain/check/testdata/index/fail_array_large_index.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/fail_array_large_index.carbon -var a: [i32; 1] = (12,); +var a: array(i32, 1) = (12,); // CHECK:STDERR: fail_array_large_index.carbon:[[@LINE+4]]:16: error: array index `1` is past the end of type `[i32; 1]` [ArrayIndexOutOfBounds] // CHECK:STDERR: var b: i32 = a[1]; @@ -74,7 +74,7 @@ var c: i32 = a[0x7FFF_FFFF]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -106,17 +106,17 @@ var c: i32 = a[0x7FFF_FFFF]; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_12: Core.IntLiteral = int_value 12 [concrete = constants.%int_12.6a3] -// CHECK:STDOUT: %.loc11_23.1: %tuple.type = tuple_literal (%int_12) +// CHECK:STDOUT: %.loc11_28.1: %tuple.type = tuple_literal (%int_12) // CHECK:STDOUT: %impl.elem0.loc11: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] // CHECK:STDOUT: %bound_method.loc11: = bound_method %int_12, %impl.elem0.loc11 [concrete = constants.%Convert.bound.221] // CHECK:STDOUT: %specific_fn.loc11: = specific_function %bound_method.loc11, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.9a9] // CHECK:STDOUT: %int.convert_checked.loc11: init %i32 = call %specific_fn.loc11(%int_12) [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.2: init %i32 = converted %int_12, %int.convert_checked.loc11 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.2: init %i32 = converted %int_12, %int.convert_checked.loc11 [concrete = constants.%int_12.1e1] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_23.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_23.4: init %i32 = initialize_from %.loc11_23.2 to %.loc11_23.3 [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.5: init %array_type = array_init (%.loc11_23.4) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_23.1, %.loc11_23.5 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_28.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_28.4: init %i32 = initialize_from %.loc11_28.2 to %.loc11_28.3 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.5: init %array_type = array_init (%.loc11_28.4) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_28.1, %.loc11_28.5 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref.loc17: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] diff --git a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon index 2d654a29c9ae0..ac4d0245fc334 100644 --- a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon +++ b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/fail_array_non_int_indexing.carbon -var a: [i32; 1] = (12,); +var a: array(i32, 1) = (12,); // CHECK:STDERR: fail_array_non_int_indexing.carbon:[[@LINE+7]]:16: error: cannot implicitly convert from `f64` to `i32` [ImplicitAsConversionFailure] // CHECK:STDERR: var b: i32 = a[2.6]; // CHECK:STDERR: ^~~ @@ -63,7 +63,7 @@ var b: i32 = a[2.6]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] @@ -85,17 +85,17 @@ var b: i32 = a[2.6]; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_12: Core.IntLiteral = int_value 12 [concrete = constants.%int_12.6a3] -// CHECK:STDOUT: %.loc11_23.1: %tuple.type = tuple_literal (%int_12) +// CHECK:STDOUT: %.loc11_28.1: %tuple.type = tuple_literal (%int_12) // CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] // CHECK:STDOUT: %bound_method: = bound_method %int_12, %impl.elem0 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] // CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_12) [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.2: init %i32 = converted %int_12, %int.convert_checked [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.2: init %i32 = converted %int_12, %int.convert_checked [concrete = constants.%int_12.1e1] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_23.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_23.4: init %i32 = initialize_from %.loc11_23.2 to %.loc11_23.3 [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.5: init %array_type = array_init (%.loc11_23.4) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_23.1, %.loc11_23.5 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_28.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_28.4: init %i32 = initialize_from %.loc11_28.2 to %.loc11_28.3 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.5: init %array_type = array_init (%.loc11_28.4) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_28.1, %.loc11_28.5 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %float: f64 = float_literal 2.6000000000000001 [concrete = constants.%float] diff --git a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon index d53f44fd4af79..4daab3c109254 100644 --- a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon +++ b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon -var a: [i32; 1] = (12,); +var a: array(i32, 1) = (12,); // CHECK:STDERR: fail_array_out_of_bound_access.carbon:[[@LINE+4]]:16: error: array index `1` is past the end of type `[i32; 1]` [ArrayIndexOutOfBounds] // CHECK:STDERR: var b: i32 = a[1]; // CHECK:STDERR: ^ @@ -62,7 +62,7 @@ var b: i32 = a[1]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %a.patt // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %array_type = var a -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -84,17 +84,17 @@ var b: i32 = a[1]; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_12: Core.IntLiteral = int_value 12 [concrete = constants.%int_12.6a3] -// CHECK:STDOUT: %.loc11_23.1: %tuple.type = tuple_literal (%int_12) +// CHECK:STDOUT: %.loc11_28.1: %tuple.type = tuple_literal (%int_12) // CHECK:STDOUT: %impl.elem0.loc11: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] // CHECK:STDOUT: %bound_method.loc11: = bound_method %int_12, %impl.elem0.loc11 [concrete = constants.%Convert.bound.221] // CHECK:STDOUT: %specific_fn.loc11: = specific_function %bound_method.loc11, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.9a9] // CHECK:STDOUT: %int.convert_checked.loc11: init %i32 = call %specific_fn.loc11(%int_12) [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.2: init %i32 = converted %int_12, %int.convert_checked.loc11 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.2: init %i32 = converted %int_12, %int.convert_checked.loc11 [concrete = constants.%int_12.1e1] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_23.3: ref %i32 = array_index file.%a.var, %int_0 -// CHECK:STDOUT: %.loc11_23.4: init %i32 = initialize_from %.loc11_23.2 to %.loc11_23.3 [concrete = constants.%int_12.1e1] -// CHECK:STDOUT: %.loc11_23.5: init %array_type = array_init (%.loc11_23.4) to file.%a.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_23.1, %.loc11_23.5 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_28.3: ref %i32 = array_index file.%a.var, %int_0 +// CHECK:STDOUT: %.loc11_28.4: init %i32 = initialize_from %.loc11_28.2 to %.loc11_28.3 [concrete = constants.%int_12.1e1] +// CHECK:STDOUT: %.loc11_28.5: init %array_type = array_init (%.loc11_28.4) to file.%a.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_28.1, %.loc11_28.5 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc11_1 // CHECK:STDOUT: %a.ref: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] diff --git a/toolchain/check/testdata/index/fail_expr_category.carbon b/toolchain/check/testdata/index/fail_expr_category.carbon index 7df85bf40271b..67dabc908b945 100644 --- a/toolchain/check/testdata/index/fail_expr_category.carbon +++ b/toolchain/check/testdata/index/fail_expr_category.carbon @@ -8,9 +8,9 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/fail_expr_category.carbon -fn F() -> [i32; 3]; +fn F() -> array(i32, 3); -fn G(b: [i32; 3]) { +fn G(b: array(i32, 3)) { // Indexing an array value gives a value. // CHECK:STDERR: fail_expr_category.carbon:[[@LINE+4]]:18: error: cannot take the address of non-reference expression [AddrOfNonRef] // CHECK:STDERR: var pb: i32* = &b[0]; diff --git a/toolchain/check/testdata/index/fail_negative_indexing.carbon b/toolchain/check/testdata/index/fail_negative_indexing.carbon index b1a00bcce2103..dbb571c24ef7c 100644 --- a/toolchain/check/testdata/index/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/index/fail_negative_indexing.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/index/fail_negative_indexing.carbon -var c: [i32; 2] = (42, 42); +var c: array(i32, 2) = (42, 42); // CHECK:STDERR: fail_negative_indexing.carbon:[[@LINE+4]]:16: error: array index `-10` is past the end of type `[i32; 2]` [ArrayIndexOutOfBounds] // CHECK:STDERR: var d: i32 = c[-10]; // CHECK:STDERR: ^~~ @@ -75,7 +75,7 @@ var d: i32 = c[-10]; // CHECK:STDOUT: %.loc11_1: %array_type = var_pattern %c.patt // CHECK:STDOUT: } // CHECK:STDOUT: %c.var: ref %array_type = var c -// CHECK:STDOUT: %.loc11_15: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc11_20: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] @@ -96,27 +96,27 @@ var d: i32 = c[-10]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_42.loc11_20: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e] -// CHECK:STDOUT: %int_42.loc11_24: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e] -// CHECK:STDOUT: %.loc11_26.1: %tuple.type = tuple_literal (%int_42.loc11_20, %int_42.loc11_24) -// CHECK:STDOUT: %impl.elem0.loc11_26.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_26.1: = bound_method %int_42.loc11_20, %impl.elem0.loc11_26.1 [concrete = constants.%Convert.bound.132] -// CHECK:STDOUT: %specific_fn.loc11_26.1: = specific_function %bound_method.loc11_26.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.2f6] -// CHECK:STDOUT: %int.convert_checked.loc11_26.1: init %i32 = call %specific_fn.loc11_26.1(%int_42.loc11_20) [concrete = constants.%int_42.c68] -// CHECK:STDOUT: %.loc11_26.2: init %i32 = converted %int_42.loc11_20, %int.convert_checked.loc11_26.1 [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %int_42.loc11_25: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e] +// CHECK:STDOUT: %int_42.loc11_29: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e] +// CHECK:STDOUT: %.loc11_31.1: %tuple.type = tuple_literal (%int_42.loc11_25, %int_42.loc11_29) +// CHECK:STDOUT: %impl.elem0.loc11_31.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_31.1: = bound_method %int_42.loc11_25, %impl.elem0.loc11_31.1 [concrete = constants.%Convert.bound.132] +// CHECK:STDOUT: %specific_fn.loc11_31.1: = specific_function %bound_method.loc11_31.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.2f6] +// CHECK:STDOUT: %int.convert_checked.loc11_31.1: init %i32 = call %specific_fn.loc11_31.1(%int_42.loc11_25) [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %.loc11_31.2: init %i32 = converted %int_42.loc11_25, %int.convert_checked.loc11_31.1 [concrete = constants.%int_42.c68] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc11_26.3: ref %i32 = array_index file.%c.var, %int_0 -// CHECK:STDOUT: %.loc11_26.4: init %i32 = initialize_from %.loc11_26.2 to %.loc11_26.3 [concrete = constants.%int_42.c68] -// CHECK:STDOUT: %impl.elem0.loc11_26.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc11_26.2: = bound_method %int_42.loc11_24, %impl.elem0.loc11_26.2 [concrete = constants.%Convert.bound.132] -// CHECK:STDOUT: %specific_fn.loc11_26.2: = specific_function %bound_method.loc11_26.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.2f6] -// CHECK:STDOUT: %int.convert_checked.loc11_26.2: init %i32 = call %specific_fn.loc11_26.2(%int_42.loc11_24) [concrete = constants.%int_42.c68] -// CHECK:STDOUT: %.loc11_26.5: init %i32 = converted %int_42.loc11_24, %int.convert_checked.loc11_26.2 [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %.loc11_31.3: ref %i32 = array_index file.%c.var, %int_0 +// CHECK:STDOUT: %.loc11_31.4: init %i32 = initialize_from %.loc11_31.2 to %.loc11_31.3 [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %impl.elem0.loc11_31.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc11_31.2: = bound_method %int_42.loc11_29, %impl.elem0.loc11_31.2 [concrete = constants.%Convert.bound.132] +// CHECK:STDOUT: %specific_fn.loc11_31.2: = specific_function %bound_method.loc11_31.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.2f6] +// CHECK:STDOUT: %int.convert_checked.loc11_31.2: init %i32 = call %specific_fn.loc11_31.2(%int_42.loc11_29) [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %.loc11_31.5: init %i32 = converted %int_42.loc11_29, %int.convert_checked.loc11_31.2 [concrete = constants.%int_42.c68] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc11_26.6: ref %i32 = array_index file.%c.var, %int_1 -// CHECK:STDOUT: %.loc11_26.7: init %i32 = initialize_from %.loc11_26.5 to %.loc11_26.6 [concrete = constants.%int_42.c68] -// CHECK:STDOUT: %.loc11_26.8: init %array_type = array_init (%.loc11_26.4, %.loc11_26.7) to file.%c.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_26.1, %.loc11_26.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_31.6: ref %i32 = array_index file.%c.var, %int_1 +// CHECK:STDOUT: %.loc11_31.7: init %i32 = initialize_from %.loc11_31.5 to %.loc11_31.6 [concrete = constants.%int_42.c68] +// CHECK:STDOUT: %.loc11_31.8: init %array_type = array_init (%.loc11_31.4, %.loc11_31.7) to file.%c.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc11_1: init %array_type = converted %.loc11_31.1, %.loc11_31.8 [concrete = constants.%array] // CHECK:STDOUT: assign file.%c.var, %.loc11_1 // CHECK:STDOUT: %c.ref: ref %array_type = name_ref c, file.%c // CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete = constants.%int_10] diff --git a/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon b/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon index 3e05fdf724227..6740690d1f5c6 100644 --- a/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon +++ b/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon @@ -15,7 +15,7 @@ fn Main() { // CHECK:STDERR: 0[1]; - var non_tuple: [i32; 2] = (5, 5); + var non_tuple: array(i32, 2) = (5, 5); // CHECK:STDERR: fail_non_tuple_access.carbon:[[@LINE+4]]:20: error: type `[i32; 2]` does not support tuple indexing; only tuples can be indexed that way [TupleIndexOnANonTupleType] // CHECK:STDERR: var first: i32 = non_tuple.0; // CHECK:STDERR: ^~~~~~~~~~~ @@ -77,29 +77,29 @@ fn Main() { // CHECK:STDOUT: %.loc18_3.1: %array_type = var_pattern %non_tuple.patt // CHECK:STDOUT: } // CHECK:STDOUT: %non_tuple.var: ref %array_type = var non_tuple -// CHECK:STDOUT: %int_5.loc18_30: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] -// CHECK:STDOUT: %int_5.loc18_33: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] -// CHECK:STDOUT: %.loc18_34.1: %tuple.type = tuple_literal (%int_5.loc18_30, %int_5.loc18_33) -// CHECK:STDOUT: %impl.elem0.loc18_34.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc18_34.1: = bound_method %int_5.loc18_30, %impl.elem0.loc18_34.1 [concrete = constants.%Convert.bound] -// CHECK:STDOUT: %specific_fn.loc18_34.1: = specific_function %bound_method.loc18_34.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %int.convert_checked.loc18_34.1: init %i32 = call %specific_fn.loc18_34.1(%int_5.loc18_30) [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc18_34.2: init %i32 = converted %int_5.loc18_30, %int.convert_checked.loc18_34.1 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %int_5.loc18_35: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] +// CHECK:STDOUT: %int_5.loc18_38: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] +// CHECK:STDOUT: %.loc18_39.1: %tuple.type = tuple_literal (%int_5.loc18_35, %int_5.loc18_38) +// CHECK:STDOUT: %impl.elem0.loc18_39.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc18_39.1: = bound_method %int_5.loc18_35, %impl.elem0.loc18_39.1 [concrete = constants.%Convert.bound] +// CHECK:STDOUT: %specific_fn.loc18_39.1: = specific_function %bound_method.loc18_39.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] +// CHECK:STDOUT: %int.convert_checked.loc18_39.1: init %i32 = call %specific_fn.loc18_39.1(%int_5.loc18_35) [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc18_39.2: init %i32 = converted %int_5.loc18_35, %int.convert_checked.loc18_39.1 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %int_0.loc18: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %.loc18_34.3: ref %i32 = array_index %non_tuple.var, %int_0.loc18 -// CHECK:STDOUT: %.loc18_34.4: init %i32 = initialize_from %.loc18_34.2 to %.loc18_34.3 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %impl.elem0.loc18_34.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc18_34.2: = bound_method %int_5.loc18_33, %impl.elem0.loc18_34.2 [concrete = constants.%Convert.bound] -// CHECK:STDOUT: %specific_fn.loc18_34.2: = specific_function %bound_method.loc18_34.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %int.convert_checked.loc18_34.2: init %i32 = call %specific_fn.loc18_34.2(%int_5.loc18_33) [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc18_34.5: init %i32 = converted %int_5.loc18_33, %int.convert_checked.loc18_34.2 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc18_39.3: ref %i32 = array_index %non_tuple.var, %int_0.loc18 +// CHECK:STDOUT: %.loc18_39.4: init %i32 = initialize_from %.loc18_39.2 to %.loc18_39.3 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %impl.elem0.loc18_39.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %bound_method.loc18_39.2: = bound_method %int_5.loc18_38, %impl.elem0.loc18_39.2 [concrete = constants.%Convert.bound] +// CHECK:STDOUT: %specific_fn.loc18_39.2: = specific_function %bound_method.loc18_39.2, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] +// CHECK:STDOUT: %int.convert_checked.loc18_39.2: init %i32 = call %specific_fn.loc18_39.2(%int_5.loc18_38) [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc18_39.5: init %i32 = converted %int_5.loc18_38, %int.convert_checked.loc18_39.2 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %int_1.loc18: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %.loc18_34.6: ref %i32 = array_index %non_tuple.var, %int_1.loc18 -// CHECK:STDOUT: %.loc18_34.7: init %i32 = initialize_from %.loc18_34.5 to %.loc18_34.6 [concrete = constants.%int_5.0f6] -// CHECK:STDOUT: %.loc18_34.8: init %array_type = array_init (%.loc18_34.4, %.loc18_34.7) to %non_tuple.var [concrete = constants.%array] -// CHECK:STDOUT: %.loc18_3.2: init %array_type = converted %.loc18_34.1, %.loc18_34.8 [concrete = constants.%array] +// CHECK:STDOUT: %.loc18_39.6: ref %i32 = array_index %non_tuple.var, %int_1.loc18 +// CHECK:STDOUT: %.loc18_39.7: init %i32 = initialize_from %.loc18_39.5 to %.loc18_39.6 [concrete = constants.%int_5.0f6] +// CHECK:STDOUT: %.loc18_39.8: init %array_type = array_init (%.loc18_39.4, %.loc18_39.7) to %non_tuple.var [concrete = constants.%array] +// CHECK:STDOUT: %.loc18_3.2: init %array_type = converted %.loc18_39.1, %.loc18_39.8 [concrete = constants.%array] // CHECK:STDOUT: assign %non_tuple.var, %.loc18_3.2 -// CHECK:STDOUT: %.loc18_25: type = splice_block %array_type [concrete = constants.%array_type] { +// CHECK:STDOUT: %.loc18_30: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_32.loc18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index e6654c22dd1f3..9a58df5bf90eb 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -76,7 +76,7 @@ CARBON_DIAGNOSTIC_KIND(WrongRealLiteralExponent) // ============================================================================ CARBON_DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace) -CARBON_DIAGNOSTIC_KIND(ExpectedArraySemi) +CARBON_DIAGNOSTIC_KIND(ExpectedArrayComma) CARBON_DIAGNOSTIC_KIND(ExpectedCloseSymbol) CARBON_DIAGNOSTIC_KIND(ExpectedCodeBlock) CARBON_DIAGNOSTIC_KIND(ExpectedExpr) diff --git a/toolchain/lex/lex.cpp b/toolchain/lex/lex.cpp index eb73ddddd5f00..e7e098750c594 100644 --- a/toolchain/lex/lex.cpp +++ b/toolchain/lex/lex.cpp @@ -525,7 +525,7 @@ CARBON_DISPATCH_LEX_TOKEN(LexHash) CARBON_DISPATCH_LEX_TOKEN(LexNumericLiteral) CARBON_DISPATCH_LEX_TOKEN(LexStringLiteral) -// A custom dispatch functions that pre-select the symbol token to lex. +// A set of custom dispatch functions that pre-select the symbol token to lex. #define CARBON_DISPATCH_LEX_SYMBOL_TOKEN(LexMethod) \ static auto Dispatch##LexMethod##SymbolToken( \ Lexer& lexer, llvm::StringRef source_text, ssize_t position) -> void { \ diff --git a/toolchain/lex/lex.h b/toolchain/lex/lex.h index 9e901148e2d38..22019d45466d7 100644 --- a/toolchain/lex/lex.h +++ b/toolchain/lex/lex.h @@ -16,7 +16,8 @@ namespace Carbon::Lex { // // The provided source buffer must outlive any returned `TokenizedBuffer` // which will refer into the source. -auto Lex(SharedValueStores& value_stores, SourceBuffer& source, +auto Lex(SharedValueStores& value_stores, + SourceBuffer& source [[clang::lifetimebound]], DiagnosticConsumer& consumer) -> TokenizedBuffer; } // namespace Carbon::Lex diff --git a/toolchain/lex/testdata/numeric_literals.carbon b/toolchain/lex/testdata/numeric_literals.carbon index d92f14ac43de5..db92d8ee60a15 100644 --- a/toolchain/lex/testdata/numeric_literals.carbon +++ b/toolchain/lex/testdata/numeric_literals.carbon @@ -14,79 +14,81 @@ fn F() { -// CHECK:STDOUT: - { index: 1, kind: "Fn", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "fn", has_leading_space: true } -// CHECK:STDOUT: - { index: 2, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 4, indent: 1, spelling: "F", identifier: 0, has_leading_space: true } -// CHECK:STDOUT: - { index: 3, kind: "OpenParen", line: {{ *}}[[@LINE-3]], column: 5, indent: 1, spelling: "(", closing_token: 4 } -// CHECK:STDOUT: - { index: 4, kind: "CloseParen", line: {{ *}}[[@LINE-4]], column: 6, indent: 1, spelling: ")", opening_token: 3 } -// CHECK:STDOUT: - { index: 5, kind: "OpenCurlyBrace", line: {{ *}}[[@LINE-5]], column: 8, indent: 1, spelling: "{", closing_token: 54, has_leading_space: true } +// CHECK:STDOUT: - { index: 1, kind: "Fn", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "fn", has_leading_space: true } +// CHECK:STDOUT: - { index: 2, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 4, indent: 1, spelling: "F", identifier: 0, has_leading_space: true } +// CHECK:STDOUT: - { index: 3, kind: "OpenParen", line: {{ *}}[[@LINE-3]], column: 5, indent: 1, spelling: "(", closing_token: 4 } +// CHECK:STDOUT: - { index: 4, kind: "CloseParen", line: {{ *}}[[@LINE-4]], column: 6, indent: 1, spelling: ")", opening_token: 3 } +// CHECK:STDOUT: - { index: 5, kind: "OpenCurlyBrace", line: {{ *}}[[@LINE-5]], column: 8, indent: 1, spelling: "{", closing_token: 56, has_leading_space: true } // 8 and 9 trigger special behavior in APInt when mishandling signed versus // unsigned, so we pay extra attention to those. - var ints: [i32; 5] = ( - // CHECK:STDOUT: - { index: 6, kind: "Var", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: "var", has_leading_space: true } - // CHECK:STDOUT: - { index: 7, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 7, indent: 3, spelling: "ints", identifier: 1, has_leading_space: true } - // CHECK:STDOUT: - { index: 8, kind: "Colon", line: {{ *}}[[@LINE-3]], column: 11, indent: 3, spelling: ":" } - // CHECK:STDOUT: - { index: 9, kind: "OpenSquareBracket", line: {{ *}}[[@LINE-4]], column: 13, indent: 3, spelling: "[", closing_token: 13, has_leading_space: true } - // CHECK:STDOUT: - { index: 10, kind: "IntTypeLiteral", line: {{ *}}[[@LINE-5]], column: 14, indent: 3, spelling: "i32" } - // CHECK:STDOUT: - { index: 11, kind: "Semi", line: {{ *}}[[@LINE-6]], column: 17, indent: 3, spelling: ";" } - // CHECK:STDOUT: - { index: 12, kind: "IntLiteral", line: {{ *}}[[@LINE-7]], column: 19, indent: 3, spelling: "5", value: "5", has_leading_space: true } - // CHECK:STDOUT: - { index: 13, kind: "CloseSquareBracket", line: {{ *}}[[@LINE-8]], column: 20, indent: 3, spelling: "]", opening_token: 9 } - // CHECK:STDOUT: - { index: 14, kind: "Equal", line: {{ *}}[[@LINE-9]], column: 22, indent: 3, spelling: "=", has_leading_space: true } - // CHECK:STDOUT: - { index: 15, kind: "OpenParen", line: {{ *}}[[@LINE-10]], column: 24, indent: 3, spelling: "(", closing_token: 26, has_leading_space: true } + var ints: array(i32, 5) = ( + // CHECK:STDOUT: - { index: 6, kind: "Var", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: "var", has_leading_space: true } + // CHECK:STDOUT: - { index: 7, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 7, indent: 3, spelling: "ints", identifier: 1, has_leading_space: true } + // CHECK:STDOUT: - { index: 8, kind: "Colon", line: {{ *}}[[@LINE-3]], column: 11, indent: 3, spelling: ":" } + // CHECK:STDOUT: - { index: 9, kind: "Array", line: {{ *}}[[@LINE-4]], column: 13, indent: 3, spelling: "array", has_leading_space: true } + // CHECK:STDOUT: - { index: 10, kind: "OpenParen", line: {{ *}}[[@LINE-5]], column: 18, indent: 3, spelling: "(", closing_token: 14 } + // CHECK:STDOUT: - { index: 11, kind: "IntTypeLiteral", line: {{ *}}[[@LINE-6]], column: 19, indent: 3, spelling: "i32" } + // CHECK:STDOUT: - { index: 12, kind: "Comma", line: {{ *}}[[@LINE-7]], column: 22, indent: 3, spelling: "," } + // CHECK:STDOUT: - { index: 13, kind: "IntLiteral", line: {{ *}}[[@LINE-8]], column: 24, indent: 3, spelling: "5", value: "5", has_leading_space: true } + // CHECK:STDOUT: - { index: 14, kind: "CloseParen", line: {{ *}}[[@LINE-9]], column: 25, indent: 3, spelling: ")", opening_token: 10 } + // CHECK:STDOUT: - { index: 15, kind: "Equal", line: {{ *}}[[@LINE-10]], column: 27, indent: 3, spelling: "=", has_leading_space: true } + // CHECK:STDOUT: - { index: 16, kind: "OpenParen", line: {{ *}}[[@LINE-11]], column: 29, indent: 3, spelling: "(", closing_token: 27, has_leading_space: true } 8, - // CHECK:STDOUT: - { index: 16, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "8", value: "8", has_leading_space: true } - // CHECK:STDOUT: - { index: 17, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 6, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 17, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "8", value: "8", has_leading_space: true } + // CHECK:STDOUT: - { index: 18, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 6, indent: 5, spelling: "," } 9, - // CHECK:STDOUT: - { index: 18, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "9", value: "9", has_leading_space: true } - // CHECK:STDOUT: - { index: 19, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 6, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 19, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "9", value: "9", has_leading_space: true } + // CHECK:STDOUT: - { index: 20, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 6, indent: 5, spelling: "," } 0x8, - // CHECK:STDOUT: - { index: 20, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0x8", value: "8", has_leading_space: true } - // CHECK:STDOUT: - { index: 21, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 21, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0x8", value: "8", has_leading_space: true } + // CHECK:STDOUT: - { index: 22, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } 0b1000, - // CHECK:STDOUT: - { index: 22, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0b1000", value: "8", has_leading_space: true } - // CHECK:STDOUT: - { index: 23, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 11, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 23, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0b1000", value: "8", has_leading_space: true } + // CHECK:STDOUT: - { index: 24, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 11, indent: 5, spelling: "," } 39999999999999999993, - // CHECK:STDOUT: - { index: 24, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "39999999999999999993", value: "39999999999999999993", has_leading_space: true } - // CHECK:STDOUT: - { index: 25, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 25, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 25, kind: "IntLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "39999999999999999993", value: "39999999999999999993", has_leading_space: true } + // CHECK:STDOUT: - { index: 26, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 25, indent: 5, spelling: "," } ); - // CHECK:STDOUT: - { index: 26, kind: "CloseParen", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: ")", opening_token: 15, has_leading_space: true } - // CHECK:STDOUT: - { index: 27, kind: "Semi", line: {{ *}}[[@LINE-2]], column: 4, indent: 3, spelling: ";" } - var floats: [f64; 7] = ( - // CHECK:STDOUT: - { index: 28, kind: "Var", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: "var", has_leading_space: true } - // CHECK:STDOUT: - { index: 29, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 7, indent: 3, spelling: "floats", identifier: 2, has_leading_space: true } - // CHECK:STDOUT: - { index: 30, kind: "Colon", line: {{ *}}[[@LINE-3]], column: 13, indent: 3, spelling: ":" } - // CHECK:STDOUT: - { index: 31, kind: "OpenSquareBracket", line: {{ *}}[[@LINE-4]], column: 15, indent: 3, spelling: "[", closing_token: 35, has_leading_space: true } - // CHECK:STDOUT: - { index: 32, kind: "FloatTypeLiteral", line: {{ *}}[[@LINE-5]], column: 16, indent: 3, spelling: "f64" } - // CHECK:STDOUT: - { index: 33, kind: "Semi", line: {{ *}}[[@LINE-6]], column: 19, indent: 3, spelling: ";" } - // CHECK:STDOUT: - { index: 34, kind: "IntLiteral", line: {{ *}}[[@LINE-7]], column: 21, indent: 3, spelling: "7", value: "7", has_leading_space: true } - // CHECK:STDOUT: - { index: 35, kind: "CloseSquareBracket", line: {{ *}}[[@LINE-8]], column: 22, indent: 3, spelling: "]", opening_token: 31 } - // CHECK:STDOUT: - { index: 36, kind: "Equal", line: {{ *}}[[@LINE-9]], column: 24, indent: 3, spelling: "=", has_leading_space: true } - // CHECK:STDOUT: - { index: 37, kind: "OpenParen", line: {{ *}}[[@LINE-10]], column: 26, indent: 3, spelling: "(", closing_token: 52, has_leading_space: true } + // CHECK:STDOUT: - { index: 27, kind: "CloseParen", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: ")", opening_token: 16, has_leading_space: true } + // CHECK:STDOUT: - { index: 28, kind: "Semi", line: {{ *}}[[@LINE-2]], column: 4, indent: 3, spelling: ";" } + var floats: array(f64, 7) = ( + // CHECK:STDOUT: - { index: 29, kind: "Var", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: "var", has_leading_space: true } + // CHECK:STDOUT: - { index: 30, kind: "Identifier", line: {{ *}}[[@LINE-2]], column: 7, indent: 3, spelling: "floats", identifier: 2, has_leading_space: true } + // CHECK:STDOUT: - { index: 31, kind: "Colon", line: {{ *}}[[@LINE-3]], column: 13, indent: 3, spelling: ":" } + // CHECK:STDOUT: - { index: 32, kind: "Array", line: {{ *}}[[@LINE-4]], column: 15, indent: 3, spelling: "array", has_leading_space: true } + // CHECK:STDOUT: - { index: 33, kind: "OpenParen", line: {{ *}}[[@LINE-5]], column: 20, indent: 3, spelling: "(", closing_token: 37 } + // CHECK:STDOUT: - { index: 34, kind: "FloatTypeLiteral", line: {{ *}}[[@LINE-6]], column: 21, indent: 3, spelling: "f64" } + // CHECK:STDOUT: - { index: 35, kind: "Comma", line: {{ *}}[[@LINE-7]], column: 24, indent: 3, spelling: "," } + // CHECK:STDOUT: - { index: 36, kind: "IntLiteral", line: {{ *}}[[@LINE-8]], column: 26, indent: 3, spelling: "7", value: "7", has_leading_space: true } + // CHECK:STDOUT: - { index: 37, kind: "CloseParen", line: {{ *}}[[@LINE-9]], column: 27, indent: 3, spelling: ")", opening_token: 33 } + // CHECK:STDOUT: - { index: 38, kind: "Equal", line: {{ *}}[[@LINE-10]], column: 29, indent: 3, spelling: "=", has_leading_space: true } + // CHECK:STDOUT: - { index: 39, kind: "OpenParen", line: {{ *}}[[@LINE-11]], column: 31, indent: 3, spelling: "(", closing_token: 54, has_leading_space: true } 0.9, - // CHECK:STDOUT: - { index: 38, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0.9", value: "9*10^-1", has_leading_space: true } - // CHECK:STDOUT: - { index: 39, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 40, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "0.9", value: "9*10^-1", has_leading_space: true } + // CHECK:STDOUT: - { index: 41, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } 8.0, - // CHECK:STDOUT: - { index: 40, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "8.0", value: "80*10^-1", has_leading_space: true } - // CHECK:STDOUT: - { index: 41, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 42, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "8.0", value: "80*10^-1", has_leading_space: true } + // CHECK:STDOUT: - { index: 43, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 8, indent: 5, spelling: "," } 80.0, - // CHECK:STDOUT: - { index: 42, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "80.0", value: "800*10^-1", has_leading_space: true } - // CHECK:STDOUT: - { index: 43, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 9, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 44, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "80.0", value: "800*10^-1", has_leading_space: true } + // CHECK:STDOUT: - { index: 45, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 9, indent: 5, spelling: "," } 1.0e7, - // CHECK:STDOUT: - { index: 44, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e7", value: "10*10^6", has_leading_space: true } - // CHECK:STDOUT: - { index: 45, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 10, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 46, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e7", value: "10*10^6", has_leading_space: true } + // CHECK:STDOUT: - { index: 47, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 10, indent: 5, spelling: "," } 1.0e8, - // CHECK:STDOUT: - { index: 46, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e8", value: "10*10^7", has_leading_space: true } - // CHECK:STDOUT: - { index: 47, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 10, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 48, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e8", value: "10*10^7", has_leading_space: true } + // CHECK:STDOUT: - { index: 49, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 10, indent: 5, spelling: "," } 1.0e-8, - // CHECK:STDOUT: - { index: 48, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e-8", value: "10*10^-9", has_leading_space: true } - // CHECK:STDOUT: - { index: 49, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 11, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 50, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "1.0e-8", value: "10*10^-9", has_leading_space: true } + // CHECK:STDOUT: - { index: 51, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 11, indent: 5, spelling: "," } 39999999999999999993.0e39999999999999999993, - // CHECK:STDOUT: - { index: 50, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "39999999999999999993.0e39999999999999999993", value: "399999999999999999930*10^39999999999999999992", has_leading_space: true } - // CHECK:STDOUT: - { index: 51, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 48, indent: 5, spelling: "," } + // CHECK:STDOUT: - { index: 52, kind: "RealLiteral", line: {{ *}}[[@LINE-1]], column: 5, indent: 5, spelling: "39999999999999999993.0e39999999999999999993", value: "399999999999999999930*10^39999999999999999992", has_leading_space: true } + // CHECK:STDOUT: - { index: 53, kind: "Comma", line: {{ *}}[[@LINE-2]], column: 48, indent: 5, spelling: "," } ); - // CHECK:STDOUT: - { index: 52, kind: "CloseParen", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: ")", opening_token: 37, has_leading_space: true } - // CHECK:STDOUT: - { index: 53, kind: "Semi", line: {{ *}}[[@LINE-2]], column: 4, indent: 3, spelling: ";" } + // CHECK:STDOUT: - { index: 54, kind: "CloseParen", line: {{ *}}[[@LINE-1]], column: 3, indent: 3, spelling: ")", opening_token: 39, has_leading_space: true } + // CHECK:STDOUT: - { index: 55, kind: "Semi", line: {{ *}}[[@LINE-2]], column: 4, indent: 3, spelling: ";" } } -// CHECK:STDOUT: - { index: 54, kind: "CloseCurlyBrace", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "}", opening_token: 5, has_leading_space: true } +// CHECK:STDOUT: - { index: 56, kind: "CloseCurlyBrace", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "}", opening_token: 5, has_leading_space: true } // --- fail_binary_real.carbon diff --git a/toolchain/lex/token_kind.def b/toolchain/lex/token_kind.def index 85abd21abfae6..4699203a7562b 100644 --- a/toolchain/lex/token_kind.def +++ b/toolchain/lex/token_kind.def @@ -169,6 +169,7 @@ CARBON_KEYWORD_TOKEN(Abstract, "abstract") CARBON_KEYWORD_TOKEN(Addr, "addr") CARBON_TOKEN_WITH_VIRTUAL_NODE( CARBON_KEYWORD_TOKEN(And, "and")) +CARBON_KEYWORD_TOKEN(Array, "array") CARBON_KEYWORD_TOKEN(As, "as") CARBON_KEYWORD_TOKEN(Auto, "auto") CARBON_KEYWORD_TOKEN(Bool, "bool") diff --git a/toolchain/lex/tokenized_buffer.h b/toolchain/lex/tokenized_buffer.h index 73ef4b62990e8..4de067d398f3c 100644 --- a/toolchain/lex/tokenized_buffer.h +++ b/toolchain/lex/tokenized_buffer.h @@ -447,8 +447,9 @@ class TokenizedBuffer : public Printable { // The constructor is merely responsible for trivial initialization of // members. A working object of this type is built with `Lex::Lex` so that its // return can indicate if an error was encountered while lexing. - explicit TokenizedBuffer(SharedValueStores& value_stores, - SourceBuffer& source) + explicit TokenizedBuffer(SharedValueStores& value_stores + [[clang::lifetimebound]], + SourceBuffer& source [[clang::lifetimebound]]) : value_stores_(&value_stores), source_(&source) {} auto FindLineIndex(int32_t byte_offset) const -> LineIndex; diff --git a/toolchain/lower/testdata/array/array_in_place.carbon b/toolchain/lower/testdata/array/array_in_place.carbon index 0348b647585c2..31b375e7e7cb5 100644 --- a/toolchain/lower/testdata/array/array_in_place.carbon +++ b/toolchain/lower/testdata/array/array_in_place.carbon @@ -11,7 +11,7 @@ fn F() -> (i32, i32, i32); fn G() { - var v: [(i32, i32, i32); 2] = (F(), F()); + var v: array((i32, i32, i32), 2) = (F(), F()); } // CHECK:STDOUT: ; ModuleID = 'array_in_place.carbon' @@ -23,10 +23,10 @@ fn G() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %v.var = alloca [2 x { i32, i32, i32 }], align 8, !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 24, ptr %v.var), !dbg !7 -// CHECK:STDOUT: %.loc14_42.2.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 0, !dbg !8 -// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_42.2.array.index), !dbg !9 -// CHECK:STDOUT: %.loc14_42.4.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 1, !dbg !8 -// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_42.4.array.index), !dbg !10 +// CHECK:STDOUT: %.loc14_47.2.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 0, !dbg !8 +// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_47.2.array.index), !dbg !9 +// CHECK:STDOUT: %.loc14_47.4.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 1, !dbg !8 +// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_47.4.array.index), !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -46,7 +46,7 @@ fn G() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 33, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 14, column: 34, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 14, column: 39, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 38, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 14, column: 39, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 14, column: 44, scope: !4) // CHECK:STDOUT: !11 = !DILocation(line: 13, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/array/assign_return_value.carbon b/toolchain/lower/testdata/array/assign_return_value.carbon index 0d8d8b99c3b22..d5b1e2c8c7e9c 100644 --- a/toolchain/lower/testdata/array/assign_return_value.carbon +++ b/toolchain/lower/testdata/array/assign_return_value.carbon @@ -11,7 +11,7 @@ fn F() -> (i32, i32) { return (12, 24); } fn Run() { - var t: [i32; 2] = F(); + var t: array(i32, 2) = F(); } // CHECK:STDOUT: ; ModuleID = 'assign_return_value.carbon' @@ -31,16 +31,16 @@ fn Run() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %t.var = alloca [2 x i32], align 4, !dbg !10 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %t.var), !dbg !10 -// CHECK:STDOUT: %.loc14_23.1.temp = alloca { i32, i32 }, align 8, !dbg !11 -// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_23.1.temp), !dbg !11 -// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_23.1.temp, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %.loc14_23.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: %.loc14_23.4.array.index = getelementptr inbounds [2 x i32], ptr %t.var, i32 0, i64 0, !dbg !11 -// CHECK:STDOUT: store i32 %.loc14_23.3, ptr %.loc14_23.4.array.index, align 4, !dbg !11 -// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_23.1.temp, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: %.loc14_23.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: %.loc14_23.7.array.index = getelementptr inbounds [2 x i32], ptr %t.var, i32 0, i64 1, !dbg !11 -// CHECK:STDOUT: store i32 %.loc14_23.6, ptr %.loc14_23.7.array.index, align 4, !dbg !11 +// CHECK:STDOUT: %.loc14_28.1.temp = alloca { i32, i32 }, align 8, !dbg !11 +// CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_28.1.temp), !dbg !11 +// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_28.1.temp, i32 0, i32 0, !dbg !11 +// CHECK:STDOUT: %.loc14_28.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !11 +// CHECK:STDOUT: %.loc14_28.4.array.index = getelementptr inbounds [2 x i32], ptr %t.var, i32 0, i64 0, !dbg !11 +// CHECK:STDOUT: store i32 %.loc14_28.3, ptr %.loc14_28.4.array.index, align 4, !dbg !11 +// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_28.1.temp, i32 0, i32 1, !dbg !11 +// CHECK:STDOUT: %.loc14_28.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !11 +// CHECK:STDOUT: %.loc14_28.7.array.index = getelementptr inbounds [2 x i32], ptr %t.var, i32 0, i64 1, !dbg !11 +// CHECK:STDOUT: store i32 %.loc14_28.6, ptr %.loc14_28.7.array.index, align 4, !dbg !11 // CHECK:STDOUT: ret void, !dbg !12 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -67,5 +67,5 @@ fn Run() { // CHECK:STDOUT: !8 = !DILocation(line: 11, column: 24, scope: !4) // CHECK:STDOUT: !9 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 13, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !10 = !DILocation(line: 14, column: 3, scope: !9) -// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 21, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 26, scope: !9) // CHECK:STDOUT: !12 = !DILocation(line: 13, column: 1, scope: !9) diff --git a/toolchain/lower/testdata/array/base.carbon b/toolchain/lower/testdata/array/base.carbon index b2a0c25c83c5f..7d024dac6a24f 100644 --- a/toolchain/lower/testdata/array/base.carbon +++ b/toolchain/lower/testdata/array/base.carbon @@ -9,11 +9,11 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/array/base.carbon fn Run() { - var a: [i32; 1] = (1,); - var b: [f64; 2] = (11.1, 2.2,); - var c: [(); 5] = ((), (), (), (), (),); + var a: array(i32, 1) = (1,); + var b: array(f64, 2) = (11.1, 2.2,); + var c: array((), 5) = ((), (), (), (), (),); var d: (i32, i32, i32) = (1, 2, 3); - var e: [i32; 3] = d; + var e: array(i32, 3) = d; } // CHECK:STDOUT: ; ModuleID = 'base.carbon' @@ -32,18 +32,18 @@ fn Run() { // CHECK:STDOUT: %d.var = alloca { i32, i32, i32 }, align 8, !dbg !7 // CHECK:STDOUT: %e.var = alloca [3 x i32], align 4, !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !7 -// CHECK:STDOUT: %.loc12_24.3.array.index = getelementptr inbounds [1 x i32], ptr %a.var, i32 0, i64 0, !dbg !8 +// CHECK:STDOUT: %.loc12_29.3.array.index = getelementptr inbounds [1 x i32], ptr %a.var, i32 0, i64 0, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a.var, ptr align 4 @array.237.loc12_3.2, i64 4, i1 false), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %b.var), !dbg !7 -// CHECK:STDOUT: %.loc13_32.2.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 0, !dbg !9 -// CHECK:STDOUT: %.loc13_32.4.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 1, !dbg !9 +// CHECK:STDOUT: %.loc13_37.2.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 0, !dbg !9 +// CHECK:STDOUT: %.loc13_37.4.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 1, !dbg !9 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %b.var, ptr align 8 @array.6a2.loc13_3.2, i64 16, i1 false), !dbg !10 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !7 -// CHECK:STDOUT: %.loc14_40.2.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 0, !dbg !11 -// CHECK:STDOUT: %.loc14_40.4.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 1, !dbg !11 -// CHECK:STDOUT: %.loc14_40.6.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 2, !dbg !11 -// CHECK:STDOUT: %.loc14_40.8.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 3, !dbg !11 -// CHECK:STDOUT: %.loc14_40.10.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 4, !dbg !11 +// CHECK:STDOUT: %.loc14_45.2.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 0, !dbg !11 +// CHECK:STDOUT: %.loc14_45.4.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 1, !dbg !11 +// CHECK:STDOUT: %.loc14_45.6.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 2, !dbg !11 +// CHECK:STDOUT: %.loc14_45.8.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 3, !dbg !11 +// CHECK:STDOUT: %.loc14_45.10.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 4, !dbg !11 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @array.1cb.loc14_3.2, i64 0, i1 false), !dbg !12 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %d.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !13 @@ -52,17 +52,17 @@ fn Run() { // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %d.var, ptr align 4 @tuple.loc15_3.2, i64 12, i1 false), !dbg !14 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %e.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !15 -// CHECK:STDOUT: %.loc16_21.1 = load i32, ptr %tuple.elem0.loc16.tuple.elem, align 4, !dbg !15 -// CHECK:STDOUT: %.loc16_21.2.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 0, !dbg !15 -// CHECK:STDOUT: store i32 %.loc16_21.1, ptr %.loc16_21.2.array.index, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.1 = load i32, ptr %tuple.elem0.loc16.tuple.elem, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.2.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 0, !dbg !15 +// CHECK:STDOUT: store i32 %.loc16_26.1, ptr %.loc16_26.2.array.index, align 4, !dbg !15 // CHECK:STDOUT: %tuple.elem1.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 1, !dbg !15 -// CHECK:STDOUT: %.loc16_21.4 = load i32, ptr %tuple.elem1.loc16.tuple.elem, align 4, !dbg !15 -// CHECK:STDOUT: %.loc16_21.5.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 1, !dbg !15 -// CHECK:STDOUT: store i32 %.loc16_21.4, ptr %.loc16_21.5.array.index, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.4 = load i32, ptr %tuple.elem1.loc16.tuple.elem, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.5.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 1, !dbg !15 +// CHECK:STDOUT: store i32 %.loc16_26.4, ptr %.loc16_26.5.array.index, align 4, !dbg !15 // CHECK:STDOUT: %tuple.elem2.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 2, !dbg !15 -// CHECK:STDOUT: %.loc16_21.7 = load i32, ptr %tuple.elem2.loc16.tuple.elem, align 4, !dbg !15 -// CHECK:STDOUT: %.loc16_21.8.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 2, !dbg !15 -// CHECK:STDOUT: store i32 %.loc16_21.7, ptr %.loc16_21.8.array.index, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.7 = load i32, ptr %tuple.elem2.loc16.tuple.elem, align 4, !dbg !15 +// CHECK:STDOUT: %.loc16_26.8.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 2, !dbg !15 +// CHECK:STDOUT: store i32 %.loc16_26.7, ptr %.loc16_26.8.array.index, align 4, !dbg !15 // CHECK:STDOUT: ret void, !dbg !16 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -91,12 +91,12 @@ fn Run() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 12, column: 21, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 21, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 12, column: 26, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 26, scope: !4) // CHECK:STDOUT: !10 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 20, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 25, scope: !4) // CHECK:STDOUT: !12 = !DILocation(line: 14, column: 3, scope: !4) // CHECK:STDOUT: !13 = !DILocation(line: 15, column: 28, scope: !4) // CHECK:STDOUT: !14 = !DILocation(line: 15, column: 3, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 16, column: 21, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 16, column: 26, scope: !4) // CHECK:STDOUT: !16 = !DILocation(line: 11, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/array/field.carbon b/toolchain/lower/testdata/array/field.carbon index ee977c9fe1800..7f617d56ee7cf 100644 --- a/toolchain/lower/testdata/array/field.carbon +++ b/toolchain/lower/testdata/array/field.carbon @@ -9,7 +9,7 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/array/field.carbon class A { - var v: [i32; 2]; + var v: array(i32, 2); // TODO: The LLVM IR we create for this crashes LLVM instruction selection. // The gep indexes are completely bogus. diff --git a/toolchain/lower/testdata/array/function_param.carbon b/toolchain/lower/testdata/array/function_param.carbon index 910e17d758671..1dce624f4488a 100644 --- a/toolchain/lower/testdata/array/function_param.carbon +++ b/toolchain/lower/testdata/array/function_param.carbon @@ -8,7 +8,7 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/array/function_param.carbon -fn F(arr: [i32; 3], i: i32) -> i32 { +fn F(arr: array(i32, 3), i: i32) -> i32 { return arr[i]; } diff --git a/toolchain/lower/testdata/basics/numeric_literals.carbon b/toolchain/lower/testdata/basics/numeric_literals.carbon index 296723d62a8eb..a2640bb3e10b5 100644 --- a/toolchain/lower/testdata/basics/numeric_literals.carbon +++ b/toolchain/lower/testdata/basics/numeric_literals.carbon @@ -11,13 +11,13 @@ fn F() { // 8 and 9 trigger special behavior in APInt when mishandling signed versus // unsigned, so we pay extra attention to those. - var ints: [i32; 4] = ( + var ints: array(i32, 4) = ( 8, 9, 0x8, 0b1000, ); - var floats: [f64; 6] = ( + var floats: array(f64, 6) = ( 0.9, 8.0, 80.0, @@ -78,7 +78,7 @@ fn F() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 24, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 20, column: 26, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 29, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 20, column: 31, scope: !4) // CHECK:STDOUT: !10 = !DILocation(line: 20, column: 3, scope: !4) // CHECK:STDOUT: !11 = !DILocation(line: 11, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/index/array_element_access.carbon b/toolchain/lower/testdata/index/array_element_access.carbon index 37505d82c18de..bbd285924a811 100644 --- a/toolchain/lower/testdata/index/array_element_access.carbon +++ b/toolchain/lower/testdata/index/array_element_access.carbon @@ -9,10 +9,10 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/index/array_element_access.carbon fn A() -> (i32, i32) { return (1, 2); } -fn B() -> [i32; 2] { return (1, 2); } +fn B() -> array(i32, 2) { return (1, 2); } fn Run() { - var a: [i32; 2] = A(); + var a: array(i32, 2) = A(); var b: i32 = 1; var c: i32 = a[b]; var d: i32 = B()[1]; @@ -22,7 +22,7 @@ fn Run() { // CHECK:STDOUT: source_filename = "array_element_access.carbon" // CHECK:STDOUT: // CHECK:STDOUT: @tuple.loc10_37 = internal constant { i32, i32 } { i32 1, i32 2 } -// CHECK:STDOUT: @array.loc12_35 = internal constant [2 x i32] [i32 1, i32 2] +// CHECK:STDOUT: @array.loc12_40 = internal constant [2 x i32] [i32 1, i32 2] // CHECK:STDOUT: // CHECK:STDOUT: define void @_CA.Main(ptr sret({ i32, i32 }) %return) !dbg !4 { // CHECK:STDOUT: entry: @@ -34,9 +34,9 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: define void @_CB.Main(ptr sret([2 x i32]) %return) !dbg !9 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc12_34.3.array.index = getelementptr inbounds [2 x i32], ptr %return, i32 0, i64 0, !dbg !10 -// CHECK:STDOUT: %.loc12_34.6.array.index = getelementptr inbounds [2 x i32], ptr %return, i32 0, i64 1, !dbg !10 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %return, ptr align 4 @array.loc12_35, i64 8, i1 false), !dbg !11 +// CHECK:STDOUT: %.loc12_39.3.array.index = getelementptr inbounds [2 x i32], ptr %return, i32 0, i64 0, !dbg !10 +// CHECK:STDOUT: %.loc12_39.6.array.index = getelementptr inbounds [2 x i32], ptr %return, i32 0, i64 1, !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %return, ptr align 4 @array.loc12_40, i64 8, i1 false), !dbg !11 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -47,16 +47,16 @@ fn Run() { // CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !13 // CHECK:STDOUT: %d.var = alloca i32, align 4, !dbg !13 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %a.var), !dbg !13 -// CHECK:STDOUT: %.loc15_23.1.temp = alloca { i32, i32 }, align 8, !dbg !14 -// CHECK:STDOUT: call void @_CA.Main(ptr %.loc15_23.1.temp), !dbg !14 -// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc15_23.1.temp, i32 0, i32 0, !dbg !14 -// CHECK:STDOUT: %.loc15_23.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !14 -// CHECK:STDOUT: %.loc15_23.4.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 0, !dbg !14 -// CHECK:STDOUT: store i32 %.loc15_23.3, ptr %.loc15_23.4.array.index, align 4, !dbg !14 -// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc15_23.1.temp, i32 0, i32 1, !dbg !14 -// CHECK:STDOUT: %.loc15_23.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !14 -// CHECK:STDOUT: %.loc15_23.7.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 1, !dbg !14 -// CHECK:STDOUT: store i32 %.loc15_23.6, ptr %.loc15_23.7.array.index, align 4, !dbg !14 +// CHECK:STDOUT: %.loc15_28.1.temp = alloca { i32, i32 }, align 8, !dbg !14 +// CHECK:STDOUT: call void @_CA.Main(ptr %.loc15_28.1.temp), !dbg !14 +// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc15_28.1.temp, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: %.loc15_28.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !14 +// CHECK:STDOUT: %.loc15_28.4.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 0, !dbg !14 +// CHECK:STDOUT: store i32 %.loc15_28.3, ptr %.loc15_28.4.array.index, align 4, !dbg !14 +// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc15_28.1.temp, i32 0, i32 1, !dbg !14 +// CHECK:STDOUT: %.loc15_28.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !14 +// CHECK:STDOUT: %.loc15_28.7.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 1, !dbg !14 +// CHECK:STDOUT: store i32 %.loc15_28.6, ptr %.loc15_28.7.array.index, align 4, !dbg !14 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !13 // CHECK:STDOUT: store i32 1, ptr %b.var, align 4, !dbg !15 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %c.var), !dbg !13 @@ -100,11 +100,11 @@ fn Run() { // CHECK:STDOUT: !7 = !DILocation(line: 10, column: 31, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 10, column: 24, scope: !4) // CHECK:STDOUT: !9 = distinct !DISubprogram(name: "B", linkageName: "_CB.Main", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !10 = !DILocation(line: 12, column: 29, scope: !9) -// CHECK:STDOUT: !11 = !DILocation(line: 12, column: 22, scope: !9) +// CHECK:STDOUT: !10 = !DILocation(line: 12, column: 34, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 12, column: 27, scope: !9) // CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !13 = !DILocation(line: 15, column: 3, scope: !12) -// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 21, scope: !12) +// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 26, scope: !12) // CHECK:STDOUT: !15 = !DILocation(line: 16, column: 3, scope: !12) // CHECK:STDOUT: !16 = !DILocation(line: 17, column: 18, scope: !12) // CHECK:STDOUT: !17 = !DILocation(line: 17, column: 16, scope: !12) diff --git a/toolchain/parse/handle_array_expr.cpp b/toolchain/parse/handle_array_expr.cpp index 4bcfbc4fb4f51..041e65c455042 100644 --- a/toolchain/parse/handle_array_expr.cpp +++ b/toolchain/parse/handle_array_expr.cpp @@ -13,28 +13,30 @@ namespace Carbon::Parse { auto HandleArrayExpr(Context& context) -> void { auto state = context.PopState(); - context.AddLeafNode(NodeKind::ArrayExprStart, - context.ConsumeChecked(Lex::TokenKind::OpenSquareBracket), - state.has_error); - context.PushState(state, State::ArrayExprSemi); + auto array_token = context.ConsumeChecked(Lex::TokenKind::Array); + context.AddLeafNode(NodeKind::ArrayExprKeyword, array_token, state.has_error); + if (auto open_paren = context.ConsumeAndAddOpenParen( + array_token, NodeKind::ArrayExprOpenParen)) { + state.token = *open_paren; + } else { + state.has_error = true; + } + context.PushState(state, State::ArrayExprComma); context.PushState(State::Expr); } -auto HandleArrayExprSemi(Context& context) -> void { +auto HandleArrayExprComma(Context& context) -> void { auto state = context.PopState(); - auto semi = context.ConsumeIf(Lex::TokenKind::Semi); - if (!semi) { - context.AddNode(NodeKind::ArrayExprSemi, *context.position(), true); - CARBON_DIAGNOSTIC(ExpectedArraySemi, Error, "expected `;` in array type"); - context.emitter().Emit(*context.position(), ExpectedArraySemi); + if (!context.ConsumeAndAddLeafNodeIf(Lex::TokenKind::Comma, + NodeKind::ArrayExprComma)) { + context.AddLeafNode(NodeKind::ArrayExprComma, *context.position(), true); + CARBON_DIAGNOSTIC(ExpectedArrayComma, Error, + "expected `,` in `array(Type, Count)`"); + context.emitter().Emit(*context.position(), ExpectedArrayComma); state.has_error = true; - } else { - context.AddNode(NodeKind::ArrayExprSemi, *semi, state.has_error); } context.PushState(state, State::ArrayExprFinish); - if (!context.PositionIs(Lex::TokenKind::CloseSquareBracket)) { - context.PushState(State::Expr); - } + context.PushState(State::Expr); } auto HandleArrayExprFinish(Context& context) -> void { diff --git a/toolchain/parse/handle_expr.cpp b/toolchain/parse/handle_expr.cpp index ef981a0372108..d62ffe6e45c4d 100644 --- a/toolchain/parse/handle_expr.cpp +++ b/toolchain/parse/handle_expr.cpp @@ -149,7 +149,7 @@ auto HandleExprInPostfix(Context& context) -> void { context.PushState(State::ParenExpr); break; } - case Lex::TokenKind::OpenSquareBracket: { + case Lex::TokenKind::Array: { context.PushState(state); context.PushState(State::ArrayExpr); break; diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index 64bd576eff4b8..1ff2fc68d40cc 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -157,8 +157,9 @@ CARBON_PARSE_NODE_KIND(ExplicitParamList) CARBON_PARSE_NODE_KIND(ImplicitParamListStart) CARBON_PARSE_NODE_KIND(ImplicitParamList) -CARBON_PARSE_NODE_KIND(ArrayExprStart) -CARBON_PARSE_NODE_KIND(ArrayExprSemi) +CARBON_PARSE_NODE_KIND(ArrayExprOpenParen) +CARBON_PARSE_NODE_KIND(ArrayExprKeyword) +CARBON_PARSE_NODE_KIND(ArrayExprComma) CARBON_PARSE_NODE_KIND(ArrayExpr) CARBON_PARSE_NODE_KIND(LetBindingPattern) diff --git a/toolchain/parse/state.def b/toolchain/parse/state.def index 63aa7b328f9ef..29e0f2f845ca3 100644 --- a/toolchain/parse/state.def +++ b/toolchain/parse/state.def @@ -73,32 +73,26 @@ CARBON_PARSE_STATE(IndexExpr) // (state done) CARBON_PARSE_STATE(IndexExprFinish) -// Handles an array expression. +// Handles the array keyword and opening paren in an array expression. // -// [T; N] -// ^ +// array(T, N) +// ^~~~~~ // 1. Expr -// 2. ArrayExprSemi +// 2. ArrayExprComma CARBON_PARSE_STATE(ArrayExpr) -// Handles ';' in an array expression. +// Handles ',' in an array expression. // -// [T;] -// ^ -// 1. ArrayExprFinish -// -// [T; N] -// ^ +// array(T, N) +// ^ // 1. Expr // 2. ArrayExprFinish -CARBON_PARSE_STATE(ArrayExprSemi) +CARBON_PARSE_STATE(ArrayExprComma) // Handles finishing the array expression. // -// [T;] -// ^ -// [T; N] -// ^ +// array(T, N) +// ^ // (state done) CARBON_PARSE_STATE(ArrayExprFinish) diff --git a/toolchain/parse/testdata/array/with_length.carbon b/toolchain/parse/testdata/array/basic.carbon similarity index 62% rename from toolchain/parse/testdata/array/with_length.carbon rename to toolchain/parse/testdata/array/basic.carbon index 0b78f611a6038..7651bf446ee5f 100644 --- a/toolchain/parse/testdata/array/with_length.carbon +++ b/toolchain/parse/testdata/array/basic.carbon @@ -4,24 +4,25 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/array/with_length.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/array/basic.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/with_length.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/basic.carbon -var x: [i32; 10]; +var x: array(i32, 10); -// CHECK:STDOUT: - filename: with_length.carbon +// CHECK:STDOUT: - filename: basic.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '10'}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/array/fail_require_close_bracket.carbon b/toolchain/parse/testdata/array/fail_require_close_bracket.carbon deleted file mode 100644 index f72681777da57..0000000000000 --- a/toolchain/parse/testdata/array/fail_require_close_bracket.carbon +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/array/fail_require_close_bracket.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/fail_require_close_bracket.carbon -// TODO: It should emit only one error message. - -// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+4]]:8: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] -// CHECK:STDERR: var x: [i32;; -// CHECK:STDERR: ^ -// CHECK:STDERR: -var x: [i32;; - -// CHECK:STDOUT: - filename: fail_require_close_bracket.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'EmptyDecl', text: ';'}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/array/fail_require_semi.carbon b/toolchain/parse/testdata/array/fail_require_semi.carbon deleted file mode 100644 index 21ffd34eed3af..0000000000000 --- a/toolchain/parse/testdata/array/fail_require_semi.carbon +++ /dev/null @@ -1,30 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/array/fail_require_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/fail_require_semi.carbon - -// CHECK:STDERR: fail_require_semi.carbon:[[@LINE+4]]:12: error: expected `;` in array type [ExpectedArraySemi] -// CHECK:STDERR: var x: [i32]; -// CHECK:STDERR: ^ -// CHECK:STDERR: -var x: [i32]; - -// CHECK:STDOUT: - filename: fail_require_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ']', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/array/fail_syntax.carbon b/toolchain/parse/testdata/array/fail_syntax.carbon index 3f52af452d3d7..b3c8771417332 100644 --- a/toolchain/parse/testdata/array/fail_syntax.carbon +++ b/toolchain/parse/testdata/array/fail_syntax.carbon @@ -8,78 +8,140 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/fail_syntax.carbon -// --- fail_type.carbon +// --- fail_no_comma.carbon -// CHECK:STDERR: fail_type.carbon:[[@LINE+4]]:12: error: expected `;` in array type [ExpectedArraySemi] -// CHECK:STDERR: var x: [i32]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_no_comma.carbon:[[@LINE+8]]:17: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: var x: array(i32); +// CHECK:STDERR: ^ // CHECK:STDERR: -var x: [i32]; +// CHECK:STDERR: fail_no_comma.carbon:[[@LINE+4]]:17: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array(i32); +// CHECK:STDERR: ^ +// CHECK:STDERR: +var x: array(i32); // --- fail_invalid_char.carbon -// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+16]]:12: error: expected expression [ExpectedExpr] -// CHECK:STDERR: fn X() -> [:]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+16]]:17: error: expected expression [ExpectedExpr] +// CHECK:STDERR: fn X() -> array(:); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+12]]:12: error: expected `;` in array type [ExpectedArraySemi] -// CHECK:STDERR: fn X() -> [:]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+12]]:17: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: fn X() -> array(:); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+8]]:12: error: expected expression [ExpectedExpr] -// CHECK:STDERR: fn X() -> [:]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+8]]:17: error: expected expression [ExpectedExpr] +// CHECK:STDERR: fn X() -> array(:); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+4]]:12: error: unexpected tokens before `]` [ExpectedCloseSymbol] -// CHECK:STDERR: fn X() -> [:]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_invalid_char.carbon:[[@LINE+4]]:17: error: unexpected tokens before `)` [ExpectedCloseSymbol] +// CHECK:STDERR: fn X() -> array(:); +// CHECK:STDERR: ^ // CHECK:STDERR: -fn X() -> [:]; +fn X() -> array(:); // --- fail_unlexed_expr.carbon -// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+12]]:9: error: encountered unrecognized characters while parsing [UnrecognizedCharacters] -// CHECK:STDERR: var y: [`]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+12]]:14: error: encountered unrecognized characters while parsing [UnrecognizedCharacters] +// CHECK:STDERR: var y: array(`); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+8]]:9: error: expected `;` in array type [ExpectedArraySemi] -// CHECK:STDERR: var y: [`]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+8]]:14: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: var y: array(`); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+4]]:9: error: unexpected tokens before `]` [ExpectedCloseSymbol] -// CHECK:STDERR: var y: [`]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_unlexed_expr.carbon:[[@LINE+4]]:14: error: unexpected tokens before `)` [ExpectedCloseSymbol] +// CHECK:STDERR: var y: array(`); +// CHECK:STDERR: ^ // CHECK:STDERR: -var y: [`]; +var y: array(`); + +// --- fail_no_open_paren.carbon -// --- fail_no_close_bracket.carbon +// CHECK:STDERR: fail_no_open_paren.carbon:[[@LINE+4]]:14: error: expected `(` after `array` [ExpectedParenAfter] +// CHECK:STDERR: var x: array i32, 1; +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +var x: array i32, 1; -// CHECK:STDERR: fail_no_close_bracket.carbon:[[@LINE+4]]:8: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] -// CHECK:STDERR: var x: [i32;; -// CHECK:STDERR: ^ +// --- fail_no_close_paren.carbon + +// CHECK:STDERR: fail_no_close_paren.carbon:[[@LINE+16]]:13: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] +// CHECK:STDERR: var x: array(i32,; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_no_close_paren.carbon:[[@LINE+12]]:13: error: expected `(` after `array` [ExpectedParenAfter] +// CHECK:STDERR: var x: array(i32,; +// CHECK:STDERR: ^ // CHECK:STDERR: -var x: [i32;; +// CHECK:STDERR: fail_no_close_paren.carbon:[[@LINE+8]]:13: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: var x: array(i32,; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_no_close_paren.carbon:[[@LINE+4]]:13: error: `var` declarations must end with a `;` [ExpectedDeclSemi] +// CHECK:STDERR: var x: array(i32,; +// CHECK:STDERR: ^ +// CHECK:STDERR: +var x: array(i32,; -// --- fail_no_semi.carbon +// --- fail_no_length.carbon -// CHECK:STDERR: fail_no_semi.carbon:[[@LINE+4]]:12: error: expected `;` in array type [ExpectedArraySemi] -// CHECK:STDERR: var x: [i32]; -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_no_length.carbon:[[@LINE+4]]:18: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array(i32,); +// CHECK:STDERR: ^ // CHECK:STDERR: -var x: [i32]; +var x: array(i32,); + +// --- fail_no_params.carbon -// CHECK:STDOUT: - filename: fail_type.carbon +// CHECK:STDERR: fail_no_params.carbon:[[@LINE+12]]:14: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array(); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_no_params.carbon:[[@LINE+8]]:14: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: var x: array(); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_no_params.carbon:[[@LINE+4]]:14: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array(); +// CHECK:STDERR: ^ +// CHECK:STDERR: +var x: array(); + +// --- fail_keyword_alone.carbon + +// CHECK:STDERR: fail_keyword_alone.carbon:[[@LINE+16]]:13: error: expected `(` after `array` [ExpectedParenAfter] +// CHECK:STDERR: var x: array; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_keyword_alone.carbon:[[@LINE+12]]:13: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_keyword_alone.carbon:[[@LINE+8]]:13: error: expected `,` in `array(Type, Count)` [ExpectedArrayComma] +// CHECK:STDERR: var x: array; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_keyword_alone.carbon:[[@LINE+4]]:13: error: expected expression [ExpectedExpr] +// CHECK:STDERR: var x: array; +// CHECK:STDERR: ^ +// CHECK:STDERR: +var x: array; + +// CHECK:STDOUT: - filename: fail_no_comma.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ']', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] // CHECK:STDOUT: - filename: fail_invalid_char.carbon @@ -89,13 +151,14 @@ var x: [i32]; // CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'X'}, // CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: ':', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ':', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ':', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ':', has_error: yes}, // CHECK:STDOUT: {kind: 'InvalidParse', text: ':', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 5}, -// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 12}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] // CHECK:STDOUT: - filename: fail_unlexed_expr.carbon @@ -103,39 +166,94 @@ var x: [i32]; // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'y'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '`', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: '`', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, // CHECK:STDOUT: {kind: 'InvalidParse', text: '`', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 5}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: '`', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '`', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_no_open_paren.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: 'array', has_error: yes}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: 'array', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_no_close_paren.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: 'array', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: 'array', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', has_error: yes, subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_no_length.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -// CHECK:STDOUT: - filename: fail_no_close_bracket.carbon +// CHECK:STDOUT: - filename: fail_no_params.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'EmptyDecl', text: ';'}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -// CHECK:STDOUT: - filename: fail_no_semi.carbon +// CHECK:STDOUT: - filename: fail_keyword_alone.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ']', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: 'array', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ';', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: 'array', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 11}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/array/without_length.carbon b/toolchain/parse/testdata/array/without_length.carbon deleted file mode 100644 index 81867a3f0094c..0000000000000 --- a/toolchain/parse/testdata/array/without_length.carbon +++ /dev/null @@ -1,26 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/array/without_length.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/array/without_length.carbon - -var x: [i32;]; - -// CHECK:STDOUT: - filename: without_length.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ';', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/basics/fail_bracket_recovery.carbon b/toolchain/parse/testdata/basics/fail_bracket_recovery.carbon index 39575327a8590..4085c1b6dd98d 100644 --- a/toolchain/parse/testdata/basics/fail_bracket_recovery.carbon +++ b/toolchain/parse/testdata/basics/fail_bracket_recovery.carbon @@ -10,11 +10,12 @@ // This is a valid parse tree even though the lex errors. fn F() { - // CHECK:STDERR: fail_bracket_recovery.carbon:[[@LINE+4]]:11: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] - // CHECK:STDERR: var x: ([i32; 3) = (0, 1, 2); - // CHECK:STDERR: ^ + var a: array(i32, 3) = (0, 1, 2); + // CHECK:STDERR: fail_bracket_recovery.carbon:[[@LINE+4]]:5: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] + // CHECK:STDERR: (a[1) + 1; + // CHECK:STDERR: ^ // CHECK:STDERR: - var x: ([i32; 3) = (0, 1, 2); + (a[1) + 1; // CHECK:STDERR: fail_bracket_recovery.carbon:[[@LINE+12]]:15: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] // CHECK:STDERR: var x: {.y: (} = {.y = ((}; // CHECK:STDERR: ^ @@ -39,16 +40,15 @@ fn F() { // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, -// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ';', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, // CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '0'}, @@ -57,7 +57,16 @@ fn F() { // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '2'}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 20}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 19}, +// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'}, +// CHECK:STDOUT: {kind: 'IndexExprStart', text: '[', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'}, +// CHECK:STDOUT: {kind: 'IndexExpr', text: ']', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'}, +// CHECK:STDOUT: {kind: 'InfixOperatorPlus', text: '+', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 9}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, // CHECK:STDOUT: {kind: 'StructTypeLiteralStart', text: '{'}, @@ -80,6 +89,6 @@ fn F() { // CHECK:STDOUT: {kind: 'StructLiteralField', text: '=', subtree_size: 7}, // CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 9}, // CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 22}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 48}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 56}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/basics/numeric_literals.carbon b/toolchain/parse/testdata/basics/numeric_literals.carbon index 227768fb3f14d..1441b5e391fa2 100644 --- a/toolchain/parse/testdata/basics/numeric_literals.carbon +++ b/toolchain/parse/testdata/basics/numeric_literals.carbon @@ -11,14 +11,14 @@ fn F() { // 8 and 9 trigger special behavior in APInt when mishandling signed versus // unsigned, so we pay extra attention to those. - var ints: [i32; 5] = ( + var ints: array(i32, 5) = ( 8, 9, 0x8, 0b1000, 39999999999999999993, ); - var floats: [f64; 7] = ( + var floats: array(f64, 7) = ( 0.9, 8.0, 80.0, @@ -39,13 +39,14 @@ fn F() { // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'ints'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '5'}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, // CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '8'}, @@ -59,16 +60,17 @@ fn F() { // CHECK:STDOUT: {kind: 'IntLiteral', text: '39999999999999999993'}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 23}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 24}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'floats'}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ArrayExprKeyword', text: 'array'}, +// CHECK:STDOUT: {kind: 'ArrayExprOpenParen', text: '('}, +// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'}, +// CHECK:STDOUT: {kind: 'ArrayExprComma', text: ','}, // CHECK:STDOUT: {kind: 'IntLiteral', text: '7'}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ArrayExpr', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 9}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, // CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'RealLiteral', text: '0.9'}, @@ -86,7 +88,7 @@ fn F() { // CHECK:STDOUT: {kind: 'RealLiteral', text: '39999999999999999993.0e39999999999999999993'}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 16}, -// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 27}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 56}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 28}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 58}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/for/fail_square_brackets.carbon b/toolchain/parse/testdata/for/fail_square_brackets.carbon index 22100f2daf2d0..656c6f7cba893 100644 --- a/toolchain/parse/testdata/for/fail_square_brackets.carbon +++ b/toolchain/parse/testdata/for/fail_square_brackets.carbon @@ -9,21 +9,25 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/for/fail_square_brackets.carbon fn F() { - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+16]]:7: error: expected `(` after `for` [ExpectedParenAfter] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+20]]:7: error: expected `(` after `for` [ExpectedParenAfter] // CHECK:STDERR: for [] { // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+12]]:7: error: expected `var` declaration [ExpectedVariableDecl] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+16]]:7: error: expected `var` declaration [ExpectedVariableDecl] // CHECK:STDERR: for [] { // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+8]]:8: error: expected expression [ExpectedExpr] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+12]]:7: error: expected expression [ExpectedExpr] // CHECK:STDERR: for [] { - // CHECK:STDERR: ^ + // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+4]]:8: error: expected `;` in array type [ExpectedArraySemi] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+8]]:7: error: expected braced code block [ExpectedCodeBlock] // CHECK:STDERR: for [] { - // CHECK:STDERR: ^ + // CHECK:STDERR: ^ + // CHECK:STDERR: + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+4]]:7: error: expected expression [ExpectedExpr] + // CHECK:STDERR: for [] { + // CHECK:STDERR: ^ // CHECK:STDERR: for [] { } @@ -38,14 +42,13 @@ fn F() { // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, // CHECK:STDOUT: {kind: 'ForHeaderStart', text: 'for', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: ']', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ']', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForHeader', text: 'for', has_error: yes, subtree_size: 6}, -// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'ForHeader', text: 'for', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'ExprStatement', text: '}', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'CodeBlock', text: '[', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 14}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/if/fail_square_brackets.carbon b/toolchain/parse/testdata/if/fail_square_brackets.carbon index f509718de253e..65a92835d0088 100644 --- a/toolchain/parse/testdata/if/fail_square_brackets.carbon +++ b/toolchain/parse/testdata/if/fail_square_brackets.carbon @@ -9,17 +9,21 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/if/fail_square_brackets.carbon fn F() { - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+12]]:6: error: expected `(` after `if` [ExpectedParenAfter] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+16]]:6: error: expected `(` after `if` [ExpectedParenAfter] // CHECK:STDERR: if [] {} // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+8]]:7: error: expected expression [ExpectedExpr] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+12]]:6: error: expected expression [ExpectedExpr] // CHECK:STDERR: if [] {} - // CHECK:STDERR: ^ + // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+4]]:7: error: expected `;` in array type [ExpectedArraySemi] + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+8]]:6: error: expected braced code block [ExpectedCodeBlock] // CHECK:STDERR: if [] {} - // CHECK:STDERR: ^ + // CHECK:STDERR: ^ + // CHECK:STDERR: + // CHECK:STDERR: fail_square_brackets.carbon:[[@LINE+4]]:6: error: expected expression [ExpectedExpr] + // CHECK:STDERR: if [] {} + // CHECK:STDERR: ^ // CHECK:STDERR: if [] {} } @@ -33,14 +37,13 @@ fn F() { // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, // CHECK:STDOUT: {kind: 'IfConditionStart', text: 'if', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprStart', text: '['}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: ']', has_error: yes}, -// CHECK:STDOUT: {kind: 'ArrayExprSemi', text: ']', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'IfCondition', text: 'if', has_error: yes, subtree_size: 6}, -// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'IfCondition', text: 'if', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '[', has_error: yes}, +// CHECK:STDOUT: {kind: 'ExprStatement', text: '}', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'CodeBlock', text: '[', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 14}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/typed_nodes.h b/toolchain/parse/typed_nodes.h index 7d244fed3128f..915ffc395c736 100644 --- a/toolchain/parse/typed_nodes.h +++ b/toolchain/parse/typed_nodes.h @@ -805,29 +805,25 @@ struct MatchStatement { // Expression nodes // ---------------- -using ArrayExprStart = - LeafNode; +using ArrayExprKeyword = + LeafNode; -// The start of an array type, `[i32;`. -// -// TODO: Consider flattening this into `ArrayExpr`. -struct ArrayExprSemi { - static constexpr auto Kind = NodeKind::ArrayExprSemi.Define( - {.bracketed_by = ArrayExprStart::Kind, .child_count = 2}); +using ArrayExprOpenParen = + LeafNode; - ArrayExprStartId left_square; - AnyExprId type; - Lex::SemiTokenIndex token; -}; +using ArrayExprComma = LeafNode; -// An array type, such as `[i32; 3]` or `[i32;]`. +// An array type, `array(T, N)`. struct ArrayExpr { static constexpr auto Kind = NodeKind::ArrayExpr.Define( - {.category = NodeCategory::Expr, .bracketed_by = ArrayExprSemi::Kind}); + {.category = NodeCategory::Expr, .child_count = 5}); - ArrayExprSemiId start; - std::optional bound; - Lex::CloseSquareBracketTokenIndex token; + ArrayExprKeywordId keyword; + ArrayExprOpenParenId start; + AnyExprId type; + ArrayExprCommaId comma; + AnyExprId bound; + Lex::CloseParenTokenIndex token; }; // The opening portion of an indexing expression: `a[`. diff --git a/toolchain/parse/typed_nodes_test.cpp b/toolchain/parse/typed_nodes_test.cpp index 6d0c9567129da..06a9401b336da 100644 --- a/toolchain/parse/typed_nodes_test.cpp +++ b/toolchain/parse/typed_nodes_test.cpp @@ -110,7 +110,7 @@ TEST_F(TypedNodeTest, ModifierOrder) { TEST_F(TypedNodeTest, For) { auto& tree = compile_helper_.GetTreeAndSubtrees(R"carbon( - fn F(arr: [i32; 5]) { + fn F(arr: array(i32, 5)) { for (var v: i32 in arr) { Print(v); } From d199ce327ad5967f12100aac4bb82d8e2b19d0d5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 20 Feb 2025 17:59:06 -0500 Subject: [PATCH 05/56] Make FacetTypeInfo and CompleteFacetType stores share id indices (#4989) The CompleteFacetType value store is now a RelationalValueStore. This type of store uses some _other_ id as the key for insertion. It allows checking if values of the _other_ id are present in the store, since those ids are handed out by another store and will (necessarily) exist before there is a matching value in the RelationalValueStore. The lookup for precense of the _other_ id returns the id of a value in the RelationalValueStore. That id can be used to get the value out of the store. For our use case, the RelationalValueStore maps from FacetTypeId to CompleteFacetTypeId. So you add a CompleteFacetType to the store with a FacetTypeId. Then you can query with a FacetTypeId to see if there exists a CompleteFacetTypeId. And if there is, you can use that CompleteFacetTypeId thereafter to get the CompleteFacetType value from the store. This removes the need for ValueStore::GetMutable() and removes the method. FacetTypeInfo no longer has a field that needs to be carefully excluded from hash and comparison. --- toolchain/base/value_store.h | 68 ++++++++++++++++++++++++++-- toolchain/check/context.h | 2 +- toolchain/check/type_completion.cpp | 19 ++++---- toolchain/sem_ir/dump.cpp | 5 +- toolchain/sem_ir/facet_type_info.cpp | 4 -- toolchain/sem_ir/facet_type_info.h | 6 --- toolchain/sem_ir/file.h | 9 ++-- toolchain/sem_ir/ids.h | 4 +- 8 files changed, 88 insertions(+), 29 deletions(-) diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index 2e6851fff43fc..f4751f22d38f3 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -5,6 +5,7 @@ #ifndef CARBON_TOOLCHAIN_BASE_VALUE_STORE_H_ #define CARBON_TOOLCHAIN_BASE_VALUE_STORE_H_ +#include #include #include "common/check.h" @@ -146,9 +147,6 @@ class CanonicalValueStore { // Returns the value for an ID. auto Get(IdT id) const -> ConstRefType { return values_.Get(id); } - // Returns the value for an ID. Changes should not affect hash or ==. - auto GetMutable(IdT id) -> RefType { return values_.Get(id); } - // Looks up the canonical ID for a value, or returns `None` if not in the // store. auto Lookup(ValueType value) const -> IdT; @@ -223,6 +221,70 @@ auto CanonicalValueStore::Reserve(size_t size) -> void { values_.Reserve(size); } +// A ValueStore that builds a 1:1 relationship between two IDs. +// * `RelatedIdT` represents a related ID that can be used to find values in the +// store. +// * `IdT` is the actual ID of values in this store, and `IdT::ValueType` is the +// value type being stored. +// +// The value store builds a mapping so that either ID can be used later to find +// a value. And the user can query if a related `RelatedIdT` has been used to +// add a value to the store or not. +// +// When adding to the store, the user provides the related `RelatedIdT` along +// with the value being stored, and gets back the ID of the value in the store. +// +// This store requires more storage space than normal ValueStore does, as it +// requires storing a bit for presence of each `RelatedIdT`. And it allocates +// memory for values for all IDs up largest ID present in the store, even if +// they are not yet used. +template +class RelationalValueStore { + public: + using ValueType = IdT::ValueType; + using ConstRefType = ValueStore::ConstRefType; + + // Given the related ID and a value, stores the value and returns a mapped ID + // to reference it in the store. + auto Add(RelatedIdT related_id, ValueType value) -> IdT { + CARBON_DCHECK(related_id.index >= 0, "{0}", related_id); + IdT id(related_id.index); + if (static_cast(id.index) >= values_.size()) { + values_.resize(id.index + 1); + } + auto& opt = values_[id.index]; + CARBON_CHECK(!opt.has_value(), + "Add with `related_id` that was already added to the store"); + opt.emplace(std::move(value)); + return id; + } + + // Returns the ID of a value in the store if the `related_id` was previously + // used to add a value to the store, or None. + auto TryGetId(RelatedIdT related_id) const -> IdT { + CARBON_DCHECK(related_id.index >= 0, "{0}", related_id); + if (static_cast(related_id.index) >= values_.size()) { + return IdT::None; + } + auto& opt = values_[related_id.index]; + if (!opt.has_value()) { + return IdT::None; + } + return IdT(related_id.index); + } + + // Returns a value for an ID. + auto Get(IdT id) const -> ConstRefType { + CARBON_DCHECK(id.index >= 0, "{0}", id); + return *values_[id.index]; + } + + private: + // Set inline size to 0 because these will typically be too large for the + // stack, while this does make File smaller. + llvm::SmallVector>, 0> values_; +}; + } // namespace Carbon #endif // CARBON_TOOLCHAIN_BASE_VALUE_STORE_H_ diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 28b4477eae30a..c3d4b625995eb 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -224,7 +224,7 @@ class Context { auto facet_types() -> CanonicalValueStore& { return sem_ir().facet_types(); } - auto complete_facet_types() -> ValueStore& { + auto complete_facet_types() -> SemIR::File::CompleteFacetTypeStore& { return sem_ir().complete_facet_types(); } auto impls() -> SemIR::ImplStore& { return sem_ir().impls(); } diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index cafddded2018a..2104090684fdb 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -10,6 +10,7 @@ #include "toolchain/check/inst.h" #include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" +#include "toolchain/sem_ir/ids.h" namespace Carbon::Check { @@ -574,9 +575,11 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, } static auto AddCompleteFacetType(Context& context, SemIR::LocId loc_id, - const SemIR::FacetTypeInfo& facet_type_info, + SemIR::FacetTypeId facet_type_id, FacetTypeContext context_for_diagnostics) -> SemIR::CompleteFacetTypeId { + const auto& facet_type_info = context.facet_types().Get(facet_type_id); + SemIR::CompleteFacetType result; result.required_interfaces.reserve(facet_type_info.impls_constraints.size()); // Every mentioned interface needs to be defined. @@ -611,7 +614,7 @@ static auto AddCompleteFacetType(Context& context, SemIR::LocId loc_id, // TODO: Distinguish interfaces that are required but would not be // implemented, such as those from `where .Self impls I`. result.num_to_impl = result.required_interfaces.size(); - return context.complete_facet_types().Add(result); + return context.complete_facet_types().Add(facet_type_id, result); } // TODO: RequireCompleteType should do these checks, this should just return @@ -628,13 +631,13 @@ auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, return SemIR::CompleteFacetTypeId::None; } - auto& facet_type_info = - context.facet_types().GetMutable(facet_type.facet_type_id); - if (!facet_type_info.complete_id.has_value()) { - facet_type_info.complete_id = AddCompleteFacetType( - context, loc_id, facet_type_info, context_for_diagnostics); + auto complete_id = + context.complete_facet_types().TryGetId(facet_type.facet_type_id); + if (!complete_id.has_value()) { + complete_id = AddCompleteFacetType( + context, loc_id, facet_type.facet_type_id, context_for_diagnostics); } - return facet_type_info.complete_id; + return complete_id; } auto AsCompleteType(Context& context, SemIR::TypeId type_id, diff --git a/toolchain/sem_ir/dump.cpp b/toolchain/sem_ir/dump.cpp index f43e19e13dea0..2f7e21545e62f 100644 --- a/toolchain/sem_ir/dump.cpp +++ b/toolchain/sem_ir/dump.cpp @@ -99,9 +99,10 @@ LLVM_DUMP_METHOD auto Dump(const File& file, FacetTypeId facet_type_id) llvm::errs() << " - "; Dump(file, rewrite.rhs_const_id); } - if (facet_type.complete_id.has_value()) { + if (auto complete_id = file.complete_facet_types().TryGetId(facet_type_id); + complete_id.has_value()) { llvm::errs() << "complete: "; - Dump(file, facet_type.complete_id); + Dump(file, complete_id); } } else { llvm::errs() << '\n'; diff --git a/toolchain/sem_ir/facet_type_info.cpp b/toolchain/sem_ir/facet_type_info.cpp index 7843c76caec54..c5ee01ec58278 100644 --- a/toolchain/sem_ir/facet_type_info.cpp +++ b/toolchain/sem_ir/facet_type_info.cpp @@ -27,7 +27,6 @@ static auto RewriteLess(const FacetTypeInfo::RewriteConstraint& lhs, } auto FacetTypeInfo::Canonicalize() -> void { - CARBON_CHECK(!complete_id.has_value()); SortAndDeduplicate(impls_constraints, ImplsLess); SortAndDeduplicate(rewrite_constraints, RewriteLess); } @@ -59,9 +58,6 @@ auto FacetTypeInfo::Print(llvm::raw_ostream& out) const -> void { out << outer_sep << "+ TODO requirements"; } - if (complete_id.has_value()) { - out << outer_sep << "complete: " << complete_id; - } out << "}"; } diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index 2ebc263db55ab..a00687c30fb29 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -56,12 +56,6 @@ struct FacetTypeInfo : Printable { // TODO: Remove once all requirements are supported. bool other_requirements; - // This is should be `None` for new facet type values, and only set as a - // private implementation detail of `RequireCompleteFacetType`. It is stored - // here so that we only compute its value once per facet type. This is not - // part of the value of the facet type, excluded from `==` and its hash value. - CompleteFacetTypeId complete_id = CompleteFacetTypeId::None; - // Sorts and deduplicates constraints. Call after building the value, and then // don't mutate this value afterwards. auto Canonicalize() -> void; diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 34ae53b72b285..132cfb9cc5cb4 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -57,6 +57,9 @@ struct ExprRegion { // Provides semantic analysis on a Parse::Tree. class File : public Printable { public: + using CompleteFacetTypeStore = + RelationalValueStore; + // Starts a new file for Check::CheckParseTree. explicit File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, const std::optional& packaging_decl, @@ -156,10 +159,10 @@ class File : public Printable { auto facet_types() const -> const CanonicalValueStore& { return facet_types_; } - auto complete_facet_types() -> ValueStore& { + auto complete_facet_types() -> CompleteFacetTypeStore& { return complete_facet_types_; } - auto complete_facet_types() const -> const ValueStore& { + auto complete_facet_types() const -> const CompleteFacetTypeStore& { return complete_facet_types_; } auto impls() -> ImplStore& { return impls_; } @@ -276,7 +279,7 @@ class File : public Printable { CanonicalValueStore facet_types_; // Storage for complete facet types. - ValueStore complete_facet_types_; + CompleteFacetTypeStore complete_facet_types_; // Storage for impls. ImplStore impls_; diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index fa285936c2e94..3711937e0b399 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -275,7 +275,7 @@ struct AssociatedConstantId : public IdBase { constexpr AssociatedConstantId AssociatedConstantId::None = AssociatedConstantId(NoneIndex); -// The ID of an faceet type value. +// The ID of an facet type value. struct FacetTypeId : public IdBase { static constexpr llvm::StringLiteral Label = "facet_type"; using ValueType = FacetTypeInfo; @@ -288,7 +288,7 @@ struct FacetTypeId : public IdBase { constexpr FacetTypeId FacetTypeId::None = FacetTypeId(NoneIndex); -// The ID of an resolved faceet type value. +// The ID of an resolved facet type value. struct CompleteFacetTypeId : public IdBase { static constexpr llvm::StringLiteral Label = "complete_facet_type"; using ValueType = CompleteFacetType; From 2ea2166cf82f3c05c09aa3ab598c476217eedfdf Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 20 Feb 2025 16:27:15 -0800 Subject: [PATCH 06/56] Update pre-commit (#4995) `pre-commit autoupdate --freeze && pre-commit run -a` --- .github/workflows/nightly_release.yaml | 2 +- .pre-commit-config.yaml | 8 ++++---- common/raw_hashtable.h | 2 +- proposals/p0253.md | 2 +- proposals/p0257.md | 2 +- proposals/p2006.md | 2 +- proposals/p3833.md | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/nightly_release.yaml b/.github/workflows/nightly_release.yaml index 6c09b290dd6b1..2019a6fc2c230 100644 --- a/.github/workflows/nightly_release.yaml +++ b/.github/workflows/nightly_release.yaml @@ -12,7 +12,7 @@ # # - Do some amount of testing prior to building and uploading the release. # - Tempting to try to examine existing testing workflow, but maybe better to -# allow re-using any complex parts and do our own testing. That would, for +# allow reusing any complex parts and do our own testing. That would, for # example, allow us to narrow or expand the set of tests uses for # pre-release testing to potentially be different from continuous testing. # - Some questions around what to do in the event of a failure... error? Where diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1864e1413de64..07783c9137ace 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: # Formatters should be run late so that they can re-format any prior changes. - repo: https://github.com/psf/black - rev: 1b2427a2b785cc4aac97c19bb4b9a0de063f9547 # frozen: 24.10.0 + rev: 8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # frozen: 25.1.0 hooks: - id: black - repo: local @@ -135,11 +135,11 @@ repos: files: ^.*/BUILD$ pass_filenames: false - repo: https://github.com/PyCQA/flake8 - rev: e43806be3607110919eff72939fda031776e885a # frozen: 7.1.1 + rev: bddd87797f8dfc07d2a10c894776018d9bec590b # frozen: 7.1.2 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'f56614daa94d5cd733d3b7004c5df9caad267b4a' # frozen: v1.13.0 + rev: 'f40886d54c729f533f864ed6ce584e920feb0af7' # frozen: v1.15.0 hooks: - id: mypy # Use setup.cfg to match the command line. @@ -161,7 +161,7 @@ repos: .*_test\.py )$ - repo: https://github.com/codespell-project/codespell - rev: 193cd7d27cd571f79358af09a8fb8997e54f8fff # frozen: v2.3.0 + rev: 63c8f8312b7559622c0d82815639671ae42132ac # frozen: v2.4.1 hooks: - id: codespell args: ['-I', '.codespell_ignore', '--uri-ignore-words-list', '*'] diff --git a/common/raw_hashtable.h b/common/raw_hashtable.h index 959c23db8c4bb..ace1e3a507994 100644 --- a/common/raw_hashtable.h +++ b/common/raw_hashtable.h @@ -518,7 +518,7 @@ class BaseImpl { // returns `true`. If not found, returns `false`. // // Does not release any memory, just leaves a tombstone behind so this entry - // cannot be found and the slot can in theory be re-used. + // cannot be found and the slot can in theory be reused. template auto EraseImpl(LookupKeyT lookup_key, KeyContextT key_context) -> bool; diff --git a/proposals/p0253.md b/proposals/p0253.md index 631353f0d854f..41b678f8f02b1 100644 --- a/proposals/p0253.md +++ b/proposals/p0253.md @@ -52,7 +52,7 @@ semantically meaningful port into Carbon code. An important nuance of this goal is that it doesn't include building a complete Carbon standard library beyond the most basic necessary types. The intent is to -exercise and show the interoperability layers of Carbon by re-using the C++ +exercise and show the interoperability layers of Carbon by reusing the C++ standard library in many cases and exporting a compatible C++ API to both woff2 and RE2's current API. diff --git a/proposals/p0257.md b/proposals/p0257.md index d631ef53a06c3..fafde9c223e96 100644 --- a/proposals/p0257.md +++ b/proposals/p0257.md @@ -203,7 +203,7 @@ implement it) alongside raw storage for the underlying object. The unformed state can have the same representation as valid and fully formed states for the object (for example, an empty `Optional(T)`). While there is a semantic difference (any operation _other_ than assignment and destruction is an -error for an unformed object), there is no problem re-using a representation +error for an unformed object), there is no problem reusing a representation which is also used for fully formed and valid objects provided it satisfies all three of the above constraints. The semantic restrictions remain even in this case. Using the hypothetical `Optional(T)` API, we could imagine: diff --git a/proposals/p2006.md b/proposals/p2006.md index 4c9ac39e4eb99..501045a2dbb3b 100644 --- a/proposals/p2006.md +++ b/proposals/p2006.md @@ -685,7 +685,7 @@ outweighing the proposed option on balance. - `const` and `var` - Some familiarity for C++ developers given the use of `const` there. - `const` is used by other languages in a similar way to Carbon's `let`. - - However, very concerned about re-using `const` but having it mean + - However, very concerned about reusing `const` but having it mean something fairly different from C++ as a declaration introducer. For example, nesting a `var` pattern within `const` might be especially surprising. diff --git a/proposals/p3833.md b/proposals/p3833.md index aa1cc9a7d7ce2..6b83b88d88b07 100644 --- a/proposals/p3833.md +++ b/proposals/p3833.md @@ -153,10 +153,10 @@ the full semantic modeling here: - Not representing a user-written `typeof` style expression to compute the type, or duplicating the `y` expression. -- Caching and re-using SemIR for immutable things like successfully resolved - name lookup. Concretely, re-using a single cached lookup of +- Caching and reusing SemIR for immutable things like successfully resolved + name lookup. Concretely, reusing a single cached lookup of `package#Core.AddWith` would still provide the full model. And similarly, - re-using an already computed parameterization such as + reusing an already computed parameterization such as `package#Core.AddWith(i32)` repeatedly, and the lookup of `Op` within that parameterization. From 8d1d491ad0c32edb6338382d8482ff5a6bbeb245 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 20 Feb 2025 20:26:45 -0800 Subject: [PATCH 07/56] Add LLD subcommand and busybox support (#4973) This removes the separately built and installed LLD binary. The symlinks used by Clang when directly invoking LLD now point back to the main `carbon-busybox` binary and dispatch through the newly added subcommand. With this change we're down to shipping a single busybox binary in the toolchain, removing duplicate installed copies of LLD and all its LLVM dependencies. =] The LLD subcommand works a bit differently from the `clang` subcommand because the CLI for LLD is specific to which platform flavor of linker is being invoked. As part of this, I've extracted some of the common functionality in the Clang runner into a base class that can be re-used. I expect to use this again in a follow-up change to add subcommands to run other LLVM tools. --------- Co-authored-by: Jon Ross-Perkins --- toolchain/diagnostics/diagnostic_kind.def | 1 + toolchain/driver/BUILD | 62 +++++- toolchain/driver/clang_runner.cpp | 50 +---- toolchain/driver/clang_runner.h | 6 +- toolchain/driver/driver.cpp | 3 + toolchain/driver/lld_runner.cpp | 59 +++++ toolchain/driver/lld_runner.h | 36 +++ toolchain/driver/lld_runner_test.cpp | 210 ++++++++++++++++++ toolchain/driver/lld_subcommand.cpp | 113 ++++++++++ toolchain/driver/lld_subcommand.h | 54 +++++ .../driver/testdata/fail_lld_fuzzing.carbon | 15 ++ toolchain/driver/tool_runner_base.cpp | 73 ++++++ toolchain/driver/tool_runner_base.h | 65 ++++++ toolchain/install/BUILD | 15 +- toolchain/install/busybox_main.cpp | 15 +- toolchain/install/install_paths.cpp | 24 ++ toolchain/install/install_paths.h | 5 + toolchain/install/install_paths_test.cpp | 3 +- 18 files changed, 745 insertions(+), 64 deletions(-) create mode 100644 toolchain/driver/lld_runner.cpp create mode 100644 toolchain/driver/lld_runner.h create mode 100644 toolchain/driver/lld_runner_test.cpp create mode 100644 toolchain/driver/lld_subcommand.cpp create mode 100644 toolchain/driver/lld_subcommand.h create mode 100644 toolchain/driver/testdata/fail_lld_fuzzing.carbon create mode 100644 toolchain/driver/tool_runner_base.cpp create mode 100644 toolchain/driver/tool_runner_base.h diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 9a58df5bf90eb..d803021abed37 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -29,6 +29,7 @@ CARBON_DIAGNOSTIC_KIND(CompilePreludeManifestError) CARBON_DIAGNOSTIC_KIND(CompileInputNotRegularFile) CARBON_DIAGNOSTIC_KIND(CompileOutputFileOpenError) CARBON_DIAGNOSTIC_KIND(FormatMultipleFilesToOneOutput) +CARBON_DIAGNOSTIC_KIND(LLDFuzzingDisallowed) // ============================================================================ // SourceBuffer diagnostics diff --git a/toolchain/driver/BUILD b/toolchain/driver/BUILD index 798b5a3455611..d845a46a186ff 100644 --- a/toolchain/driver/BUILD +++ b/toolchain/driver/BUILD @@ -20,11 +20,8 @@ cc_library( name = "clang_runner", srcs = ["clang_runner.cpp"], hdrs = ["clang_runner.h"], - data = [ - "//toolchain/install:install_data.no_driver", - ], deps = [ - "//common:command_line", + ":tool_runner_base", "//common:ostream", "//common:vlog", "//toolchain/install:install_paths", @@ -104,6 +101,8 @@ cc_library( "language_server_subcommand.h", "link_subcommand.cpp", "link_subcommand.h", + "lld_subcommand.cpp", + "lld_subcommand.h", ], hdrs = [ "driver.h", @@ -115,6 +114,7 @@ cc_library( textual_hdrs = ["flags.def"], deps = [ ":clang_runner", + ":lld_runner", "//common:command_line", "//common:error", "//common:ostream", @@ -182,3 +182,57 @@ cc_fuzz_test( "@llvm-project//llvm:Support", ], ) + +cc_library( + name = "lld_runner", + srcs = ["lld_runner.cpp"], + hdrs = ["lld_runner.h"], + deps = [ + ":tool_runner_base", + "//common:ostream", + "//common:vlog", + "//toolchain/install:install_paths", + "@llvm-project//lld:Common", + "@llvm-project//lld:ELF", + "@llvm-project//lld:MachO", + "@llvm-project//llvm:Support", + ], +) + +cc_test( + name = "lld_runner_test", + size = "small", + srcs = ["lld_runner_test.cpp"], + env = cc_env(), + deps = [ + ":clang_runner", + ":lld_runner", + "//common:all_llvm_targets", + "//common:check", + "//common:ostream", + "//common:raw_string_ostream", + "//testing/base:capture_std_streams", + "//testing/base:file_helpers", + "//testing/base:global_exe_path", + "//testing/base:gtest_main", + "@googletest//:gtest", + "@llvm-project//llvm:Object", + "@llvm-project//llvm:Support", + "@llvm-project//llvm:TargetParser", + ], +) + +cc_library( + name = "tool_runner_base", + srcs = ["tool_runner_base.cpp"], + hdrs = ["tool_runner_base.h"], + data = [ + "//toolchain/install:install_data.no_driver", + ], + deps = [ + "//common:ostream", + "//common:vlog", + "//toolchain/install:install_paths", + "@llvm-project//llvm:Support", + ], +) diff --git a/toolchain/driver/clang_runner.cpp b/toolchain/driver/clang_runner.cpp index 2d569c7432180..ca05bd5307445 100644 --- a/toolchain/driver/clang_runner.cpp +++ b/toolchain/driver/clang_runner.cpp @@ -15,7 +15,6 @@ #include "clang/Driver/Driver.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/TextDiagnosticPrinter.h" -#include "common/command_line.h" #include "common/vlog.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ScopeExit.h" @@ -44,59 +43,20 @@ ClangRunner::ClangRunner(const InstallPaths* install_paths, llvm::StringRef target, llvm::IntrusiveRefCntPtr fs, llvm::raw_ostream* vlog_stream) - : installation_(install_paths), + : ToolRunnerBase(install_paths, vlog_stream), target_(target), fs_(std::move(fs)), - vlog_stream_(vlog_stream), diagnostic_ids_(new clang::DiagnosticIDs()) {} auto ClangRunner::Run(llvm::ArrayRef args) -> bool { // TODO: Maybe handle response file expansion similar to the Clang CLI? - // If we have a verbose logging stream, and that stream is the same as - // `llvm::errs`, then add the `-v` flag so that the driver also prints verbose - // information. - bool inject_v_arg = vlog_stream_ == &llvm::errs(); - std::array v_arg_storage; - llvm::ArrayRef maybe_v_arg; - if (inject_v_arg) { - v_arg_storage[0] = "-v"; - maybe_v_arg = v_arg_storage; - } - - CARBON_VLOG("Running Clang driver with arguments: \n"); - - // Render the arguments into null-terminated C-strings for use by the Clang - // driver. Command lines can get quite long in build systems so this tries to - // minimize the memory allocation overhead. - - // Provide the wrapped `clang` path in order to support subprocessing. We also - // set the install directory below. std::string clang_path = installation_->clang_path(); - std::array exe_arg = {clang_path}; - auto args_range = - llvm::concat(exe_arg, maybe_v_arg, args); - int total_size = 0; - for (llvm::StringRef arg : args_range) { - // Accumulate both the string size and a null terminator byte. - total_size += arg.size() + 1; - } - // Allocate one chunk of storage for the actual C-strings and a vector of - // pointers into the storage. - llvm::OwningArrayRef cstr_arg_storage(total_size); - llvm::SmallVector cstr_args; - cstr_args.reserve(args.size() + inject_v_arg + 1); - for (ssize_t i = 0; llvm::StringRef arg : args_range) { - cstr_args.push_back(&cstr_arg_storage[i]); - memcpy(&cstr_arg_storage[i], arg.data(), arg.size()); - i += arg.size(); - cstr_arg_storage[i] = '\0'; - ++i; - } - for (const char* cstr_arg : llvm::ArrayRef(cstr_args)) { - CARBON_VLOG(" '{0}'\n", cstr_arg); - } + // Rebuild the args as C-string args. + llvm::OwningArrayRef cstr_arg_storage; + llvm::SmallVector cstr_args = + BuildCStrArgs("Clang", clang_path, "-v", args, cstr_arg_storage); if (!args.empty() && args[0].starts_with("-cc1")) { CARBON_VLOG("Calling clang_main for cc1..."); diff --git a/toolchain/driver/clang_runner.h b/toolchain/driver/clang_runner.h index 4d93031b865b1..854c5bb85c224 100644 --- a/toolchain/driver/clang_runner.h +++ b/toolchain/driver/clang_runner.h @@ -10,6 +10,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VirtualFileSystem.h" +#include "toolchain/driver/tool_runner_base.h" #include "toolchain/install/install_paths.h" namespace Carbon { @@ -36,7 +37,7 @@ namespace Carbon { // standard output and standard error, and otherwise can only read and write // files based on their names described in the arguments. It doesn't provide any // higher-level abstraction such as streams for inputs or outputs. -class ClangRunner { +class ClangRunner : ToolRunnerBase { public: // Build a Clang runner that uses the provided `exe_name` and `err_stream`. // @@ -61,11 +62,8 @@ class ClangRunner { auto EnableLeakingMemory() -> void { enable_leaking_ = true; } private: - const InstallPaths* installation_; - llvm::StringRef target_; llvm::IntrusiveRefCntPtr fs_; - llvm::raw_ostream* vlog_stream_; llvm::IntrusiveRefCntPtr diagnostic_ids_; diff --git a/toolchain/driver/driver.cpp b/toolchain/driver/driver.cpp index e0bd0381e0eb2..850c029c09bca 100644 --- a/toolchain/driver/driver.cpp +++ b/toolchain/driver/driver.cpp @@ -15,6 +15,7 @@ #include "toolchain/driver/format_subcommand.h" #include "toolchain/driver/language_server_subcommand.h" #include "toolchain/driver/link_subcommand.h" +#include "toolchain/driver/lld_subcommand.h" namespace Carbon { @@ -33,6 +34,7 @@ struct Options { FormatSubcommand format; LanguageServerSubcommand language_server; LinkSubcommand link; + LldSubcommand lld; // On success, this is set to the subcommand to run. DriverSubcommand* selected_subcommand = nullptr; @@ -89,6 +91,7 @@ applies to each message that forms a diagnostic, not just the primary message. format.AddTo(b, &selected_subcommand); language_server.AddTo(b, &selected_subcommand); link.AddTo(b, &selected_subcommand); + lld.AddTo(b, &selected_subcommand); b.RequiresSubcommand(); } diff --git a/toolchain/driver/lld_runner.cpp b/toolchain/driver/lld_runner.cpp new file mode 100644 index 0000000000000..8386cd516670d --- /dev/null +++ b/toolchain/driver/lld_runner.cpp @@ -0,0 +1,59 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/driver/lld_runner.h" + +#include +#include +#include +#include + +#include "common/vlog.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" + +// Declare the supported driver flavor entry points. +// +// TODO: Currently, just ELF and MachO, but eventually we should support all of +// the LLD platforms. +// +// NOLINTBEGIN(readability-identifier-naming): External library name. +LLD_HAS_DRIVER(elf) +LLD_HAS_DRIVER(macho) +// NOLINTEND(readability-identifier-naming) + +namespace Carbon { + +auto LldRunner::LinkHelper(llvm::StringLiteral label, + llvm::ArrayRef args, + const std::string& path, lld::DriverDef driver_def) + -> bool { + // Allocate one chunk of storage for the actual C-strings and a vector of + // pointers into the storage. + llvm::OwningArrayRef cstr_arg_storage; + llvm::SmallVector cstr_args = + BuildCStrArgs("LLD", path, "-v", args, cstr_arg_storage); + + CARBON_VLOG("Running LLD {0}-platform link...\n", label); + lld::Result result = + lld::lldMain(cstr_args, llvm::outs(), llvm::errs(), {driver_def}); + + // Check for an unrecoverable error. + CARBON_CHECK(result.canRunAgain, "LLD encountered an unrecoverable error!"); + + // TODO: Should this be forwarding the full exit code? + return result.retCode == 0; +} + +auto LldRunner::ElfLink(llvm::ArrayRef args) -> bool { + return LinkHelper("GNU", args, installation_->ld_lld_path(), + {.f = lld::Gnu, .d = &lld::elf::link}); +} + +auto LldRunner::MachOLink(llvm::ArrayRef args) -> bool { + return LinkHelper("Darwin", args, installation_->ld64_lld_path(), + {.f = lld::Darwin, .d = &lld::macho::link}); +} + +} // namespace Carbon diff --git a/toolchain/driver/lld_runner.h b/toolchain/driver/lld_runner.h new file mode 100644 index 0000000000000..9143bdf040b13 --- /dev/null +++ b/toolchain/driver/lld_runner.h @@ -0,0 +1,36 @@ +// 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_DRIVER_LLD_RUNNER_H_ +#define CARBON_TOOLCHAIN_DRIVER_LLD_RUNNER_H_ + +#include "common/ostream.h" +#include "lld/Common/Driver.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "toolchain/driver/tool_runner_base.h" +#include "toolchain/install/install_paths.h" + +namespace Carbon { + +// Runs LLD in a manner similar to invoking it with the provided arguments. +class LldRunner : ToolRunnerBase { + public: + using ToolRunnerBase::ToolRunnerBase; + + // Run LLD as a GNU-style linker with the provided arguments. + auto ElfLink(llvm::ArrayRef args) -> bool; + + // Run LLD as a Darwin-style linker with the provided arguments. + auto MachOLink(llvm::ArrayRef args) -> bool; + + private: + auto LinkHelper(llvm::StringLiteral label, + llvm::ArrayRef args, const std::string& path, + lld::DriverDef driver_def) -> bool; +}; + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_DRIVER_LLD_RUNNER_H_ diff --git a/toolchain/driver/lld_runner_test.cpp b/toolchain/driver/lld_runner_test.cpp new file mode 100644 index 0000000000000..fc26f5a172350 --- /dev/null +++ b/toolchain/driver/lld_runner_test.cpp @@ -0,0 +1,210 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/driver/lld_runner.h" + +#include +#include + +#include +#include +#include + +#include "common/check.h" +#include "common/ostream.h" +#include "common/raw_string_ostream.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/Object/Binary.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Program.h" +#include "llvm/TargetParser/Host.h" +#include "testing/base/capture_std_streams.h" +#include "testing/base/file_helpers.h" +#include "testing/base/global_exe_path.h" +#include "toolchain/driver/clang_runner.h" + +namespace Carbon { +namespace { + +using ::testing::HasSubstr; +using ::testing::Not; +using ::testing::StrEq; + +TEST(LldRunnerTest, Version) { + RawStringOstream test_os; + const auto install_paths = + InstallPaths::MakeForBazelRunfiles(Testing::GetExePath()); + LldRunner runner(&install_paths, &test_os); + + std::string out; + std::string err; + EXPECT_TRUE(Testing::CallWithCapturedOutput( + out, err, [&] { return runner.ElfLink({"--version"}); })); + + // The arguments to LLD should be part of the verbose log. + EXPECT_THAT(test_os.TakeStr(), HasSubstr("--version")); + + // Nothing should print to stderr here. + EXPECT_THAT(err, StrEq("")); + + // We don't care about any particular version, just that it is printed. + EXPECT_THAT(out, HasSubstr("LLD")); + // Check that it was in fact the GNU linker. + EXPECT_THAT(out, HasSubstr("compatible with GNU linkers")); + + // Try the Darwin linker. + EXPECT_TRUE(Testing::CallWithCapturedOutput( + out, err, [&] { return runner.MachOLink({"--version"}); })); + + // Again, the arguments to LLD should be part of the verbose log. + EXPECT_THAT(test_os.TakeStr(), HasSubstr("--version")); + + // Nothing should print to stderr. + EXPECT_THAT(err, StrEq("")); + + // We don't care about any particular version. + EXPECT_THAT(out, HasSubstr("LLD")); + // The Darwin link code path doesn't print anything distinct, so instead check + // that the GNU output isn't repeated. + EXPECT_THAT(out, Not(HasSubstr("GNU"))); +} + +static auto CompileTwoSources(const InstallPaths& install_paths, + llvm::StringRef target) + -> std::pair { + std::filesystem::path test_a_file = + *Testing::WriteTestFile("test_a.cpp", "int test_a() { return 0; }"); + std::filesystem::path test_b_file = *Testing::WriteTestFile( + "test_b.cpp", "int test_a();\nint main() { return test_a(); }"); + std::filesystem::path test_a_output = *Testing::WriteTestFile("test_a.o", ""); + std::filesystem::path test_b_output = *Testing::WriteTestFile("test_b.o", ""); + + // First compile the two source files to `.o` files with Clang. + RawStringOstream verbose_out; + auto vfs = llvm::vfs::getRealFileSystem(); + ClangRunner clang(&install_paths, target, vfs, &verbose_out); + std::string target_arg = llvm::formatv("--target={0}", target).str(); + std::string out; + std::string err; + CARBON_CHECK( + Testing::CallWithCapturedOutput( + out, err, + [&] { + return clang.Run({target_arg, "-fPIE", "-c", test_a_file.string(), + "-o", test_a_output.string()}); + }), + "Verbose output from runner:\n{0}\nStderr:\n{1}\n", verbose_out.TakeStr(), + err); + verbose_out.clear(); + + CARBON_CHECK( + Testing::CallWithCapturedOutput( + out, err, + [&] { + return clang.Run({target_arg, "-fPIE", "-c", test_b_file.string(), + "-o", test_b_output.string()}); + }), + "Verbose output from runner:\n{0}\nStderr:\n{1}\n", verbose_out.TakeStr(), + err); + verbose_out.clear(); + + return {test_a_output, test_b_output}; +} + +TEST(LldRunnerTest, ElfLinkTest) { + const auto install_paths = + InstallPaths::MakeForBazelRunfiles(Testing::GetExePath()); + + std::filesystem::path test_a_output; + std::filesystem::path test_b_output; + std::tie(test_a_output, test_b_output) = + CompileTwoSources(install_paths, "aarch64-unknown-linux"); + + std::filesystem::path test_output = *Testing::WriteTestFile("test.o", ""); + + RawStringOstream verbose_out; + std::string out; + std::string err; + + LldRunner lld(&install_paths, &verbose_out); + + // Link the two object files together. + // + // TODO: Currently, this uses a relocatable link, but it would be better to do + // a full link to an executable. For that to work, we need at least the + // C-runtime built artifacts available in the toolchain. We should revisit + // this once we have those in place. This also prevents us from testing a + // failed link easily. + EXPECT_TRUE(Testing::CallWithCapturedOutput( + out, err, + [&] { + return lld.ElfLink({"-m", "aarch64linux", "--relocatable", "-o", + test_output.string(), test_a_output.string(), + test_b_output.string()}); + })) + << "Verbose output from runner:\n" + << verbose_out.TakeStr() << "\n"; + verbose_out.clear(); + + // No output should be produced. + EXPECT_THAT(out, StrEq("")); + EXPECT_THAT(err, StrEq("")); +} + +TEST(LldRunnerTest, MachOLinkTest) { + const auto install_paths = + InstallPaths::MakeForBazelRunfiles(Testing::GetExePath()); + + std::filesystem::path test_a_output; + std::filesystem::path test_b_output; + std::tie(test_a_output, test_b_output) = + CompileTwoSources(install_paths, "arm64-unknown-macosx10.4.0"); + + std::filesystem::path test_output = *Testing::WriteTestFile("test.o", ""); + + RawStringOstream verbose_out; + std::string out; + std::string err; + + // Link the two object files together. + // + // This is a somewhat arbitrary command line, and is missing the C-runtimes, + // but seems to succeed currently. The goal isn't to test any *particular* + // link, but just than an actual link occurs successfully. + LldRunner lld(&install_paths, &verbose_out); + EXPECT_TRUE(Testing::CallWithCapturedOutput( + out, err, + [&] { + return lld.MachOLink({"-arch", "arm64", "-platform_version", "macos", + "10.4.0", "10.4.0", "-o", test_output.string(), + test_a_output.string(), test_b_output.string()}); + })) + << "Verbose output from runner:\n" + << verbose_out.TakeStr() << "\n"; + verbose_out.clear(); + + // No output should be produced. + EXPECT_THAT(out, StrEq("")); + EXPECT_THAT(err, StrEq("")); + + // Re-do the link, but with only one of the inputs. This should fail due to an + // unresolved symbol. + EXPECT_FALSE(Testing::CallWithCapturedOutput( + out, err, + [&] { + return lld.MachOLink({"-arch", "arm64", "-platform_version", "macos", + "10.4.0", "10.4.0", "-o", test_output.string(), + test_b_output.string()}); + })) + << "Verbose output from runner:\n" + << verbose_out.TakeStr() << "\n"; + verbose_out.clear(); + + // The missing symbol should be diagnosed on `stderr`. + EXPECT_THAT(out, StrEq("")); + EXPECT_THAT(err, HasSubstr("undefined symbol: __Z6test_av")); +} + +} // namespace +} // namespace Carbon diff --git a/toolchain/driver/lld_subcommand.cpp b/toolchain/driver/lld_subcommand.cpp new file mode 100644 index 0000000000000..3c082fbdf31bc --- /dev/null +++ b/toolchain/driver/lld_subcommand.cpp @@ -0,0 +1,113 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/driver/lld_subcommand.h" + +#include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/Triple.h" +#include "toolchain/driver/lld_runner.h" + +namespace Carbon { + +auto LldOptions::Build(CommandLine::CommandBuilder& b) -> void { + // We want to select a default platform based on the default target. Since + // that requires some dynamic inspection of the target, do that here. + std::string default_target = llvm::sys::getDefaultTargetTriple(); + llvm::Triple default_triple(default_target); + switch (default_triple.getObjectFormat()) { + case llvm::Triple::MachO: + platform = Platform::MachO; + break; + + // We default to the GNU or Unix platform as ELF is a plausible default + // and LLD doesn't support any generic invocations. + default: + case llvm::Triple::ELF: + platform = Platform::Elf; + break; + } + + b.AddOneOfOption( + { + .name = "platform", + .help = R"""( +Platform linking style to use. The default is selected to match the default +target's platform. +)""", + }, + [&](auto& arg_b) { + arg_b.SetOneOf( + { + arg_b.OneOfValue("elf", Platform::Elf), + // Some of LLD documentation uses "Unix" or "GNU", so + // include an alias here. + arg_b.OneOfValue("gnu", Platform::Elf), + arg_b.OneOfValue("unix", Platform::Elf), + + arg_b.OneOfValue("macho", Platform::MachO), + // Darwin is also sometimes used, include it as an alias here. + arg_b.OneOfValue("darwin", Platform::MachO), + }, + &platform); + }); + b.AddStringPositionalArg( + { + .name = "ARG", + .help = R"""( +Arguments passed to LLD. +)""", + }, + [&](auto& arg_b) { arg_b.Append(&args); }); +} + +static constexpr CommandLine::CommandInfo SubcommandInfo = { + .name = "lld", + .help = R"""( +Runs LLD with the provided arguments. + +Note that a specific LLD platform must be selected, and it is actually that +particular platform's LLD-driver that is run with the arguments. There is no +generic LLD command line. + +For a given platform, this is equivalent to running that platform's LLD alias +directly, and provides the full command line interface. + +Use `carbon lld --platform=elf -- ARGS` to separate the `ARGS` forwarded to LLD +from the flags passed to the Carbon subcommand. + +Note that typically it is better to use a higher level command to link code, +such as invoking `carbon link` with the relevant flags. However, this subcommand +supports when you already have a specific invocation using existing command line +syntaxes, as well as testing and debugging of the underlying tool. +)""", +}; + +LldSubcommand::LldSubcommand() : DriverSubcommand(SubcommandInfo) {} + +// TODO: This lacks a lot of features from the main driver code. We may need to +// add more. +// https://github.com/llvm/llvm-project/blob/main/clang/tools/driver/driver.cpp +auto LldSubcommand::Run(DriverEnv& driver_env) -> DriverResult { + LldRunner runner(driver_env.installation, driver_env.vlog_stream); + + // Don't run LLD when fuzzing, as we're not currently in a good position to + // debug and fix fuzzer-found bugs within LLD. + if (driver_env.fuzzing) { + CARBON_DIAGNOSTIC( + LLDFuzzingDisallowed, Error, + "preventing fuzzing of `lld` subcommand due to external library"); + driver_env.emitter.Emit(LLDFuzzingDisallowed); + return {.success = false}; + } + + switch (options_.platform) { + case LldOptions::Platform::Elf: + return {.success = runner.ElfLink(options_.args)}; + case LldOptions::Platform::MachO: + return {.success = runner.MachOLink(options_.args)}; + } + CARBON_FATAL("Failed to find and run a valid LLD platform link!"); +} + +} // namespace Carbon diff --git a/toolchain/driver/lld_subcommand.h b/toolchain/driver/lld_subcommand.h new file mode 100644 index 0000000000000..24569cae695dd --- /dev/null +++ b/toolchain/driver/lld_subcommand.h @@ -0,0 +1,54 @@ +// 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_DRIVER_LLD_SUBCOMMAND_H_ +#define CARBON_TOOLCHAIN_DRIVER_LLD_SUBCOMMAND_H_ + +#include "common/command_line.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "toolchain/driver/driver_env.h" +#include "toolchain/driver/driver_subcommand.h" + +namespace Carbon { + +// Options for the LLD subcommand, which is just a thin wrapper. +// +// See the implementation of `Build` for documentation on members. +struct LldOptions { + // Supported linking platforms. + // + // Note that these are similar to the object formats in an LLVM triple, but we + // use a distinct enum because we only include the platforms supported by our + // subcommand which is a subset of those recognized by the LLVM triple + // infrastructure. + enum class Platform { + Elf, + MachO, + }; + + auto Build(CommandLine::CommandBuilder& b) -> void; + + Platform platform; + llvm::SmallVector args; +}; + +// Implements the LLD subcommand of the driver. +class LldSubcommand : public DriverSubcommand { + public: + explicit LldSubcommand(); + + auto BuildOptions(CommandLine::CommandBuilder& b) -> void override { + options_.Build(b); + } + + auto Run(DriverEnv& driver_env) -> DriverResult override; + + private: + LldOptions options_; +}; + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_DRIVER_LLD_SUBCOMMAND_H_ diff --git a/toolchain/driver/testdata/fail_lld_fuzzing.carbon b/toolchain/driver/testdata/fail_lld_fuzzing.carbon new file mode 100644 index 0000000000000..b1e144c75344e --- /dev/null +++ b/toolchain/driver/testdata/fail_lld_fuzzing.carbon @@ -0,0 +1,15 @@ +// 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 +// +// ARGS: --include-diagnostic-kind --fuzzing lld -- -o foo foo.o bar.o +// +// SET-CAPTURE-CONSOLE-OUTPUT +// clang-format off +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_lld_fuzzing.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/driver/testdata/fail_lld_fuzzing.carbon +// CHECK:STDERR: error: preventing fuzzing of `lld` subcommand due to external library [LLDFuzzingDisallowed] +// CHECK:STDERR: diff --git a/toolchain/driver/tool_runner_base.cpp b/toolchain/driver/tool_runner_base.cpp new file mode 100644 index 0000000000000..a3455ed546bb5 --- /dev/null +++ b/toolchain/driver/tool_runner_base.cpp @@ -0,0 +1,73 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/driver/tool_runner_base.h" + +#include + +#include "common/vlog.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" + +namespace Carbon { + +ToolRunnerBase::ToolRunnerBase(const InstallPaths* install_paths, + llvm::raw_ostream* vlog_stream) + : installation_(install_paths), vlog_stream_(vlog_stream) {} + +auto ToolRunnerBase::BuildCStrArgs(llvm::StringRef tool_name, + llvm::StringRef tool_path, + std::optional verbose_flag, + llvm::ArrayRef args, + llvm::OwningArrayRef& cstr_arg_storage) + -> llvm::SmallVector { + // TODO: Maybe handle response file expansion similar to the Clang CLI? + + // If we have a verbose logging stream, and that stream is the same as + // `llvm::errs`, then add the `-v` flag so that the driver also prints verbose + // information. + bool inject_v_arg = verbose_flag.has_value() && vlog_stream_ == &llvm::errs(); + std::array v_arg_storage; + llvm::ArrayRef maybe_v_arg; + if (inject_v_arg) { + v_arg_storage[0] = *verbose_flag; + maybe_v_arg = v_arg_storage; + } + + CARBON_VLOG("Running {} driver with arguments:\n", tool_name); + + // Render the arguments into null-terminated C-strings. Command lines can get + // quite long in build systems so this tries to minimize the memory allocation + // overhead. + + // Provide the wrapped tool path as the synthetic `argv[0]`. + std::array exe_arg = {tool_path}; + auto args_range = + llvm::concat(exe_arg, maybe_v_arg, args); + int total_size = 0; + for (llvm::StringRef arg : args_range) { + // Accumulate both the string size and a null terminator byte. + total_size += arg.size() + 1; + } + + // Allocate one chunk of storage for the actual C-strings and a vector of + // pointers into the storage. + cstr_arg_storage = llvm::OwningArrayRef(total_size); + llvm::SmallVector cstr_args; + cstr_args.reserve(args.size() + inject_v_arg + 1); + for (ssize_t i = 0; llvm::StringRef arg : args_range) { + cstr_args.push_back(&cstr_arg_storage[i]); + memcpy(&cstr_arg_storage[i], arg.data(), arg.size()); + i += arg.size(); + cstr_arg_storage[i] = '\0'; + ++i; + } + for (const char* cstr_arg : llvm::ArrayRef(cstr_args)) { + CARBON_VLOG(" '{0}'\n", cstr_arg); + } + + return cstr_args; +} + +} // namespace Carbon diff --git a/toolchain/driver/tool_runner_base.h b/toolchain/driver/tool_runner_base.h new file mode 100644 index 0000000000000..5fc4c2b33a3de --- /dev/null +++ b/toolchain/driver/tool_runner_base.h @@ -0,0 +1,65 @@ +// 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_DRIVER_TOOL_RUNNER_BASE_H_ +#define CARBON_TOOLCHAIN_DRIVER_TOOL_RUNNER_BASE_H_ + +#include + +#include "common/ostream.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "toolchain/install/install_paths.h" + +namespace Carbon { + +// Base that factors out common utilities needed when implementing a runner of +// an external tool, especially tools part of the LLVM and Clang C++ toolchain +// that Carbon will end up wrapping. +// +// Note that this struct just collects common data and helper methods, and does +// not itself impose any invariants or form a meaningful API. It should be used +// as an implementation detail only. +class ToolRunnerBase { + public: + // Construct the tool runner bas. + // + // If `vlog_stream` is provided, it will be used for `CARBON_VLOG`s. If it is + // also equal to `&llvm::errs()`, and so tied to stderr, that will be used by + // verbose flag injection helpers in this class. + explicit ToolRunnerBase(const InstallPaths* install_paths, + llvm::raw_ostream* vlog_stream = nullptr); + + protected: + // Translates `args` into C-string arguments for tool APIs based on `main`. + // + // Accepts a `tool_name` for logging, and a `tool_path` that will be used as + // the first C-string argument to simulate and `argv[0]` entry. + // + // Accepts a `cstr_arg_storage` that will provide the underlying storage for + // the C-strings, and returns a small vector of the C-string pointers. The + // returned small vector uses a large small size to allow most common command + // lines to avoid extra allocations and growth passes. + // + // Lastly accepts an optional `verbose_flag`. If provided, and if + // `vlog_stream_` is bound to stderr for this instance, the verbose flag will + // be injected at the start of the argument list. + auto BuildCStrArgs(llvm::StringRef tool_name, llvm::StringRef tool_path, + std::optional verbose_flag, + llvm::ArrayRef args, + llvm::OwningArrayRef& cstr_arg_storage) + -> llvm::SmallVector; + + // We use protected members as this base is just factoring out common + // implementation details of other runners. + // + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) + const InstallPaths* installation_; + llvm::raw_ostream* vlog_stream_; + // NOLINTEND(misc-non-private-member-variables-in-classes) +}; + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_DRIVER_TOOL_RUNNER_BASE_H_ diff --git a/toolchain/install/BUILD b/toolchain/install/BUILD index 6c520478f6fbb..61c967455abe7 100644 --- a/toolchain/install/BUILD +++ b/toolchain/install/BUILD @@ -116,11 +116,11 @@ cc_binary( ], ) +# TODO: Add remaining aliases of LLD for Windows and WASM when we have support +# for them wired up through the busybox. lld_aliases = [ "ld.lld", "ld64.lld", - "lld-link", - "wasm-ld", ] filegroup( @@ -156,17 +156,16 @@ install_dirs = { install_filegroup("core", "//core:prelude"), ], "lib/carbon/llvm/bin": [ - install_target( - "lld", - "@llvm-project//lld:lld", - executable = True, - ), install_symlink( "clang", "../../carbon-busybox", is_driver = True, ), - ] + [install_symlink(name, "lld") for name in lld_aliases], + ] + [install_symlink( + name, + "../../carbon-busybox", + is_driver = True, + ) for name in lld_aliases], "lib/carbon/llvm/lib/clang/" + LLVM_VERSION_MAJOR: [ install_filegroup("include", ":clang_headers", "staging/include/"), ], diff --git a/toolchain/install/busybox_main.cpp b/toolchain/install/busybox_main.cpp index c4a87635a839b..bfc93971e1c75 100644 --- a/toolchain/install/busybox_main.cpp +++ b/toolchain/install/busybox_main.cpp @@ -42,7 +42,20 @@ static auto Main(int argc, char** argv) -> ErrorOr { llvm::SmallVector args; args.reserve(argc + 1); if (busybox_info.mode) { - args.append({*busybox_info.mode, "--"}); + // Map busybox modes to the relevant subcommands with any flags needed to + // emulate the requested command. Typically, our busyboxed binaries redirect + // to a specific subcommand with some flags set and then pass the remaining + // busybox arguments as positional arguments to that subcommand. + // + // TODO: Add relevant flags to the `clang` subcommand and add `clang`-based + // symlinks to this like `clang++`. + auto subcommand_args = + llvm::StringSwitch>( + *busybox_info.mode) + .Case("ld.lld", {"lld", "--platform=gnu", "--"}) + .Case("ld64.lld", {"lld", "--platform=darwin", "--"}) + .Default({*busybox_info.mode, "--"}); + args.append(subcommand_args); } args.append(argv + 1, argv + argc); diff --git a/toolchain/install/install_paths.cpp b/toolchain/install/install_paths.cpp index eff97b6d80dd9..cf7d6ccf5f9fc 100644 --- a/toolchain/install/install_paths.cpp +++ b/toolchain/install/install_paths.cpp @@ -171,4 +171,28 @@ auto InstallPaths::clang_path() const -> std::string { return path.str().str(); } +auto InstallPaths::lld_path() const -> std::string { + llvm::SmallString<256> path(prefix_); + // TODO: Adjust this to work equally well on Windows. + llvm::sys::path::append(path, llvm::sys::path::Style::posix, + "lib/carbon/llvm/bin/lld"); + return path.str().str(); +} + +auto InstallPaths::ld_lld_path() const -> std::string { + llvm::SmallString<256> path(prefix_); + // TODO: Adjust this to work equally well on Windows. + llvm::sys::path::append(path, llvm::sys::path::Style::posix, + "lib/carbon/llvm/bin/ld.lld"); + return path.str().str(); +} + +auto InstallPaths::ld64_lld_path() const -> std::string { + llvm::SmallString<256> path(prefix_); + // TODO: Adjust this to work equally well on Windows. + llvm::sys::path::append(path, llvm::sys::path::Style::posix, + "lib/carbon/llvm/bin/ld64.lld"); + return path.str().str(); +} + } // namespace Carbon diff --git a/toolchain/install/install_paths.h b/toolchain/install/install_paths.h index 745d451f06a21..b28d677cffeac 100644 --- a/toolchain/install/install_paths.h +++ b/toolchain/install/install_paths.h @@ -87,6 +87,11 @@ class InstallPaths { // The path to `clang`. auto clang_path() const -> std::string; + // The path to `lld' and various aliases of `lld`. + auto lld_path() const -> std::string; + auto ld_lld_path() const -> std::string; + auto ld64_lld_path() const -> std::string; + private: friend class InstallPathsTestPeer; diff --git a/toolchain/install/install_paths_test.cpp b/toolchain/install/install_paths_test.cpp index 1ba4abfc6eb9b..cedcf2019ca53 100644 --- a/toolchain/install/install_paths_test.cpp +++ b/toolchain/install/install_paths_test.cpp @@ -75,8 +75,7 @@ class InstallPathsTest : public ::testing::Test { EXPECT_TRUE(llvm::sys::fs::is_directory(llvm_bin_path)) << "path: " << llvm_bin_path; - for (llvm::StringRef llvm_bin : - {"lld", "ld.lld", "ld64.lld", "lld-link", "wasm-ld"}) { + for (llvm::StringRef llvm_bin : {"ld.lld", "ld64.lld"}) { llvm::SmallString<128> bin_path; bin_path.assign(llvm_bin_path); llvm::sys::path::append(bin_path, llvm_bin); From d843cc53fb6f7a7c19c2ca31da9fc0f5fd73a025 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 21 Feb 2025 13:52:45 -0800 Subject: [PATCH 08/56] Small rephrasing of 'partial' interaction with final classes (#5000) I believe this reflects the intent, but the phrasing of "even if `MyBaseClass` is not" implies that `MyBaseClass` _can_ be final in `partial MyBaseClass`. Also, make clear it's allowed on `abstract` classes, not only `base` (this seems explicitly intended from the `MyAbstractClass` example around line 1482). --- docs/design/classes.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/design/classes.md b/docs/design/classes.md index f3e94b1b5b08d..84e67b994abab 100644 --- a/docs/design/classes.md +++ b/docs/design/classes.md @@ -1409,15 +1409,14 @@ The partial class type for a base class type like `MyBaseType` is written `partial MyBaseClass` to `MyBaseClass`. It changes the value by filling in the hidden vptr slot. If `MyBaseClass` is abstract, then attempting that conversion is an error. -- `partial MyBaseClass` is considered final, even if `MyBaseClass` is not. - This is despite the fact that from a data layout perspective, - `partial MyDerivedClass` will have `partial MyBaseClass` as a prefix if - `MyDerivedClass` extends `MyBaseClass`. The type `partial MyBaseClass` - specifically means "exactly this and no more." This means we don't need to - look at the hidden vptr slot, and we can instantiate it even if it doesn't - have a virtual [destructor](#destructors). -- The keyword `partial` may only be applied to a base class. For final - classes, there is no need for a second type. +- `partial MyBaseClass` is considered final. This is despite the fact that + from a data layout perspective, `partial MyDerivedClass` will have + `partial MyBaseClass` as a prefix if `MyDerivedClass` extends `MyBaseClass`. + The type `partial MyBaseClass` specifically means "exactly this and no + more." This means we don't need to look at the hidden vptr slot, and we can + instantiate it even if it doesn't have a virtual [destructor](#destructors). +- The keyword `partial` is only valid for a `base` or `abstract` class. For + final classes, there is no need for a second type. ##### Usage From 210c26e3697441c9e7e9971d1bc99446b232b70b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 21 Feb 2025 17:13:38 -0500 Subject: [PATCH 09/56] Use llvm::map_range() instead of using mapped_iterator directly (#4997) map_range() is a nice helper for constructing a pair of mapped_iterators. --- toolchain/base/value_store.h | 7 +------ toolchain/sem_ir/constant.h | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index f4751f22d38f3..8446748e6a3a2 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -116,12 +116,7 @@ class ValueStore auto [index, value] = pair; return std::pair(IdT(index), value); }; - auto range = llvm::enumerate(values_); - using Iter = - llvm::mapped_iterator; - auto begin = Iter(range.begin(), index_to_id); - auto end = Iter(range.end(), index_to_id); - return llvm::make_range(begin, end); + return llvm::map_range(llvm::enumerate(values_), index_to_id); } private: diff --git a/toolchain/sem_ir/constant.h b/toolchain/sem_ir/constant.h index 9c85d0dcb8754..67a47028cfd87 100644 --- a/toolchain/sem_ir/constant.h +++ b/toolchain/sem_ir/constant.h @@ -166,12 +166,7 @@ class ConstantValueStore { auto [index, value] = pair; return std::pair(InstId(index), value); }; - auto range = llvm::enumerate(values_); - using Iter = - llvm::mapped_iterator; - auto begin = Iter(range.begin(), index_to_id); - auto end = Iter(range.end(), index_to_id); - return llvm::make_range(begin, end); + return llvm::map_range(llvm::enumerate(values_), index_to_id); } // Returns the symbolic constants mapping as an ArrayRef whose keys are From 1d48270dc4138f5156f8dd6349e6f298ae75c1b6 Mon Sep 17 00:00:00 2001 From: Alina Sbirlea Date: Fri, 21 Feb 2025 17:29:22 -0800 Subject: [PATCH 10/56] Emit diagnostics missing declaration of owned function. (#4962) Emit diagnostics for a function declared in a non-owning library, that is not redeclared (or defined) in the owning library. --------- Co-authored-by: jonmeow --- toolchain/check/check_unit.cpp | 41 ++++ toolchain/check/check_unit.h | 5 + toolchain/check/import.cpp | 50 +++- .../function/declaration/import.carbon | 60 ++--- .../no_prelude/extern_library.carbon | 220 +++++++++++++++++- toolchain/diagnostics/diagnostic_kind.def | 1 + 6 files changed, 341 insertions(+), 36 deletions(-) diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index a191139c54f8e..b7ff88304a00e 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -20,6 +20,7 @@ #include "toolchain/check/inst.h" #include "toolchain/check/node_id_traversal.h" #include "toolchain/check/type.h" +#include "toolchain/sem_ir/import_ir.h" namespace Carbon::Check { @@ -77,6 +78,8 @@ auto CheckUnit::Run() -> void { CheckRequiredDefinitions(); + CheckRequiredDeclarations(); + context_.Finalize(); context_.VerifyOnFinish(); @@ -398,6 +401,44 @@ auto CheckUnit::ProcessNodeIds() -> bool { return true; } +auto CheckUnit::CheckRequiredDeclarations() -> void { + for (const auto& function : context_.functions().array_ref()) { + if (!function.first_owning_decl_id.has_value() && + function.extern_library_id == context_.sem_ir().library_id()) { + auto function_loc_id = + context_.insts().GetLocId(function.non_owning_decl_id); + CARBON_CHECK(function_loc_id.is_import_ir_inst_id()); + auto import_ir_id = context_.sem_ir() + .import_ir_insts() + .Get(function_loc_id.import_ir_inst_id()) + .ir_id; + auto& import_ir = context_.import_irs().Get(import_ir_id); + if (import_ir.sem_ir->package_id().has_value() != + context_.sem_ir().package_id().has_value()) { + continue; + } + + CARBON_DIAGNOSTIC( + MissingOwningDeclarationInApi, Error, + "owning declaration required for non-owning declaration"); + if (!import_ir.sem_ir->package_id().has_value() && + !context_.sem_ir().package_id().has_value()) { + emitter_.Emit(function.non_owning_decl_id, + MissingOwningDeclarationInApi); + continue; + } + + if (import_ir.sem_ir->identifiers().Get( + import_ir.sem_ir->package_id().AsIdentifierId()) == + context_.sem_ir().identifiers().Get( + context_.sem_ir().package_id().AsIdentifierId())) { + emitter_.Emit(function.non_owning_decl_id, + MissingOwningDeclarationInApi); + } + } + } +} + auto CheckUnit::CheckRequiredDefinitions() -> void { CARBON_DIAGNOSTIC(MissingDefinitionInImpl, Error, "no definition found for declaration in impl file"); diff --git a/toolchain/check/check_unit.h b/toolchain/check/check_unit.h index 5562643b115ee..9c2060e123621 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -159,6 +159,11 @@ class CheckUnit { // definition. auto CheckRequiredDefinitions() -> void; + // Checks that each required declaration is available. This applies for + // declarations that should exist in an owning library, for which an extern + // declaration exists that assigns ownership to the current API. + auto CheckRequiredDeclarations() -> void; + // Loops over all nodes in the tree. On some errors, this may return early, // for example if an unrecoverable state is encountered. // NOLINTNEXTLINE(readability-function-size) diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index 3e6c1fe0606a4..18e653ae06d53 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -265,6 +265,40 @@ static auto CopyAncestorNameScopesFromImportIR( return scope_cursor; } +// Imports the function if it's a non-owning declaration with the current file +// as owner. +static auto LoadImportForOwningFunction(Context& context, + const SemIR::File& import_sem_ir, + const SemIR::Function& function, + SemIR::InstId import_ref) { + if (!function.extern_library_id.has_value()) { + return; + } + CARBON_CHECK(function.is_extern && "Expected extern functions"); + auto lib_id = function.extern_library_id; + bool is_lib_default = lib_id == SemIR::LibraryNameId::Default; + + auto current_id = context.sem_ir().library_id(); + bool is_current_default = current_id == SemIR::LibraryNameId::Default; + + if (is_lib_default == is_current_default) { + if (is_lib_default) { + // Both libraries are default, import ref. + LoadImportRef(context, import_ref); + } else { + // Both libraries are non-default: check if they're the same named + // library, import ref if yes. + auto str_owner_library = context.string_literal_values().Get( + current_id.AsStringLiteralValueId()); + auto str_decl_library = import_sem_ir.string_literal_values().Get( + lib_id.AsStringLiteralValueId()); + if (str_owner_library == str_decl_library) { + LoadImportRef(context, import_ref); + } + } + } +} + // Adds an ImportRef for an entity, handling merging if needed. static auto AddImportRefOrMerge(Context& context, SemIR::ImportIRId ir_id, const SemIR::File& import_sem_ir, @@ -281,10 +315,20 @@ static auto AddImportRefOrMerge(Context& context, SemIR::ImportIRId ir_id, if (inserted) { auto entity_name_id = context.entity_names().Add( {.name_id = name_id, .parent_scope_id = parent_scope_id}); + auto import_ref = AddImportRef( + context, {.ir_id = ir_id, .inst_id = import_inst_id}, entity_name_id); entry.result = SemIR::ScopeLookupResult::MakeFound( - AddImportRef(context, {.ir_id = ir_id, .inst_id = import_inst_id}, - entity_name_id), - SemIR::AccessKind::Public); + import_ref, SemIR::AccessKind::Public); + + // Import references for non-owning declarations that match current library. + if (auto function_decl = + import_sem_ir.insts().TryGetAs( + import_inst_id)) { + LoadImportForOwningFunction( + context, import_sem_ir, + import_sem_ir.functions().Get(function_decl->function_id), + import_ref); + } return; } diff --git a/toolchain/check/testdata/function/declaration/import.carbon b/toolchain/check/testdata/function/declaration/import.carbon index 531ec9cc06869..567548cbad1ba 100644 --- a/toolchain/check/testdata/function/declaration/import.carbon +++ b/toolchain/check/testdata/function/declaration/import.carbon @@ -810,32 +810,32 @@ import library "extern_api"; // CHECK:STDOUT: %A.type: type = fn_type @A [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %A: %A.type = struct_value () [concrete] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] -// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %B.type: type = fn_type @B [concrete] // CHECK:STDOUT: %B: %B.type = struct_value () [concrete] -// CHECK:STDOUT: %tuple.type.85c: type = tuple_type (type) [concrete] -// CHECK:STDOUT: %tuple.type.a1c: type = tuple_type (%i32) [concrete] -// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %C.type: type = fn_type @C [concrete] // CHECK:STDOUT: %C: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %tuple.type.dd4: type = tuple_type (%i32) [concrete] +// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete] // CHECK:STDOUT: %D.type: type = fn_type @D [concrete] // CHECK:STDOUT: %D: %D.type = struct_value () [concrete] // CHECK:STDOUT: %E.type: type = fn_type @E [concrete] // CHECK:STDOUT: %E: %E.type = struct_value () [concrete] +// CHECK:STDOUT: %tuple.type.85c: type = tuple_type (type) [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] -// CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] -// CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] -// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] -// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] -// CHECK:STDOUT: %Convert.bound: = bound_method %int_1.5b8, %Convert.956 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] +// CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Convert.bound: = bound_method %int_1.5b8, %Convert.16d [concrete] // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.2(%int_32) [concrete] -// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %int_1.47b: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] -// CHECK:STDOUT: %tuple: %tuple.type.a1c = tuple_value (%int_1.5d2) [concrete] +// CHECK:STDOUT: %tuple: %tuple.type.dd4 = tuple_value (%int_1.47b) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -884,14 +884,14 @@ import library "extern_api"; // CHECK:STDOUT: %int_32.loc8_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc8_32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c] -// CHECK:STDOUT: %c.param: %tuple.type.a1c = value_param runtime_param0 -// CHECK:STDOUT: %.loc8_21.1: type = splice_block %.loc8_21.3 [concrete = constants.%tuple.type.a1c] { +// CHECK:STDOUT: %c.param: %tuple.type.dd4 = value_param runtime_param0 +// CHECK:STDOUT: %.loc8_21.1: type = splice_block %.loc8_21.3 [concrete = constants.%tuple.type.dd4] { // CHECK:STDOUT: %int_32.loc8_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc8_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc8_21.2: %tuple.type.85c = tuple_literal (%i32.loc8_17) -// CHECK:STDOUT: %.loc8_21.3: type = converted %.loc8_21.2, constants.%tuple.type.a1c [concrete = constants.%tuple.type.a1c] +// CHECK:STDOUT: %.loc8_21.3: type = converted %.loc8_21.2, constants.%tuple.type.dd4 [concrete = constants.%tuple.type.dd4] // CHECK:STDOUT: } -// CHECK:STDOUT: %c: %tuple.type.a1c = bind_name c, %c.param +// CHECK:STDOUT: %c: %tuple.type.dd4 = bind_name c, %c.param // CHECK:STDOUT: %return.param: ref %struct_type.c = out_param runtime_param1 // CHECK:STDOUT: %return: ref %struct_type.c = return_slot %return.param // CHECK:STDOUT: } @@ -954,7 +954,7 @@ import library "extern_api"; // CHECK:STDOUT: // CHECK:STDOUT: extern fn @B(%b.param_patt: %i32) -> %i32; // CHECK:STDOUT: -// CHECK:STDOUT: extern fn @C(%c.param_patt: %tuple.type.a1c) -> %struct_type.c; +// CHECK:STDOUT: extern fn @C(%c.param_patt: %tuple.type.dd4) -> %struct_type.c; // CHECK:STDOUT: // CHECK:STDOUT: extern fn @D(); // CHECK:STDOUT: @@ -967,25 +967,25 @@ import library "extern_api"; // CHECK:STDOUT: assign file.%a.var, %A.call // CHECK:STDOUT: %B.ref: %B.type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %int_1.loc13: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %impl.elem0.loc13: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %impl.elem0.loc13: %.39b = impl_witness_access constants.%impl_witness.b97, element0 [concrete = constants.%Convert.16d] // CHECK:STDOUT: %bound_method.loc13: = bound_method %int_1.loc13, %impl.elem0.loc13 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn.loc13: = specific_function %bound_method.loc13, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %int.convert_checked.loc13: init %i32 = call %specific_fn.loc13(%int_1.loc13) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc13_16.1: %i32 = value_of_initializer %int.convert_checked.loc13 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc13_16.2: %i32 = converted %int_1.loc13, %.loc13_16.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %int.convert_checked.loc13: init %i32 = call %specific_fn.loc13(%int_1.loc13) [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc13_16.1: %i32 = value_of_initializer %int.convert_checked.loc13 [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc13_16.2: %i32 = converted %int_1.loc13, %.loc13_16.1 [concrete = constants.%int_1.47b] // CHECK:STDOUT: %B.call: init %i32 = call %B.ref(%.loc13_16.2) // CHECK:STDOUT: assign file.%b.var, %B.call // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %int_1.loc14: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %.loc14_25.1: %tuple.type.985 = tuple_literal (%int_1.loc14) -// CHECK:STDOUT: %impl.elem0.loc14: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956] +// CHECK:STDOUT: %impl.elem0.loc14: %.39b = impl_witness_access constants.%impl_witness.b97, element0 [concrete = constants.%Convert.16d] // CHECK:STDOUT: %bound_method.loc14: = bound_method %int_1.loc14, %impl.elem0.loc14 [concrete = constants.%Convert.bound] // CHECK:STDOUT: %specific_fn.loc14: = specific_function %bound_method.loc14, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %specific_fn.loc14(%int_1.loc14) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_25.2: %i32 = value_of_initializer %int.convert_checked.loc14 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc14_25.3: %i32 = converted %int_1.loc14, %.loc14_25.2 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %tuple: %tuple.type.a1c = tuple_value (%.loc14_25.3) [concrete = constants.%tuple] -// CHECK:STDOUT: %.loc14_25.4: %tuple.type.a1c = converted %.loc14_25.1, %tuple [concrete = constants.%tuple] +// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %specific_fn.loc14(%int_1.loc14) [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc14_25.2: %i32 = value_of_initializer %int.convert_checked.loc14 [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc14_25.3: %i32 = converted %int_1.loc14, %.loc14_25.2 [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %tuple: %tuple.type.dd4 = tuple_value (%.loc14_25.3) [concrete = constants.%tuple] +// CHECK:STDOUT: %.loc14_25.4: %tuple.type.dd4 = converted %.loc14_25.1, %tuple [concrete = constants.%tuple] // CHECK:STDOUT: %C.call: init %struct_type.c = call %C.ref(%.loc14_25.4) // CHECK:STDOUT: assign file.%c.var, %C.call // CHECK:STDOUT: %D.ref: %D.type = name_ref D, file.%D.decl [concrete = constants.%D] diff --git a/toolchain/check/testdata/function/definition/no_prelude/extern_library.carbon b/toolchain/check/testdata/function/definition/no_prelude/extern_library.carbon index e62a123690617..fc203e702b8ff 100644 --- a/toolchain/check/testdata/function/definition/no_prelude/extern_library.carbon +++ b/toolchain/check/testdata/function/definition/no_prelude/extern_library.carbon @@ -64,16 +64,42 @@ impl library "[[@TEST_NAME]]"; // CHECK:STDERR: fn F() {} +// --- no_decl_extern.carbon + +library "[[@TEST_NAME]]"; + +extern library "no_decl" fn F(); + +// --- no_decl_extern.impl.carbon + +impl library "no_decl_extern"; + +// --- fail_no_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_no_decl.carbon:[[@LINE+5]]:1: in import [InImport] +// CHECK:STDERR: no_decl_extern.carbon:4:1: error: owning declaration required for non-owning declaration [MissingOwningDeclarationInApi] +// CHECK:STDERR: extern library "no_decl" fn F(); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +import library "no_decl_extern"; + // --- indirect_two_file_extern.carbon library "[[@TEST_NAME]]"; extern library "indirect_two_file" fn F(); -// --- indirect_two_file.carbon +// --- fail_indirect_two_file.carbon library "[[@TEST_NAME]]"; +// CHECK:STDERR: fail_indirect_two_file.carbon:[[@LINE+5]]:1: in import [InImport] +// CHECK:STDERR: indirect_two_file_extern.carbon:4:1: error: owning declaration required for non-owning declaration [MissingOwningDeclarationInApi] +// CHECK:STDERR: extern library "indirect_two_file" fn F(); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: import library "indirect_two_file_extern"; // --- fail_indirect_two_file.impl.carbon @@ -108,6 +134,40 @@ import library "in_impl_extern"; // CHECK:STDERR: extern fn F() {} + +// --- cross_package_extern.carbon + +package OtherPackage library "[[@TEST_NAME]]"; + +extern library "cross_package" fn Extern(); + +// --- cross_package.carbon + +package ThisPackage library "[[@TEST_NAME]]"; + +import OtherPackage library "cross_package_extern"; + +// This call causes the function to be imported. +fn F() { OtherPackage.Extern(); } + + +// --- unloaded_decl_extern.carbon + +library "[[@TEST_NAME]]"; + +extern library "unloaded_decl" fn ExternDecl(); + +fn NonExternDecl(); + +// --- unloaded_decl.carbon + +library "[[@TEST_NAME]]"; + +import library "unloaded_decl_extern"; + +extern fn ExternDecl(); + + // CHECK:STDOUT: --- one_file_extern.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -255,6 +315,56 @@ extern fn F() {} // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- no_decl_extern.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @F(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- no_decl_extern.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.F = import_ref Main//no_decl_extern, F, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = imports.%Main.F +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_no_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.F: %F.type = import_ref Main//no_decl_extern, F, loaded [concrete = constants.%F] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = imports.%Main.F +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @F(); +// CHECK:STDOUT: // CHECK:STDOUT: --- indirect_two_file_extern.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -271,10 +381,15 @@ extern fn F() {} // CHECK:STDOUT: // CHECK:STDOUT: extern fn @F(); // CHECK:STDOUT: -// CHECK:STDOUT: --- indirect_two_file.carbon +// CHECK:STDOUT: --- fail_indirect_two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.F = import_ref Main//indirect_two_file_extern, F, unloaded +// CHECK:STDOUT: %Main.F: %F.type = import_ref Main//indirect_two_file_extern, F, loaded [concrete = constants.%F] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -284,6 +399,8 @@ extern fn F() {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: extern fn @F(); +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_indirect_two_file.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -354,3 +471,100 @@ extern fn F() {} // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- cross_package_extern.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Extern.type: type = fn_type @Extern [concrete] +// CHECK:STDOUT: %Extern: %Extern.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Extern = %Extern.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Extern.decl: %Extern.type = fn_decl @Extern [concrete = constants.%Extern] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @Extern(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- cross_package.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %Extern.type: type = fn_type @Extern [concrete] +// CHECK:STDOUT: %Extern: %Extern.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %OtherPackage: = namespace file.%OtherPackage.import, [concrete] { +// CHECK:STDOUT: .Extern = %OtherPackage.Extern +// CHECK:STDOUT: import OtherPackage//cross_package_extern +// CHECK:STDOUT: } +// CHECK:STDOUT: %OtherPackage.Extern: %Extern.type = import_ref OtherPackage//cross_package_extern, Extern, loaded [concrete = constants.%Extern] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .OtherPackage = imports.%OtherPackage +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %OtherPackage.import = import OtherPackage +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %OtherPackage.ref: = name_ref OtherPackage, imports.%OtherPackage [concrete = imports.%OtherPackage] +// CHECK:STDOUT: %Extern.ref: %Extern.type = name_ref Extern, imports.%OtherPackage.Extern [concrete = constants.%Extern] +// CHECK:STDOUT: %Extern.call: init %empty_tuple.type = call %Extern.ref() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @Extern(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- unloaded_decl_extern.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %ExternDecl.type: type = fn_type @ExternDecl [concrete] +// CHECK:STDOUT: %ExternDecl: %ExternDecl.type = struct_value () [concrete] +// CHECK:STDOUT: %NonExternDecl.type: type = fn_type @NonExternDecl [concrete] +// CHECK:STDOUT: %NonExternDecl: %NonExternDecl.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .ExternDecl = %ExternDecl.decl +// CHECK:STDOUT: .NonExternDecl = %NonExternDecl.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %ExternDecl.decl: %ExternDecl.type = fn_decl @ExternDecl [concrete = constants.%ExternDecl] {} {} +// CHECK:STDOUT: %NonExternDecl.decl: %NonExternDecl.type = fn_decl @NonExternDecl [concrete = constants.%NonExternDecl] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @ExternDecl(); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @NonExternDecl(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- unloaded_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %ExternDecl.type: type = fn_type @ExternDecl [concrete] +// CHECK:STDOUT: %ExternDecl: %ExternDecl.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.NonExternDecl = import_ref Main//unloaded_decl_extern, NonExternDecl, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .ExternDecl = %ExternDecl.decl +// CHECK:STDOUT: .NonExternDecl = imports.%Main.NonExternDecl +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %ExternDecl.decl: %ExternDecl.type = fn_decl @ExternDecl [concrete = constants.%ExternDecl] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: extern fn @ExternDecl(); +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index d803021abed37..9cc0c87123493 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -184,6 +184,7 @@ CARBON_DIAGNOSTIC_KIND(ExplicitImportApi) CARBON_DIAGNOSTIC_KIND(RepeatedImport) CARBON_DIAGNOSTIC_KIND(FirstImported) CARBON_DIAGNOSTIC_KIND(ExportFromImpl) +CARBON_DIAGNOSTIC_KIND(MissingOwningDeclarationInApi) CARBON_DIAGNOSTIC_KIND(MissingDefinitionInImpl) CARBON_DIAGNOSTIC_KIND(MissingGenericFunctionDefinition) CARBON_DIAGNOSTIC_KIND(MissingGenericFunctionDefinitionHere) From 3ebd098597cdefd12f7f28dbcdff1a553d572f37 Mon Sep 17 00:00:00 2001 From: josh11b <15258583+josh11b@users.noreply.github.com> Date: Sat, 22 Feb 2025 13:40:43 -0800 Subject: [PATCH 11/56] Completing a type no longer ignores facet types (#5004) Make facet types complete like other types. This means that in the body of an interface, the type of `Self` is incomplete. This involved fixing an issue where eval of a specific_id that was already canonical was not resolving the specific declaration, which could occur as part of substituting into a facet type. --------- Co-authored-by: Josh L Co-authored-by: Richard Smith Co-authored-by: Dana Jansens --- toolchain/check/eval.cpp | 18 +++ toolchain/check/generic.cpp | 6 +- toolchain/check/generic.h | 6 + toolchain/check/handle_impl.cpp | 8 +- toolchain/check/name_lookup.cpp | 8 +- ..._value_to_generic_facet_value_value.carbon | 2 +- ...t_class_type_to_generic_facet_value.carbon | 12 ++ ..._value_to_generic_facet_value_value.carbon | 8 ++ .../call_method_on_generic_facet.carbon | 2 +- .../testdata/impl/extend_impl_generic.carbon | 2 +- ..._extend_partially_defined_interface.carbon | 4 +- .../fail_extend_undefined_interface.carbon | 8 +- .../impl/fail_self_type_mismatch.carbon | 58 +++++----- .../impl/lookup/no_prelude/impl_forall.carbon | 4 +- .../no_prelude/fail_extend_impl_scope.carbon | 4 +- .../impl/no_prelude/fail_impl_as_scope.carbon | 4 +- .../fail_undefined_interface.carbon | 8 +- .../no_prelude/assoc_const_in_generic.carbon | 26 +++-- .../no_prelude/fail_lookup_undefined.carbon | 4 +- .../interface/no_prelude/generic.carbon | 4 + .../testdata/where_expr/dot_self_index.carbon | 2 +- toolchain/check/type_completion.cpp | 106 ++++++++---------- toolchain/check/type_completion.h | 10 +- toolchain/diagnostics/diagnostic_kind.def | 3 +- .../lower/testdata/interface/basic.carbon | 12 -- 25 files changed, 184 insertions(+), 145 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index ca2251345c8e4..1a97f526e6af7 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -452,6 +452,24 @@ static auto GetConstantValue(EvalContext& eval_context, } if (args_id == specific.args_id) { + const auto& specific = eval_context.specifics().Get(specific_id); + // A constant specific_id should always have a resolved declaration. The + // specific_id from the instruction may coincidentally be canonical, and so + // constant evaluation gives the same value. In that case, we still need to + // ensure its declaration is resolved. + // + // However, don't resolve the declaration if the generic's eval block hasn't + // been set yet. This happens when building the eval block during import. + // + // TODO: Change importing of generic eval blocks to be less fragile and + // remove this `if` so we unconditionally call `ResolveSpecificDeclaration`. + if (!specific.decl_block_id.has_value() && eval_context.context() + .generics() + .Get(specific.generic_id) + .decl_block_id.has_value()) { + ResolveSpecificDeclaration(eval_context.context(), + eval_context.fallback_loc(), specific_id); + } return specific_id; } return MakeSpecific(eval_context.context(), eval_context.fallback_loc(), diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index 8ae449ce0dac4..c819bfd62e198 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -21,8 +21,6 @@ namespace Carbon::Check { static auto MakeSelfSpecificId(Context& context, SemIR::GenericId generic_id) -> SemIR::SpecificId; -static auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc, - SemIR::SpecificId specific_id) -> void; auto StartGenericDecl(Context& context) -> void { context.generic_region_stack().Push(); @@ -414,8 +412,8 @@ auto FinishGenericDefinition(Context& context, SemIR::GenericId generic_id) context.generic_region_stack().Pop(); } -static auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc, - SemIR::SpecificId specific_id) -> void { +auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc, + SemIR::SpecificId specific_id) -> void { // If this is the first time we've formed this specific, evaluate its decl // block to form information about the specific. if (!context.specifics().Get(specific_id).decl_block_id.has_value()) { diff --git a/toolchain/check/generic.h b/toolchain/check/generic.h index 4a842371d565e..ffda796251fd3 100644 --- a/toolchain/check/generic.h +++ b/toolchain/check/generic.h @@ -70,6 +70,12 @@ auto MakeSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id, auto MakeSelfSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id) -> SemIR::SpecificId; +// Resolve the declaration of the given specific, by evaluating the eval block +// of the corresponding generic and storing a corresponding value block in the +// specific. +auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc, + SemIR::SpecificId specific_id) -> void; + // Attempts to resolve the definition of the given specific, by evaluating the // eval block of the corresponding generic and storing a corresponding value // block in the specific. Returns false if a definition is not available. diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 013cd4b90f036..8fecb950ca75c 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -322,7 +322,13 @@ static auto CheckConstraintIsInterface(Context& context, auto complete_id = RequireCompleteFacetType( context, facet_type_id, context.insts().GetLocId(impl.constraint_id), - *facet_type, FacetTypeImpl); + *facet_type, [&] { + CARBON_DIAGNOSTIC(ImplAsIncompleteFacetType, Error, + "impl as incomplete facet type {0}", InstIdAsType); + return context.emitter().Build(impl.latest_decl_id(), + ImplAsIncompleteFacetType, + impl.constraint_id); + }); if (!complete_id.has_value()) { return nullptr; } diff --git a/toolchain/check/name_lookup.cpp b/toolchain/check/name_lookup.cpp index 712e27baf19e9..2662355cf5736 100644 --- a/toolchain/check/name_lookup.cpp +++ b/toolchain/check/name_lookup.cpp @@ -258,7 +258,13 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id, if (auto base_as_facet_type = base.TryAs()) { auto complete_id = RequireCompleteFacetType( context, context.types().GetTypeIdForTypeConstantId(base_const_id), - loc_id, *base_as_facet_type, FacetTypeMemberAccess); + loc_id, *base_as_facet_type, [&] { + CARBON_DIAGNOSTIC(QualifiedExprInIncompleteFacetTypeScope, Error, + "member access into incomplete facet type {0}", + InstIdAsType); + return context.emitter().Build( + loc_id, QualifiedExprInIncompleteFacetTypeScope, base_id); + }); if (complete_id.has_value()) { const auto& resolved = context.complete_facet_types().Get(complete_id); for (const auto& interface : resolved.required_interfaces) { diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon index 5c72520dae22b..bc6eb0297b6b9 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon @@ -174,11 +174,11 @@ fn G() { // CHECK:STDOUT: %CallGenericMethod2: %CallGenericMethod2.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.7b2: = require_complete_type %U.as_type [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] -// CHECK:STDOUT: %require_complete.02a: = require_complete_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %F.type.f439a9.2: type = fn_type @F.1, @Generic(%T) [symbolic] // CHECK:STDOUT: %F.8a2d67.2: %F.type.f439a9.2 = struct_value () [symbolic] // CHECK:STDOUT: %Generic.assoc_type.de973d.2: type = assoc_entity_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %assoc0.29ce53.2: %Generic.assoc_type.de973d.2 = assoc_entity element0, @Generic.%F.decl [symbolic] +// CHECK:STDOUT: %require_complete.02a: = require_complete_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %U.as_wit: = facet_access_witness %U [symbolic] // CHECK:STDOUT: %Generic.facet.2ea: %Generic.type.91ccba.2 = facet_value %U.as_type, %U.as_wit [symbolic] // CHECK:STDOUT: %.da8: type = fn_type_with_self_type %F.type.f439a9.2, %Generic.facet.2ea [symbolic] diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_class_type_to_generic_facet_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_class_type_to_generic_facet_value.carbon index 11259c5478478..ed61d062e7382 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_class_type_to_generic_facet_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_class_type_to_generic_facet_value.carbon @@ -182,6 +182,10 @@ fn G() { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.c3b: type = facet_type <@Generic, @Generic(%WrongGenericParam)> [concrete] +// CHECK:STDOUT: %F.type.96d: type = fn_type @F.1, @Generic(%WrongGenericParam) [concrete] +// CHECK:STDOUT: %F.86b: %F.type.96d = struct_value () [concrete] +// CHECK:STDOUT: %Generic.assoc_type.967: type = assoc_entity_type %Generic.type.c3b [concrete] +// CHECK:STDOUT: %assoc0.c10: %Generic.assoc_type.967 = assoc_entity element0, @Generic.%F.decl [concrete] // CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.d62: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic] // CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic] @@ -422,6 +426,14 @@ fn G() { // CHECK:STDOUT: specific @Generic(constants.%WrongGenericParam) { // CHECK:STDOUT: %Scalar.loc4_19.2 => constants.%WrongGenericParam // CHECK:STDOUT: %Scalar.patt.loc4_19.2 => constants.%WrongGenericParam +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.type => constants.%Generic.type.c3b +// CHECK:STDOUT: %Self.2 => constants.%Self.dee +// CHECK:STDOUT: %F.type => constants.%F.type.96d +// CHECK:STDOUT: %F => constants.%F.86b +// CHECK:STDOUT: %Generic.assoc_type => constants.%Generic.assoc_type.967 +// CHECK:STDOUT: %assoc0.loc5_9.2 => constants.%assoc0.c10 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @ImplicitAs(constants.%Dest) { diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon index f4dfaf8a295ef..e862c5efcff3e 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon @@ -590,6 +590,10 @@ fn F() { // CHECK:STDOUT: specific @Eats(constants.%Food.as_type.fae) { // CHECK:STDOUT: %Food.loc12_16.2 => constants.%Food.as_type.fae // CHECK:STDOUT: %Food.patt.loc12_16.2 => constants.%Food.as_type.fae +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Eats.type => constants.%Eats.type.f54c3d.2 +// CHECK:STDOUT: %Self.2 => constants.%Self.4eb // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @impl.2(constants.%T.fd4, constants.%Food.5fe) { @@ -657,6 +661,10 @@ fn F() { // CHECK:STDOUT: specific @Eats(constants.%Grass) { // CHECK:STDOUT: %Food.loc12_16.2 => constants.%Grass // CHECK:STDOUT: %Food.patt.loc12_16.2 => constants.%Grass +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Eats.type => constants.%Eats.type.1ae +// CHECK:STDOUT: %Self.2 => constants.%Self.4eb // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @impl.2(constants.%Animal.facet, constants.%Edible.facet) { diff --git a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon index 96cf2cbe9c1ce..2a079f7bd8d93 100644 --- a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon +++ b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon @@ -78,11 +78,11 @@ fn G() { // CHECK:STDOUT: %U.patt: %Generic.type.91ccba.2 = symbolic_binding_pattern U, 1 [symbolic] // CHECK:STDOUT: %CallGenericMethod.type: type = fn_type @CallGenericMethod [concrete] // CHECK:STDOUT: %CallGenericMethod: %CallGenericMethod.type = struct_value () [concrete] -// CHECK:STDOUT: %require_complete: = require_complete_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %F.type.f439a9.2: type = fn_type @F.1, @Generic(%T) [symbolic] // CHECK:STDOUT: %F.8a2d67.2: %F.type.f439a9.2 = struct_value () [symbolic] // CHECK:STDOUT: %Generic.assoc_type.de973d.2: type = assoc_entity_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %assoc0.29ce53.2: %Generic.assoc_type.de973d.2 = assoc_entity element0, @Generic.%F.decl [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %Generic.type.91ccba.2 [symbolic] // CHECK:STDOUT: %U.as_type: type = facet_access_type %U [symbolic] // CHECK:STDOUT: %U.as_wit: = facet_access_witness %U [symbolic] // CHECK:STDOUT: %Generic.facet.2ea: %Generic.type.91ccba.2 = facet_value %U.as_type, %U.as_wit [symbolic] diff --git a/toolchain/check/testdata/impl/extend_impl_generic.carbon b/toolchain/check/testdata/impl/extend_impl_generic.carbon index 186da0bcaba2b..3f8457a749eda 100644 --- a/toolchain/check/testdata/impl/extend_impl_generic.carbon +++ b/toolchain/check/testdata/impl/extend_impl_generic.carbon @@ -328,11 +328,11 @@ class X(U:! type) { // CHECK:STDOUT: %X.generic: %X.type = struct_value () [concrete] // CHECK:STDOUT: %X: type = class_type @X, @X(%U) [symbolic] // CHECK:STDOUT: %I.type.325e65.2: type = facet_type <@I, @I(%U)> [symbolic] -// CHECK:STDOUT: %require_complete.cfe: = require_complete_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %F.type.2aef59.2: type = fn_type @F.1, @I(%U) [symbolic] // CHECK:STDOUT: %F.bb2dd4.2: %F.type.2aef59.2 = struct_value () [symbolic] // CHECK:STDOUT: %I.assoc_type.955255.2: type = assoc_entity_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %assoc0.fef501.2: %I.assoc_type.955255.2 = assoc_entity element0, @I.%F.decl [symbolic] +// CHECK:STDOUT: %require_complete.cfe: = require_complete_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%F.decl), @impl(%U) [symbolic] // CHECK:STDOUT: %F.type.e88: type = fn_type @F.2, @impl(%U) [symbolic] // CHECK:STDOUT: %F.b02: %F.type.e88 = struct_value () [symbolic] diff --git a/toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon b/toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon index e5beff3f8d1a3..97cb46ff8e35e 100644 --- a/toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon +++ b/toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon @@ -10,9 +10,9 @@ interface I { class C { - // CHECK:STDERR: fail_extend_partially_defined_interface.carbon:[[@LINE+11]]:20: error: impl of undefined interface I [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_extend_partially_defined_interface.carbon:[[@LINE+11]]:5: error: impl as incomplete facet type `I` [ImplAsIncompleteFacetType] // CHECK:STDERR: extend impl as I; - // CHECK:STDERR: ^ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_extend_partially_defined_interface.carbon:[[@LINE-5]]:1: note: interface is currently being defined [InterfaceUndefinedWithinDefinition] // CHECK:STDERR: interface I { // CHECK:STDERR: ^~~~~~~~~~~~~ diff --git a/toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon b/toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon index 7e25502409aff..f80b3d419fca8 100644 --- a/toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon +++ b/toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon @@ -11,9 +11,9 @@ interface I; class C { - // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+7]]:18: error: impl of undefined interface I [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+7]]:3: error: impl as incomplete facet type `I` [ImplAsIncompleteFacetType] // CHECK:STDERR: extend impl as I; - // CHECK:STDERR: ^ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] // CHECK:STDERR: interface I; // CHECK:STDERR: ^~~~~~~~~~~~ @@ -22,7 +22,7 @@ class C { } fn F(c: C) { - // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+10]]:3: error: member access into undefined interface I [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+10]]:3: error: member access into incomplete facet type `I` [QualifiedExprInIncompleteFacetTypeScope] // CHECK:STDERR: C.F(); // CHECK:STDERR: ^~~ // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE-17]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] @@ -33,7 +33,7 @@ fn F(c: C) { // CHECK:STDERR: ^ // CHECK:STDERR: C.F(); - // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+14]]:3: error: member access into undefined interface I [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE+14]]:3: error: member access into incomplete facet type `I` [QualifiedExprInIncompleteFacetTypeScope] // CHECK:STDERR: c.F(); // CHECK:STDERR: ^~~ // CHECK:STDERR: fail_extend_undefined_interface.carbon:[[@LINE-28]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] diff --git a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon index 05264c03d3f59..43b6cd0271cfd 100644 --- a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon +++ b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon @@ -11,17 +11,25 @@ class C[T:! type](X:! T) {} interface I { + // This tests that inside the definition of `I`, `Self` has type `I`. + + // Below, `C(Self)` deduces `T` to be the incomplete facet type `I`, which + // leads to the error. + + // CHECK:STDERR: fail_self_type_mismatch.carbon:[[@LINE+10]]:11: error: forming value of incomplete type `I` [IncompleteTypeInValueConversion] + // CHECK:STDERR: fn F(c: C(Self)); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_self_type_mismatch.carbon:[[@LINE-9]]:1: note: interface is currently being defined [InterfaceUndefinedWithinDefinition] + // CHECK:STDERR: interface I { + // CHECK:STDERR: ^~~~~~~~~~~~~ + // CHECK:STDERR: fail_self_type_mismatch.carbon:[[@LINE-14]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: class C[T:! type](X:! T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fn F(c: C(Self)); } impl i32 as I { - // CHECK:STDERR: fail_self_type_mismatch.carbon:[[@LINE+7]]:8: error: type `C(i32)` of parameter 1 in redeclaration differs from previous parameter type `C(i32 as I)` [RedeclParamDiffersType] - // CHECK:STDERR: fn F(c: C(i32)); - // CHECK:STDERR: ^~~~~~~~~ - // CHECK:STDERR: fail_self_type_mismatch.carbon:[[@LINE-7]]:8: note: previous declaration's corresponding parameter here [RedeclParamPrevious] - // CHECK:STDERR: fn F(c: C(Self)); - // CHECK:STDERR: ^~~~~~~~~~ - // CHECK:STDERR: fn F(c: C(i32)); } @@ -39,7 +47,6 @@ impl i32 as I { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %C.dbb: type = class_type @C, @C(%I.type, %Self) [symbolic] // CHECK:STDOUT: %F.type.cf0: type = fn_type @F.1 [concrete] // CHECK:STDOUT: %F.bc6: %F.type.cf0 = struct_value () [concrete] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [concrete] @@ -51,7 +58,6 @@ impl i32 as I { // CHECK:STDOUT: %F.type.066: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.9ec: %F.type.066 = struct_value () [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %i32, %impl_witness [concrete] -// CHECK:STDOUT: %C.d7a: type = class_type @C, @C(%I.type, %I.facet) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -93,16 +99,16 @@ impl i32 as I { // CHECK:STDOUT: interface @I { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %F.decl: %F.type.cf0 = fn_decl @F.1 [concrete = constants.%F.bc6] { -// CHECK:STDOUT: %c.patt: @F.1.%C.loc14_17.1 (%C.dbb) = binding_pattern c -// CHECK:STDOUT: %c.param_patt: @F.1.%C.loc14_17.1 (%C.dbb) = value_param_pattern %c.patt, runtime_param0 +// CHECK:STDOUT: %c.patt: = binding_pattern c +// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 // CHECK:STDOUT: } { -// CHECK:STDOUT: %c.param: @F.1.%C.loc14_17.1 (%C.dbb) = value_param runtime_param0 -// CHECK:STDOUT: %.loc14: type = splice_block %C.loc14_17.2 [symbolic = %C.loc14_17.1 (constants.%C.dbb)] { +// CHECK:STDOUT: %c.param: = value_param runtime_param0 +// CHECK:STDOUT: %.loc29: type = splice_block %C [concrete = ] { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %C.loc14_17.2: type = class_type @C, @C(constants.%I.type, constants.%Self) [symbolic = %C.loc14_17.1 (constants.%C.dbb)] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%I.type, ) [concrete = ] // CHECK:STDOUT: } -// CHECK:STDOUT: %c: @F.1.%C.loc14_17.1 (%C.dbb) = bind_name c, %c.param +// CHECK:STDOUT: %c: = bind_name c, %c.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %F.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -119,7 +125,7 @@ impl i32 as I { // CHECK:STDOUT: %c.param_patt: %C.6fb = value_param_pattern %c.patt, runtime_param0 // CHECK:STDOUT: } { // CHECK:STDOUT: %c.param: %C.6fb = value_param runtime_param0 -// CHECK:STDOUT: %.loc25: type = splice_block %C [concrete = constants.%C.6fb] { +// CHECK:STDOUT: %.loc33: type = splice_block %C [concrete = constants.%C.6fb] { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -153,9 +159,8 @@ impl i32 as I { // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %C.loc14_17.1: type = class_type @C, @C(constants.%I.type, %Self) [symbolic = %C.loc14_17.1 (constants.%C.dbb)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%c.param_patt: @F.1.%C.loc14_17.1 (%C.dbb)); +// CHECK:STDOUT: fn(%c.param_patt: ); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F.2(%c.param_patt: %C.6fb); @@ -167,20 +172,17 @@ impl i32 as I { // CHECK:STDOUT: %X.patt.loc11_19.2 => constants.%X // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%I.type, constants.%Self) { +// CHECK:STDOUT: specific @C(constants.%I.type, ) { // CHECK:STDOUT: %T.loc11_9.2 => constants.%I.type // CHECK:STDOUT: %T.patt.loc11_9.2 => constants.%I.type -// CHECK:STDOUT: %X.loc11_19.2 => constants.%Self -// CHECK:STDOUT: %X.patt.loc11_19.2 => constants.%Self +// CHECK:STDOUT: %X.loc11_19.2 => +// CHECK:STDOUT: %X.patt.loc11_19.2 => // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F.1(constants.%Self) { // CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %C.loc14_17.1 => constants.%C.dbb // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%I.type, @F.1.%Self) {} -// CHECK:STDOUT: // CHECK:STDOUT: specific @C(type, constants.%i32) { // CHECK:STDOUT: %T.loc11_9.2 => type // CHECK:STDOUT: %T.patt.loc11_9.2 => type @@ -190,13 +192,5 @@ impl i32 as I { // CHECK:STDOUT: // CHECK:STDOUT: specific @F.1(constants.%I.facet) { // CHECK:STDOUT: %Self => constants.%I.facet -// CHECK:STDOUT: %C.loc14_17.1 => constants.%C.d7a -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%I.type, constants.%I.facet) { -// CHECK:STDOUT: %T.loc11_9.2 => constants.%I.type -// CHECK:STDOUT: %T.patt.loc11_9.2 => constants.%I.type -// CHECK:STDOUT: %X.loc11_19.2 => constants.%I.facet -// CHECK:STDOUT: %X.patt.loc11_19.2 => constants.%I.facet // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon b/toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon index 6e23e97c8646d..4d17bd0d9b7db 100644 --- a/toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon +++ b/toolchain/check/testdata/impl/lookup/no_prelude/impl_forall.carbon @@ -59,11 +59,11 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: %V.patt: type = symbolic_binding_pattern V, 0 [symbolic] // CHECK:STDOUT: %A.13025a.2: type = class_type @A, @A(%V) [symbolic] // CHECK:STDOUT: %I.type.325e65.2: type = facet_type <@I, @I(%V)> [symbolic] -// CHECK:STDOUT: %require_complete.cfebb2.1: = require_complete_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %F.type.2aef59.2: type = fn_type @F.1, @I(%V) [symbolic] // CHECK:STDOUT: %F.bb2dd4.2: %F.type.2aef59.2 = struct_value () [symbolic] // CHECK:STDOUT: %I.assoc_type.955255.2: type = assoc_entity_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %assoc0.fef501.2: %I.assoc_type.955255.2 = assoc_entity element0, @I.%F.decl [symbolic] +// CHECK:STDOUT: %require_complete.cfebb2.1: = require_complete_type %I.type.325e65.2 [symbolic] // CHECK:STDOUT: %impl_witness.ab3b51.1: = impl_witness (@impl.%F.decl), @impl(%V) [symbolic] // CHECK:STDOUT: %F.type.0fea45.1: type = fn_type @F.2, @impl(%V) [symbolic] // CHECK:STDOUT: %F.d6ae34.1: %F.type.0fea45.1 = struct_value () [symbolic] @@ -84,11 +84,11 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: %complete_type.84bb3d.3: = complete_type_witness %struct_type.n.848971.3 [symbolic] // CHECK:STDOUT: %require_complete.5b8aee.2: = require_complete_type %A.13025a.3 [symbolic] // CHECK:STDOUT: %I.type.325e65.3: type = facet_type <@I, @I(%W)> [symbolic] -// CHECK:STDOUT: %require_complete.cfebb2.2: = require_complete_type %I.type.325e65.3 [symbolic] // CHECK:STDOUT: %F.type.2aef59.3: type = fn_type @F.1, @I(%W) [symbolic] // CHECK:STDOUT: %F.bb2dd4.3: %F.type.2aef59.3 = struct_value () [symbolic] // CHECK:STDOUT: %I.assoc_type.955255.3: type = assoc_entity_type %I.type.325e65.3 [symbolic] // CHECK:STDOUT: %assoc0.fef501.3: %I.assoc_type.955255.3 = assoc_entity element0, @I.%F.decl [symbolic] +// CHECK:STDOUT: %require_complete.cfebb2.2: = require_complete_type %I.type.325e65.3 [symbolic] // CHECK:STDOUT: %impl_witness.ab3b51.2: = impl_witness (@impl.%F.decl), @impl(%W) [symbolic] // CHECK:STDOUT: %F.type.0fea45.2: type = fn_type @F.2, @impl(%W) [symbolic] // CHECK:STDOUT: %F.d6ae34.2: %F.type.0fea45.2 = struct_value () [symbolic] diff --git a/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon b/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon index 5bb330ad0e9ad..7518851e8296f 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon @@ -42,9 +42,9 @@ interface Z { // CHECK:STDERR: extend impl as Z { // CHECK:STDERR: ^~ // CHECK:STDERR: - // CHECK:STDERR: fail_extend_impl_self_interface.carbon:[[@LINE+7]]:18: error: impl of undefined interface Z [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_extend_impl_self_interface.carbon:[[@LINE+7]]:3: error: impl as incomplete facet type `Z` [ImplAsIncompleteFacetType] // CHECK:STDERR: extend impl as Z { - // CHECK:STDERR: ^ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_extend_impl_self_interface.carbon:[[@LINE-10]]:1: note: interface is currently being defined [InterfaceUndefinedWithinDefinition] // CHECK:STDERR: interface Z { // CHECK:STDERR: ^~~~~~~~~~~~~ diff --git a/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon b/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon index aec43b4a0a4c9..e79c47b5b3e4f 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon @@ -49,9 +49,9 @@ interface Z { // CHECK:STDERR: impl as Z { // CHECK:STDERR: ^~ // CHECK:STDERR: - // CHECK:STDERR: fail_impl_as_self_interface.carbon:[[@LINE+7]]:12: error: impl of undefined interface Z [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_impl_as_self_interface.carbon:[[@LINE+7]]:4: error: impl as incomplete facet type `Z` [ImplAsIncompleteFacetType] // CHECK:STDERR: impl as Z { - // CHECK:STDERR: ^ + // CHECK:STDERR: ^~~~~~~~~~~ // CHECK:STDERR: fail_impl_as_self_interface.carbon:[[@LINE-10]]:1: note: interface is currently being defined [InterfaceUndefinedWithinDefinition] // CHECK:STDERR: interface Z { // CHECK:STDERR: ^~~~~~~~~~~~~ diff --git a/toolchain/check/testdata/impl/no_prelude/fail_undefined_interface.carbon b/toolchain/check/testdata/impl/no_prelude/fail_undefined_interface.carbon index 584082f1832fa..6a854ba7f1ce9 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_undefined_interface.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_undefined_interface.carbon @@ -13,9 +13,9 @@ library "[[@TEST_NAME]]"; interface I; -// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE+7]]:12: error: impl of undefined interface I [ResolveFacetTypeWithUndefinedInterface] +// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE+7]]:1: error: impl as incomplete facet type `I` [ImplAsIncompleteFacetType] // CHECK:STDERR: impl {} as I {} -// CHECK:STDERR: ^ +// CHECK:STDERR: ^~~~~~~~~~~~~~ // CHECK:STDERR: fail_empty_struct.carbon:[[@LINE-4]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] // CHECK:STDERR: interface I; // CHECK:STDERR: ^~~~~~~~~~~~ @@ -28,9 +28,9 @@ library "[[@TEST_NAME]]"; interface J; class C {} -// CHECK:STDERR: fail_class.carbon:[[@LINE+7]]:11: error: impl of undefined interface J [ResolveFacetTypeWithUndefinedInterface] +// CHECK:STDERR: fail_class.carbon:[[@LINE+7]]:1: error: impl as incomplete facet type `J` [ImplAsIncompleteFacetType] // CHECK:STDERR: impl C as J {} -// CHECK:STDERR: ^ +// CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: fail_class.carbon:[[@LINE-5]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] // CHECK:STDERR: interface J; // CHECK:STDERR: ^~~~~~~~~~~~ diff --git a/toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon b/toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon index 68827f87da08a..e479606de4a4f 100644 --- a/toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon +++ b/toolchain/check/testdata/interface/no_prelude/assoc_const_in_generic.carbon @@ -35,8 +35,8 @@ fn H() { // CHECK:STDOUT: %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 2 [symbolic] // CHECK:STDOUT: %U.patt: type = symbolic_binding_pattern U, 2 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T) [symbolic] -// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] +// CHECK:STDOUT: %F.type.2ae: type = fn_type @F, @I(%T) [symbolic] +// CHECK:STDOUT: %F.bb2: %F.type.2ae = struct_value () [symbolic] // CHECK:STDOUT: %I.assoc_type.955: type = assoc_entity_type %I.type.325 [symbolic] // CHECK:STDOUT: %assoc0.fef: %I.assoc_type.955 = assoc_entity element0, @I.%F.decl [symbolic] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] @@ -48,9 +48,11 @@ fn H() { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %G.specific_fn: = specific_function %G, @G(%empty_struct_type) [concrete] // CHECK:STDOUT: %I.type.885: type = facet_type <@I, @I(%empty_struct_type)> [concrete] -// CHECK:STDOUT: %complete_type.788: = complete_type_witness %I.type.885 [concrete] +// CHECK:STDOUT: %F.type.684: type = fn_type @F, @I(%empty_struct_type) [concrete] +// CHECK:STDOUT: %F.a8d: %F.type.684 = struct_value () [concrete] // CHECK:STDOUT: %I.assoc_type.67f: type = assoc_entity_type %I.type.885 [concrete] // CHECK:STDOUT: %assoc0.639: %I.assoc_type.67f = assoc_entity element0, @I.%F.decl [concrete] +// CHECK:STDOUT: %complete_type.788: = complete_type_witness %I.type.885 [concrete] // CHECK:STDOUT: %complete_type.973: = complete_type_witness %I.assoc_type.67f [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -84,14 +86,14 @@ fn H() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc11_13.2)> [symbolic = %I.type (constants.%I.type.325)] // CHECK:STDOUT: %Self.2: %I.type.325 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type)] -// CHECK:STDOUT: %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type.2ae)] +// CHECK:STDOUT: %F: @I.%F.type (%F.type.2ae) = struct_value () [symbolic = %F (constants.%F.bb2)] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I.%I.type (%I.type.325) [symbolic = %I.assoc_type (constants.%I.assoc_type.955)] // CHECK:STDOUT: %assoc0.loc12_22.2: @I.%I.assoc_type (%I.assoc_type.955) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc12_22.2 (constants.%assoc0.fef)] // CHECK:STDOUT: // CHECK:STDOUT: interface { // CHECK:STDOUT: %Self.1: @I.%I.type (%I.type.325) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] -// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = @I.%F (constants.%F)] { +// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type.2ae) = fn_decl @F [symbolic = @I.%F (constants.%F.bb2)] { // CHECK:STDOUT: %U.patt.loc12_8.2: type = symbolic_binding_pattern U, 2 [symbolic = %U.patt.loc12_8.1 (constants.%U.patt)] // CHECK:STDOUT: %U.param_patt: type = value_param_pattern %U.patt.loc12_8.2, runtime_param [symbolic = %U.patt.loc12_8.1 (constants.%U.patt)] // CHECK:STDOUT: %return.patt: @F.%U.loc12_8.1 (%U) = return_slot_pattern @@ -158,8 +160,8 @@ fn H() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %I.type => constants.%I.type.325 // CHECK:STDOUT: %Self.2 => constants.%Self -// CHECK:STDOUT: %F.type => constants.%F.type -// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %F.type => constants.%F.type.2ae +// CHECK:STDOUT: %F => constants.%F.bb2 // CHECK:STDOUT: %I.assoc_type => constants.%I.assoc_type.955 // CHECK:STDOUT: %assoc0.loc12_22.2 => constants.%assoc0.fef // CHECK:STDOUT: } @@ -193,5 +195,13 @@ fn H() { // CHECK:STDOUT: specific @I(constants.%empty_struct_type) { // CHECK:STDOUT: %T.loc11_13.2 => constants.%empty_struct_type // CHECK:STDOUT: %T.patt.loc11_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.885 +// CHECK:STDOUT: %Self.2 => constants.%Self +// CHECK:STDOUT: %F.type => constants.%F.type.684 +// CHECK:STDOUT: %F => constants.%F.a8d +// CHECK:STDOUT: %I.assoc_type => constants.%I.assoc_type.67f +// CHECK:STDOUT: %assoc0.loc12_22.2 => constants.%assoc0.639 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon b/toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon index 1869b426c7764..24d46654589e5 100644 --- a/toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon +++ b/toolchain/check/testdata/interface/no_prelude/fail_lookup_undefined.carbon @@ -20,7 +20,7 @@ interface Undefined; fn Undefined.F(); fn Test() { - // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE+7]]:3: error: member access into undefined interface Undefined [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE+7]]:3: error: member access into incomplete facet type `Undefined` [QualifiedExprInIncompleteFacetTypeScope] // CHECK:STDERR: Undefined.G(); // CHECK:STDERR: ^~~~~~~~~~~ // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE-15]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] @@ -31,7 +31,7 @@ fn Test() { } interface BeingDefined { - // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE+7]]:13: error: member access into undefined interface BeingDefined [ResolveFacetTypeWithUndefinedInterface] + // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE+7]]:13: error: member access into incomplete facet type `BeingDefined` [QualifiedExprInIncompleteFacetTypeScope] // CHECK:STDERR: fn H() -> BeingDefined.T; // CHECK:STDERR: ^~~~~~~~~~~~~~ // CHECK:STDERR: fail_lookup_undefined.carbon:[[@LINE-4]]:1: note: interface is currently being defined [InterfaceUndefinedWithinDefinition] diff --git a/toolchain/check/testdata/interface/no_prelude/generic.carbon b/toolchain/check/testdata/interface/no_prelude/generic.carbon index ca77c1df9f45d..a849e1341c656 100644 --- a/toolchain/check/testdata/interface/no_prelude/generic.carbon +++ b/toolchain/check/testdata/interface/no_prelude/generic.carbon @@ -518,6 +518,10 @@ fn G(T:! Generic(B)) { // CHECK:STDOUT: specific @Generic(constants.%A) { // CHECK:STDOUT: %T.loc4_19.2 => constants.%A // CHECK:STDOUT: %T.patt.loc4_19.2 => constants.%A +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.type => constants.%Generic.type.c7c +// CHECK:STDOUT: %Self.2 => constants.%Self // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.a53) { diff --git a/toolchain/check/testdata/where_expr/dot_self_index.carbon b/toolchain/check/testdata/where_expr/dot_self_index.carbon index 5832d316fca41..fbff12bdeb6d8 100644 --- a/toolchain/check/testdata/where_expr/dot_self_index.carbon +++ b/toolchain/check/testdata/where_expr/dot_self_index.carbon @@ -37,9 +37,9 @@ fn G(U: Empty(i32) where .A = i32*) { // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %Empty.type.3e5fde.2: type = facet_type <@Empty, @Empty(%T)> [symbolic] // CHECK:STDOUT: %.Self.c95: %Empty.type.3e5fde.2 = bind_symbolic_name .Self [symbolic] -// CHECK:STDOUT: %require_complete.22f: = require_complete_type %Empty.type.3e5fde.2 [symbolic] // CHECK:STDOUT: %Empty.assoc_type.54c14f.2: type = assoc_entity_type %Empty.type.3e5fde.2 [symbolic] // CHECK:STDOUT: %assoc0.68f673.2: %Empty.assoc_type.54c14f.2 = assoc_entity element0, @Empty.%A [symbolic] +// CHECK:STDOUT: %require_complete.22f: = require_complete_type %Empty.type.3e5fde.2 [symbolic] // CHECK:STDOUT: %.Self.as_type.a75: type = facet_access_type %.Self.c95 [symbolic] // CHECK:STDOUT: %.Self.as_wit.da4: = facet_access_witness %.Self.c95 [symbolic] // CHECK:STDOUT: %Empty.facet.bea: %Empty.type.3e5fde.2 = facet_value %.Self.as_type.a75, %.Self.as_wit.da4 [symbolic] diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 2104090684fdb..4935907f7b9a7 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -283,6 +283,52 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { Push(inst.inner_id); break; } + case CARBON_KIND(SemIR::FacetType inst): { + if (context_.complete_facet_types() + .TryGetId(inst.facet_type_id) + .has_value()) { + break; + } + const auto& facet_type_info = + context_.facet_types().Get(inst.facet_type_id); + + SemIR::CompleteFacetType result; + result.required_interfaces.reserve( + facet_type_info.impls_constraints.size()); + // Every mentioned interface needs to be defined. + for (auto impl_interface : facet_type_info.impls_constraints) { + // TODO: expand named constraints + auto interface_id = impl_interface.interface_id; + const auto& interface = context_.interfaces().Get(interface_id); + if (!interface.is_defined()) { + if (diagnoser_) { + auto builder = diagnoser_(); + NoteUndefinedInterface(context_, interface_id, builder); + builder.Emit(); + } + return false; + } + + if (impl_interface.specific_id.has_value()) { + ResolveSpecificDefinition(context_, loc_, impl_interface.specific_id); + } + result.required_interfaces.push_back( + {.interface_id = interface_id, + .specific_id = impl_interface.specific_id}); + } + // TODO: Sort and deduplicate result.required_interfaces. For now, we have + // at most one. + CARBON_CHECK(result.required_interfaces.size() <= 1); + + // TODO: Distinguish interfaces that are required but would not be + // implemented, such as those from `where .Self impls I`. + result.num_to_impl = result.required_interfaces.size(); + + // TODO: Process other kinds of requirements. + context_.complete_facet_types().Add(inst.facet_type_id, result); + break; + } + default: break; } @@ -574,70 +620,16 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, return true; } -static auto AddCompleteFacetType(Context& context, SemIR::LocId loc_id, - SemIR::FacetTypeId facet_type_id, - FacetTypeContext context_for_diagnostics) - -> SemIR::CompleteFacetTypeId { - const auto& facet_type_info = context.facet_types().Get(facet_type_id); - - SemIR::CompleteFacetType result; - result.required_interfaces.reserve(facet_type_info.impls_constraints.size()); - // Every mentioned interface needs to be defined. - for (auto impl_interface : facet_type_info.impls_constraints) { - // TODO: expand named constraints - auto interface_id = impl_interface.interface_id; - const auto& interface = context.interfaces().Get(interface_id); - if (!interface.is_defined()) { - CARBON_DIAGNOSTIC( - ResolveFacetTypeWithUndefinedInterface, Error, - "{0:=0:member access into|=1:impl of} undefined interface {1}", - IntAsSelect, SemIR::NameId); - auto builder = context.emitter().Build( - loc_id, ResolveFacetTypeWithUndefinedInterface, - static_cast(context_for_diagnostics), interface.name_id); - NoteUndefinedInterface(context, interface_id, builder); - builder.Emit(); - return SemIR::CompleteFacetTypeId::None; - } - - if (impl_interface.specific_id.has_value()) { - ResolveSpecificDefinition(context, loc_id, impl_interface.specific_id); - } - result.required_interfaces.push_back( - {.interface_id = interface_id, - .specific_id = impl_interface.specific_id}); - } - // TODO: Sort and deduplicate result.required_interfaces. For now, we have at - // most one. - CARBON_CHECK(result.required_interfaces.size() <= 1); - - // TODO: Distinguish interfaces that are required but would not be - // implemented, such as those from `where .Self impls I`. - result.num_to_impl = result.required_interfaces.size(); - return context.complete_facet_types().Add(facet_type_id, result); -} - -// TODO: RequireCompleteType should do these checks, this should just return -// additional information. auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, SemIR::LocId loc_id, const SemIR::FacetType& facet_type, - FacetTypeContext context_for_diagnostics) + Context::BuildDiagnosticFn diagnoser) -> SemIR::CompleteFacetTypeId { - if (!RequireCompleteType( - context, type_id, loc_id, [&]() -> Context::DiagnosticBuilder { - CARBON_FATAL("Unreachable, facet types are always complete."); - })) { + if (!RequireCompleteType(context, type_id, loc_id, diagnoser)) { return SemIR::CompleteFacetTypeId::None; } - auto complete_id = - context.complete_facet_types().TryGetId(facet_type.facet_type_id); - if (!complete_id.has_value()) { - complete_id = AddCompleteFacetType( - context, loc_id, facet_type.facet_type_id, context_for_diagnostics); - } - return complete_id; + return context.complete_facet_types().TryGetId(facet_type.facet_type_id); } auto AsCompleteType(Context& context, SemIR::TypeId type_id, diff --git a/toolchain/check/type_completion.h b/toolchain/check/type_completion.h index 923c99ffca231..3c743c054525b 100644 --- a/toolchain/check/type_completion.h +++ b/toolchain/check/type_completion.h @@ -48,16 +48,12 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, Context::BuildDiagnosticFn diagnoser, Context::BuildDiagnosticFn abstract_diagnoser) -> bool; -// Like `RequireCompleteType`, but also require the facet type to be fully -// defined with known members. If it uses some incomplete interface, diagnoses -// the problem and returns None. -// TODO: Get rid of this enum and use the `RequireCompleteType` diagnostic -// mechanism instead. -enum FacetTypeContext { FacetTypeMemberAccess, FacetTypeImpl }; +// Like `RequireCompleteType`, but only for facet types. If it uses some +// incomplete interface, diagnoses the problem and returns `None`. auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, SemIR::LocId loc_id, const SemIR::FacetType& facet_type, - FacetTypeContext context_for_diagnostics) + Context::BuildDiagnosticFn diagnoser) -> SemIR::CompleteFacetTypeId; // Returns the type `type_id` if it is a complete type, or produces an diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 9cc0c87123493..43a954a096445 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -284,6 +284,7 @@ CARBON_DIAGNOSTIC_KIND(ExtendImplOutsideClass) CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAs) CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAsDefault) CARBON_DIAGNOSTIC_KIND(ImplAccessMemberBeforeComplete) +CARBON_DIAGNOSTIC_KIND(ImplAsIncompleteFacetType) CARBON_DIAGNOSTIC_KIND(ImplAsNonFacetType) CARBON_DIAGNOSTIC_KIND(ImplAsOutsideClass) CARBON_DIAGNOSTIC_KIND(ImplAssociatedConstantNeedsValue) @@ -411,6 +412,7 @@ CARBON_DIAGNOSTIC_KIND(UnexpectedDeclNameParams) CARBON_DIAGNOSTIC_KIND(QualifiedNameInNonScope) CARBON_DIAGNOSTIC_KIND(QualifiedNameNonScopeEntity) CARBON_DIAGNOSTIC_KIND(QualifiedExprInIncompleteClassScope) +CARBON_DIAGNOSTIC_KIND(QualifiedExprInIncompleteFacetTypeScope) CARBON_DIAGNOSTIC_KIND(QualifiedExprUnsupported) CARBON_DIAGNOSTIC_KIND(QualifiedExprNameNotFound) CARBON_DIAGNOSTIC_KIND(UseOfNonExprAsValue) @@ -448,7 +450,6 @@ CARBON_DIAGNOSTIC_KIND(WhereOnNonFacetType) CARBON_DIAGNOSTIC_KIND(AssociatedConstantNotConstantAfterConversion) CARBON_DIAGNOSTIC_KIND(AssociatedConstantWithDifferentValues) CARBON_DIAGNOSTIC_KIND(RewriteForAssociatedFunction) -CARBON_DIAGNOSTIC_KIND(ResolveFacetTypeWithUndefinedInterface) // Pattern matching diagnostics. CARBON_DIAGNOSTIC_KIND(TuplePatternSizeDoesntMatchLiteral) diff --git a/toolchain/lower/testdata/interface/basic.carbon b/toolchain/lower/testdata/interface/basic.carbon index 68dc97cabeb0b..5df8cc9d65f4c 100644 --- a/toolchain/lower/testdata/interface/basic.carbon +++ b/toolchain/lower/testdata/interface/basic.carbon @@ -16,11 +16,6 @@ interface I { // you can't pass a facet around at runtime, so make sure it works. fn F(T: I) -> I { return T; } -interface J; - -// Declared-but-not-defined interfaces are still complete types. -fn G(T: J) {} - // CHECK:STDOUT: ; ModuleID = 'basic.carbon' // CHECK:STDOUT: source_filename = "basic.carbon" // CHECK:STDOUT: @@ -29,11 +24,6 @@ fn G(T: J) {} // CHECK:STDOUT: ret void, !dbg !7 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define void @_CG.Main() !dbg !8 { -// CHECK:STDOUT: entry: -// CHECK:STDOUT: ret void, !dbg !9 -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -45,5 +35,3 @@ fn G(T: J) {} // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 17, column: 19, scope: !4) -// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "G", linkageName: "_CG.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !9 = !DILocation(line: 22, column: 1, scope: !8) From 5b67bb89819753e6e0c5280696e8c3067dd5e41f Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Mon, 24 Feb 2025 09:59:36 +0100 Subject: [PATCH 12/56] Refactor name poisoning tests to be more organized, complete and consistent (#4987) This is also following https://github.com/carbon-language/carbon-lang/pull/4900#discussion_r1945606053, which points that name poisoning tests are not in the correct place. Part of #4622. --- .../class/no_prelude/name_poisoning.carbon | 835 ++++++++++- .../no_prelude/name_poisoning.carbon | 1284 ++++------------- .../impl/no_prelude/name_poisoning.carbon | 871 +++++++++++ .../no_prelude/name_poisoning.carbon | 458 ++++++ 4 files changed, 2468 insertions(+), 980 deletions(-) create mode 100644 toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon create mode 100644 toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon diff --git a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon index ab2fc9765906e..ea59e93894b13 100644 --- a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon @@ -2,14 +2,249 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// EXTRA-ARGS: --no-dump-sem-ir -// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/name_poisoning.carbon // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/name_poisoning.carbon +// --- no_poison.carbon + +library "[[@TEST_NAME]]"; + +class C; + +// `N.F` uses `N.C` and not `package.C`. +namespace N; +class N.C {} +fn N.F(x: C); + +fn TestCall(x: N.C) { + // `N.F` accepts an `N.C` not a `package.C`. + N.F(x); +} + +// --- poison.carbon + +library "[[@TEST_NAME]]"; + +class C; + +namespace N; +// Use `package.C` and poison `N.C`. +fn N.F(x: C); + +// --- fail_declare_after_poison.carbon + +library "[[@TEST_NAME]]"; + +class C; + +namespace N; +// Use `package.C` and poison `N.C`. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:11: error: name `C` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: C); +// CHECK:STDERR: ^ +fn N.F(x: C); + +// Failure: `N.C` declared after it was poisoned. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: class N.C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +class N.C; + +// --- fail_use_poison.carbon + +library "[[@TEST_NAME]]"; + +class C; + +namespace N; +// Use `package.C` and poison `N.C`. +fn N.F1() -> C; + +// Use `N.C` which was poisoned and not declared. +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:14: error: member name `C` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2() -> N.C; +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2() -> N.C; + +// --- fail_use_declaration_after_poison.carbon + +library "[[@TEST_NAME]]"; + +class C; + +namespace N; +// Use `package.C` and poison `N.C`. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:12: error: name `C` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F1(x: C); +// CHECK:STDERR: ^ +fn N.F1(x: C); + +// Failure: N.C declared after it was poisoned. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: class N.C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +class N.C; + +// Failure: `N.C` used after declaration failed. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:12: error: member name `C` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x: N.C); +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2(x: N.C); + +// --- fail_alias.carbon + +library "[[@TEST_NAME]]"; + +class C; + +namespace N; +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `C` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.C = C; +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: alias N.C = C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +alias N.C = C; + +// --- fail_poison_multiple_scopes.carbon + +library "[[@TEST_NAME]]"; + +class C1; + +class C2 { + class C3 { + class C4 { + // Use `package.C1` and poison: + // * `C2.C1` + // * `C2.C3.C1` + // * `C2.C3.C4.C1` + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:15: error: name `C1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: C1); + // CHECK:STDERR: ^~ + fn F(x: C1); + + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:13: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: class C1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:15: error: name `C1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: C1); + // CHECK:STDERR: ^~ + class C1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: class C1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:15: error: name `C1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: C1); + // CHECK:STDERR: ^~ + class C1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: class C1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + class C1; +} + +// --- ignored_poison_in_import.carbon + +library "[[@TEST_NAME]]"; +import library "poison"; + +// This doesn't fail. +class N.C; + +// --- poison.impl.carbon + +impl library "[[@TEST_NAME]]"; + +// TODO: #4622 This should fail since `N.C` was poisoned in the api. +class N.C {} + +// --- fail_poison_when_lookup_fails.carbon + +library "[[@TEST_NAME]]"; + +namespace N; +// `package.C` and `N.C` poisoned when not found. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: error: name `C` not found [NameNotFound] +// CHECK:STDERR: fn N.F(x: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:11: error: name `C` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: C); +// CHECK:STDERR: ^ +fn N.F(x: C); + +// TODO: We should ideally only produce one diagnostic here. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:7: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: class C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:11: error: name `C` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: C); +// CHECK:STDERR: ^ +class C; +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: class N.C; +// CHECK:STDERR: ^ +// CHECK:STDERR: +class N.C; + +// --- fail_poison_with_lexical_result.carbon + +library "[[@TEST_NAME]]"; + +fn F() { + class C1 {} + + class C2 { + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:12: error: name `C1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: var v: C1; + // CHECK:STDERR: ^~ + var v: C1; + + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:11: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: class C1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + class C1; + } +} + +// --- fail_declare_data_member_after_poison.carbon + +library "[[@TEST_NAME]]"; + +class C1; + +class C2 { + // Use `package.C1` and poison `C2.C1`. + // CHECK:STDERR: fail_declare_data_member_after_poison.carbon:[[@LINE+3]]:11: error: name `C1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: C1); + // CHECK:STDERR: ^~ + fn F(x: C1); + + class C2 {} + // Failure: `C2.C1` declared after it was poisoned. + // CHECK:STDERR: fail_declare_data_member_after_poison.carbon:[[@LINE+4]]:7: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: var C1: C2; + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: + var C1: C2; +} + // --- fail_extend_poison_class_members.carbon library "[[@TEST_NAME]]"; @@ -28,3 +263,599 @@ class C { // CHECK:STDERR: fn B(); } + +// CHECK:STDOUT: --- no_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] +// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .TestCall = %TestCall.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc8 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc8: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] +// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { +// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 +// CHECK:STDOUT: %.loc11: type = splice_block %C.ref [concrete = constants.%C.9f4] { +// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.2 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.9f4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %C.9f4); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @TestCall(%x.param_patt: %C.9f4) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: %C.9f4 = name_ref x, %x +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%x.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %C = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C = value_param runtime_param0 +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %x: %C = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declare_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] +// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc18: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %C.f79); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %return.patt: %C = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %C = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %return.param: ref %C = out_param runtime_param0 +// CHECK:STDOUT: %return: ref %C = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] +// CHECK:STDOUT: %return.param: ref = out_param runtime_param0 +// CHECK:STDOUT: %return: ref = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F1() -> %C; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F2() -> ; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] +// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc18: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %x.patt: = binding_pattern x +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param0 +// CHECK:STDOUT: %.1: = splice_block [concrete = ] { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F1(%x.param_patt: %C.f79); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F2(%x.param_patt: ); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] +// CHECK:STDOUT: %C: type = bind_alias C, %C.decl [concrete = constants.%C] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C1.26b: type = class_type @C1.1 [concrete] +// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] +// CHECK:STDOUT: %C3: type = class_type @C3 [concrete] +// CHECK:STDOUT: %C4: type = class_type @C4 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C1.d8b: type = class_type @C1.2 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C1.a31: type = class_type @C1.3 [concrete] +// CHECK:STDOUT: %C1.f31: type = class_type @C1.4 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C1 = %C1.decl +// CHECK:STDOUT: .C2 = %C2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.1 [concrete = constants.%C1.26b] {} {} +// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C2 { +// CHECK:STDOUT: %C3.decl: type = class_decl @C3 [concrete = constants.%C3] {} {} +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.4 [concrete = constants.%C1.f31] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C2 +// CHECK:STDOUT: .C3 = %C3.decl +// CHECK:STDOUT: .C1 = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C3 { +// CHECK:STDOUT: %C4.decl: type = class_decl @C4 [concrete = constants.%C4] {} {} +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.3 [concrete = constants.%C1.a31] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C3 +// CHECK:STDOUT: .C4 = %C4.decl +// CHECK:STDOUT: .C1 = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C4 { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %C1.26b = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C1.26b = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C1.26b = value_param runtime_param0 +// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1.26b] +// CHECK:STDOUT: %x: %C1.26b = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.2 [concrete = constants.%C1.d8b] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C4 +// CHECK:STDOUT: .C1 = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.2; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.3; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.4; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %C1.26b); +// CHECK:STDOUT: +// CHECK:STDOUT: --- ignored_poison_in_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .C = file.%C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = imports.%Main.C +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C; +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .C = file.%C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = imports.%Main.C +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .C = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: = binding_pattern x +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param0 +// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] +// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl.loc23: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %C.decl.loc28: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: ); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C1.138: type = class_type @C1.1 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] +// CHECK:STDOUT: %C2.elem: type = unbound_element_type %C2, %C1.138 [concrete] +// CHECK:STDOUT: %C1.46c: type = class_type @C1.2 [concrete] +// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %C1.138} [concrete] +// CHECK:STDOUT: %complete_type.fb7: = complete_type_witness %struct_type.v [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.1 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C1.138 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C2 { +// CHECK:STDOUT: %.loc11_10: %C2.elem = field_decl v, element0 [concrete] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %.loc11_5: %C2.elem = var_pattern %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.var: ref %C2.elem = var +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.2 [concrete = constants.%C1.46c] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type.fb7] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C2 +// CHECK:STDOUT: .C1 = +// CHECK:STDOUT: .v = %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %C1.decl: type = class_decl @C1.1 [concrete = constants.%C1.138] {} {} +// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declare_data_member_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C1: type = class_type @C1 [concrete] +// CHECK:STDOUT: %C2.311: type = class_type @C2.1 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C2.0a0: type = class_type @C2.2 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C2.elem: type = unbound_element_type %C2.311, %C2.0a0 [concrete] +// CHECK:STDOUT: %struct_type.C1: type = struct_type {.C1: %C2.0a0} [concrete] +// CHECK:STDOUT: %complete_type.979: = complete_type_witness %struct_type.C1 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C1 = %C1.decl +// CHECK:STDOUT: .C2 = %C2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C1.decl: type = class_decl @C1 [concrete = constants.%C1] {} {} +// CHECK:STDOUT: %C2.decl: type = class_decl @C2.1 [concrete = constants.%C2.311] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C1; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C2.1 { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %C1 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C1 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C1 = value_param runtime_param0 +// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1] +// CHECK:STDOUT: %x: %C1 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C2.decl: type = class_decl @C2.2 [concrete = constants.%C2.0a0] {} {} +// CHECK:STDOUT: %.loc19_9: %C2.elem = field_decl C1, element0 [concrete] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %.loc19_3: %C2.elem = var_pattern %.loc19_9 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.var: ref %C2.elem = var +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.C1 [concrete = constants.%complete_type.979] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C2.311 +// CHECK:STDOUT: .C1 = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: .C2 = %C2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C2.2 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C2.0a0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %C1); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_extend_poison_class_members.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %B.fa3: type = class_type @B.2 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B.fa3 [concrete] +// CHECK:STDOUT: %B.type: type = fn_type @B.1 [concrete] +// CHECK:STDOUT: %B.489: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B.fa3} [concrete] +// CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: type = class_decl @B.2 [concrete = constants.%B.fa3] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @B.2 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%B.fa3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.fa3] +// CHECK:STDOUT: %.loc10: %C.elem = base_decl %B.ref, element0 [concrete] +// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B.1 [concrete = constants.%B.489] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .B = +// CHECK:STDOUT: .base = %.loc10 +// CHECK:STDOUT: extend %B.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.1(); +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon index 741b80f776d68..4962c6109d4e7 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon @@ -12,264 +12,149 @@ library "[[@TEST_NAME]]"; -class C {}; +class C1 {} +class C2 {} -// Both N.F1 and N.F2 use N.C and not C. -namespace N; -class N.C {} -fn N.F1(x: C); -fn N.F2(x: C) { N.F1(x); } - -// --- poison.carbon - -library "[[@TEST_NAME]]"; - -class C {}; +fn F1(x: C1); +// `N.F2` uses `N.F1` and not `package.F1`. namespace N; -// Here we use C and poison N.C. -fn N.F1(x: C); +fn N.F1(x: C2); +alias N.F2 = F1; -// --- fail_poison_class_without_usage.carbon - -library "[[@TEST_NAME]]"; - -class C {}; - -namespace N; -// Here we use C and poison N.C. -// CHECK:STDERR: fail_poison_class_without_usage.carbon:[[@LINE+3]]:12: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: C); -// CHECK:STDERR: ^ -fn N.F1(x: C); - -// Should fail here since C was poisoned for namespace N when it was used in N -// context without qualification. -// CHECK:STDERR: fail_poison_class_without_usage.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class N.C {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -class N.C {} +fn TestCall(x: C2) { + // `N.F2` accepts a `C2` not a `C1`. + N.F2(x); +} -// --- fail_poison_interface_without_usage.carbon +// --- poison.carbon library "[[@TEST_NAME]]"; -interface I {}; +fn F1(); +// Use `package.F1` and poison `N.F1`. namespace N; -// Here we use I and poison N.I. -// CHECK:STDERR: fail_poison_interface_without_usage.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: I); -// CHECK:STDERR: ^ -fn N.F1(x: I); - -// Should fail here since I was poisoned for namespace N when it was used in N -// context without qualification. -// CHECK:STDERR: fail_poison_interface_without_usage.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface N.I {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -interface N.I {} +alias N.F2 = F1; -// --- fail_poison_namespace_without_usage.carbon +// --- fail_declare_after_poison.carbon library "[[@TEST_NAME]]"; -class C {}; +fn F1(); namespace N; -// Here we use C and poison N.C. -// CHECK:STDERR: fail_poison_namespace_without_usage.carbon:[[@LINE+3]]:12: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: C); -// CHECK:STDERR: ^ -fn N.F1(x: C); - -// Should fail here since C was poisoned for namespace N when it was used in N -// context without qualification. -// CHECK:STDERR: fail_poison_namespace_without_usage.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: namespace N.C; -// CHECK:STDERR: ^ +// Use `package.F1` and poison `N.F1`. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:14: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.F2 = F1; +// CHECK:STDERR: ^~ +alias N.F2 = F1; + +// Failure: `N.F1` declared after it was poisoned. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:6: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -namespace N.C; - -// --- fail_poison_member_without_usage.carbon +fn N.F1(); -library "[[@TEST_NAME]]"; - -class C1 {}; - -class D { - // Here we use C1 and poison D.C1. - // CHECK:STDERR: fail_poison_member_without_usage.carbon:[[@LINE+3]]:12: error: name `C1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F1(x: C1); - // CHECK:STDERR: ^~ - fn F1(x: C1); - - class C2 {}; - // Should fail here since C1 was poisoned for namespace class D when it was - // used in D context without qualification. - // CHECK:STDERR: fail_poison_member_without_usage.carbon:[[@LINE+4]]:7: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: var C1: C2; - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: - var C1: C2; -} - -// --- fail_poison_function_without_usage.carbon +// --- fail_use_poison.carbon library "[[@TEST_NAME]]"; -class C {}; +fn F1(); +// Use `package.F1` and poison `N.F1`. namespace N; -// Here we use C and poison N.C. -// CHECK:STDERR: fail_poison_function_without_usage.carbon:[[@LINE+3]]:12: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: C); -// CHECK:STDERR: ^ -fn N.F1(x: C); +alias N.F2 = F1; -// Should fail here since C was poisoned for namespace N when it was used in N -// context without qualification. -// CHECK:STDERR: fail_poison_function_without_usage.carbon:[[@LINE+4]]:6: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: fn N.C(); -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:14: error: member name `F1` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: alias N.F3 = N.F1; +// CHECK:STDERR: ^~~~ // CHECK:STDERR: -fn N.C(); +alias N.F3 = N.F1; -// --- fail_use_undefined_poisoned_name.carbon +// --- fail_use_declaration_after_poison.carbon library "[[@TEST_NAME]]"; -class C {}; +fn F1(); namespace N; -// Here we use C and poison N.C. -fn N.F1() -> C; - -// Try to use N.C which was never defined and poisoned. -// CHECK:STDERR: fail_use_undefined_poisoned_name.carbon:[[@LINE+4]]:14: error: member name `C` not found in `N` [MemberNameNotFoundInScope] -// CHECK:STDERR: fn N.F2() -> N.C; -// CHECK:STDERR: ^~~ +// Use `package.F1` and poison `N.F1`. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:14: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.F2 = F1; +// CHECK:STDERR: ^~ +alias N.F2 = F1; + +// Failure: `N.F1` declared after it was poisoned. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:6: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -fn N.F2() -> N.C; +fn N.F1(); -// --- fail_poison_with_usage.carbon - -library "[[@TEST_NAME]]"; - -class C {}; - -namespace N; -// Here we use C and poison N.C. -// CHECK:STDERR: fail_poison_with_usage.carbon:[[@LINE+3]]:12: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: C); -// CHECK:STDERR: ^ -fn N.F1(x: C); - -// Should fail here since C was poisoned for namespace N when it was used in N -// context without qualification. -// CHECK:STDERR: fail_poison_with_usage.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class N.C {} -// CHECK:STDERR: ^ +// Failure: `N.F1` used after declaration failed. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:14: error: member name `F1` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: alias N.F3 = N.F1; +// CHECK:STDERR: ^~~~ // CHECK:STDERR: -class N.C {} - -// Should not fail here since both N.F2() and N.F1() input is the class C and -// not class N.C. -fn N.F2(x: C) { N.F1(x); } +alias N.F3 = N.F1; // --- fail_poison_multiple_scopes.carbon library "[[@TEST_NAME]]"; -class C {}; +fn F1(); namespace N1; namespace N1.N2; namespace N1.N2.N3; -class N1.N2.N3.D1 { - interface D2 { - class D3 { - // Here we use C and poison: - // * N1.C - // * N1.N2.C - // * N1.N2.N3.C - // * N1.N2.N3.D1.C - // * N1.N2.N3.D1.D2.C - // * N1.N2.N3.D1.D2.D3.C - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: C); - // CHECK:STDERR: ^ - fn F(x: C); - - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:13: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: class C {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: C); - // CHECK:STDERR: ^ - class C {} - } - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: class C {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: C); - // CHECK:STDERR: ^ - class C {} - } - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:9: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: class C {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-24]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: C); - // CHECK:STDERR: ^ - class C {} -} - -// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:10: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class N1.C {} -// CHECK:STDERR: ^ +// Use `package.F1` and poison: +// * `N1.F1` +// * `N1.N2.F1` +// * `N1.N2.N3.F1` +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:21: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N1.N2.N3.F2 = F1; +// CHECK:STDERR: ^~ +alias N1.N2.N3.F2 = F1; + +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:7: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N1.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-34]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn F(x: C); -// CHECK:STDERR: ^ -class N1.C {} - -// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface N1.N2.C {} -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:21: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N1.N2.N3.F2 = F1; +// CHECK:STDERR: ^~ +fn N1.F1(); +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:10: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N1.N2.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-43]]:15: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn F(x: C); -// CHECK:STDERR: ^ -interface N1.N2.C {} - -// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:16: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class N1.N2.N3.C {} -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-14]]:21: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N1.N2.N3.F2 = F1; +// CHECK:STDERR: ^~ +fn N1.N2.F1(); +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N1.N2.N3.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -class N1.N2.N3.C {} +fn N1.N2.N3.F1(); // --- fail_alias.carbon library "[[@TEST_NAME]]"; -class C {} +fn F(); namespace N; -// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: alias N.C = C; +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `F` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.F = F; // CHECK:STDERR: ^ // CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: alias N.C = C; +// CHECK:STDERR: alias N.F = F; // CHECK:STDERR: ^ // CHECK:STDERR: -alias N.C = C; +alias N.F = F; // --- ignored_poison_in_import.carbon @@ -277,1019 +162,462 @@ library "[[@TEST_NAME]]"; import library "poison"; // This doesn't fail. -class N.C {} +fn N.F1(); // --- poison.impl.carbon impl library "[[@TEST_NAME]]"; -// TODO: This should fail since N.C was poisoned in the api. -class N.C {} - -// --- using_poisoned_name_in_impl.carbon - -library "[[@TEST_NAME]]"; - -interface C {}; - -namespace N; -// Here we use C and poison N.C. -fn N.F1(x: C); - -class N.X { - extend impl as C { - } -} +// TODO: #4622 This should fail since `N.F1` was poisoned in the api. +fn N.F1() {} // --- fail_poison_when_lookup_fails.carbon library "[[@TEST_NAME]]"; namespace N; -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: error: name `C` not found [NameNotFound] -// CHECK:STDERR: fn N.F(x: C); -// CHECK:STDERR: ^ +// `N.F1` poisoned when not found. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:14: error: name `F1` not found [NameNotFound] +// CHECK:STDERR: alias N.F2 = F1; +// CHECK:STDERR: ^~ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:11: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x: C); -// CHECK:STDERR: ^ -fn N.F(x: C); +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:14: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.F2 = F1; +// CHECK:STDERR: ^~ +alias N.F2 = F1; // TODO: We should ideally only produce one diagnostic here. -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:7: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class C {} -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:4: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:11: error: name `C` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x: C); -// CHECK:STDERR: ^ -class C {} -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class N.C {} -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:14: error: name `F1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.F2 = F1; +// CHECK:STDERR: ^~ +fn F1(); +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:6: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: fn N.F1(); +// CHECK:STDERR: ^~ // CHECK:STDERR: -class N.C {} +fn N.F1(); // --- fail_poison_with_lexical_result.carbon library "[[@TEST_NAME]]"; -fn F() { - class A {} +fn F1() { + fn F2(); - class B { - // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:12: error: name `A` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: var v: A; - // CHECK:STDERR: ^ - var v: A; + class C { + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:16: error: name `F2` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: alias F3 = F2; + // CHECK:STDERR: ^~ + alias F3 = F2; - // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:11: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: class A {} - // CHECK:STDERR: ^ + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:8: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: fn F2(); + // CHECK:STDERR: ^~ // CHECK:STDERR: - class A {} + fn F2(); } } // CHECK:STDOUT: --- no_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %C1: type = class_type @C1 [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] +// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] +// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] +// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .C1 = %C1.decl +// CHECK:STDOUT: .C2 = %C2.decl +// CHECK:STDOUT: .F1 = %F1.decl.loc7 // CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .TestCall = %TestCall.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C1.decl: type = class_decl @C1 [concrete = constants.%C1] {} {} +// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} +// CHECK:STDOUT: %F1.decl.loc7: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] { +// CHECK:STDOUT: %x.patt: %C1 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C1 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %C1 = value_param runtime_param0 +// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1] +// CHECK:STDOUT: %x: %C1 = bind_name x, %x.param // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc8 -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: .N = +// CHECK:STDOUT: .C2 = +// CHECK:STDOUT: .F1 = %F1.decl.loc11 +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc8: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %F1.decl.loc11: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] { +// CHECK:STDOUT: %x.patt: %C2 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C2 = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] -// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.param: %C2 = value_param runtime_param0 +// CHECK:STDOUT: %C2.ref: type = name_ref C2, file.%C2.decl [concrete = constants.%C2] +// CHECK:STDOUT: %x: %C2 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.ref: %F1.type.fe6 = name_ref F1, %F1.decl.loc11 [concrete = constants.%F1.cc1] +// CHECK:STDOUT: %F2: %F1.type.fe6 = bind_alias F2, %F1.decl.loc11 [concrete = constants.%F1.cc1] +// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { +// CHECK:STDOUT: %x.patt: %C2 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %C2 = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] -// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %C2 = value_param runtime_param0 +// CHECK:STDOUT: %C2.ref: type = name_ref C2, file.%C2.decl [concrete = constants.%C2] +// CHECK:STDOUT: %x: %C2 = bind_name x, %x.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { +// CHECK:STDOUT: class @C1 { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 +// CHECK:STDOUT: .Self = constants.%C1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { +// CHECK:STDOUT: class @C2 { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.9f4 +// CHECK:STDOUT: .Self = constants.%C2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.9f4); +// CHECK:STDOUT: fn @F1.1(%x.param_patt: %C1); // CHECK:STDOUT: -// CHECK:STDOUT: fn @F2(%x.param_patt: %C.9f4) { +// CHECK:STDOUT: fn @F1.2(%x.param_patt: %C2); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @TestCall(%x.param_patt: %C2) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F1.ref: %F1.type = name_ref F1, file.%F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: %x.ref: %C.9f4 = name_ref x, %x -// CHECK:STDOUT: %F1.call: init %empty_tuple.type = call %F1.ref(%x.ref) +// CHECK:STDOUT: %F2.ref: %F1.type.fe6 = name_ref F2, file.%F2 [concrete = constants.%F1.cc1] +// CHECK:STDOUT: %x.ref: %C2 = name_ref x, %x +// CHECK:STDOUT: %F1.call: init %empty_tuple.type = call %F2.ref(%x.ref) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] // CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = // CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %x: %C = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_class_without_usage.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc19: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.9f4 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.f79); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_interface_without_usage.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %Self.826: %I.type.733 = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %Self.f85: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 // CHECK:STDOUT: .N = %N // CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %I.type.733 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param0 -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %x: %I.type.733 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc19: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1 { -// CHECK:STDOUT: %Self: %I.type.733 = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2 { -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self.f85] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () +// CHECK:STDOUT: %F1.ref: %F1.type = name_ref F1, %F1.decl [concrete = constants.%F1] +// CHECK:STDOUT: %F2: %F1.type = bind_alias F2, %F1.decl [concrete = constants.%F1] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %I.type.733); +// CHECK:STDOUT: fn @F1(); // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_namespace_without_usage.carbon +// CHECK:STDOUT: --- fail_declare_after_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] +// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .F1 = %F1.decl.loc4 // CHECK:STDOUT: .N = %N // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %x: %C = bind_name x, %x.param +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: } -// CHECK:STDOUT: %C: = namespace [concrete] {} +// CHECK:STDOUT: %F1.ref: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F1.decl.loc18: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F1.1(); // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C); +// CHECK:STDOUT: fn @F1.2(); // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_member_without_usage.carbon +// CHECK:STDOUT: --- fail_use_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C1: type = class_type @C1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] // CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] -// CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %C2 [concrete] -// CHECK:STDOUT: %struct_type.C1: type = struct_type {.C1: %C2} [concrete] -// CHECK:STDOUT: %complete_type.ec1: = complete_type_witness %struct_type.C1 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C1 = %C1.decl -// CHECK:STDOUT: .D = %D.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C1.decl: type = class_decl @C1 [concrete = constants.%C1] {} {} -// CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C1 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @D { -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C1 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C1 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C1 = value_param runtime_param0 -// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1] -// CHECK:STDOUT: %x: %C1 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} -// CHECK:STDOUT: %.loc20_9: %D.elem = field_decl C1, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc20_3: %D.elem = var_pattern %.loc20_9 -// CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %D.elem = var -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.C1 [concrete = constants.%complete_type.ec1] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%D -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .C2 = %C2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C1); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_function_without_usage.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C.type: type = fn_type @C.1 [concrete] -// CHECK:STDOUT: %C.3f2: %C.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.2 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = // CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc19: %C.type = fn_decl @C.1 [concrete = constants.%C.3f2] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.f79); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @C.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_undefined_poisoned_name.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl // CHECK:STDOUT: .N = %N // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: .F3 = %F3 // CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %return.patt: %C = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %C = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %return.param: ref %C = out_param runtime_param0 -// CHECK:STDOUT: %return: ref %C = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %return.patt: = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] -// CHECK:STDOUT: %return.param: ref = out_param runtime_param0 -// CHECK:STDOUT: %return: ref = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: %F1.ref.loc8: %F1.type = name_ref F1, %F1.decl [concrete = constants.%F1] +// CHECK:STDOUT: %F2: %F1.type = bind_alias F2, %F1.decl [concrete = constants.%F1] +// CHECK:STDOUT: %N.ref: = name_ref N, %N [concrete = %N] +// CHECK:STDOUT: %F1.ref.loc14: = name_ref F1, [concrete = ] +// CHECK:STDOUT: %F3: = bind_alias F3, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1() -> %C; +// CHECK:STDOUT: fn @F1(); // CHECK:STDOUT: -// CHECK:STDOUT: fn @F2() -> ; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_with_usage.carbon +// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] +// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .F1 = %F1.decl.loc4 // CHECK:STDOUT: .N = %N // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: .N = +// CHECK:STDOUT: .F3 = %F3 // CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc19: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.ref.loc11: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F1.decl.loc18: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} +// CHECK:STDOUT: %N.ref: = name_ref N, %N [concrete = %N] +// CHECK:STDOUT: %F1.ref.loc25: = name_ref F1, [concrete = ] +// CHECK:STDOUT: %F3: = bind_alias F3, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: fn @F1.1(); // CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.9f4 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.f79); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F2(%x.param_patt: %C.f79) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F1.ref: %F1.type = name_ref F1, file.%F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: %x.ref: %C.f79 = name_ref x, %x -// CHECK:STDOUT: %F1.call: init %empty_tuple.type = call %F1.ref(%x.ref) -// CHECK:STDOUT: return -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F1.2(); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %D1: type = class_type @D1 [concrete] -// CHECK:STDOUT: %D2.type: type = facet_type <@D2> [concrete] -// CHECK:STDOUT: %Self.8cf: %D2.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %D3.b65: type = class_type @D3 [concrete] -// CHECK:STDOUT: %D3.68e: type = class_type @D3, @D3(%Self.8cf) [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F, @D3(%Self.8cf) [symbolic] -// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] -// CHECK:STDOUT: %C.fef: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %C.5a3: type = class_type @C.2, @C.2(%Self.8cf) [symbolic] -// CHECK:STDOUT: %C.2fa: type = class_type @C.3 [concrete] -// CHECK:STDOUT: %C.4bd: type = class_type @C.3, @C.3(%Self.8cf) [symbolic] -// CHECK:STDOUT: %C.6f6: type = class_type @C.4 [concrete] -// CHECK:STDOUT: %C.0b8: type = class_type @C.5 [concrete] -// CHECK:STDOUT: %C.type: type = facet_type <@C.7> [concrete] -// CHECK:STDOUT: %Self.b2a: %C.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %C.6f1: type = class_type @C.6 [concrete] +// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] +// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.1f8: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.19a: %F1.type.1f8 = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.73a: type = fn_type @F1.3 [concrete] +// CHECK:STDOUT: %F1.727: %F1.type.73a = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.fe3: type = fn_type @F1.4 [concrete] +// CHECK:STDOUT: %F1.6a8: %F1.type.fe3 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 +// CHECK:STDOUT: .F1 = %F1.decl.loc4 // CHECK:STDOUT: .N1 = %N1 // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} +// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} // CHECK:STDOUT: %N1: = namespace [concrete] { // CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = // CHECK:STDOUT: } // CHECK:STDOUT: %N2: = namespace [concrete] { // CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = // CHECK:STDOUT: } // CHECK:STDOUT: %N3: = namespace [concrete] { -// CHECK:STDOUT: .D1 = %D1.decl -// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: } -// CHECK:STDOUT: %D1.decl: type = class_decl @D1 [concrete = constants.%D1] {} {} -// CHECK:STDOUT: %C.decl.loc59: type = class_decl @C.5 [concrete = constants.%C.0b8] {} {} -// CHECK:STDOUT: %C.decl.loc68: type = interface_decl @C.7 [concrete = constants.%C.type] {} {} -// CHECK:STDOUT: %C.decl.loc74: type = class_decl @C.6 [concrete = constants.%C.6f1] {} {} +// CHECK:STDOUT: %F1.ref: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] +// CHECK:STDOUT: %F1.decl.loc25: %F1.type.1f8 = fn_decl @F1.2 [concrete = constants.%F1.19a] {} {} +// CHECK:STDOUT: %F1.decl.loc33: %F1.type.73a = fn_decl @F1.3 [concrete = constants.%F1.727] {} {} +// CHECK:STDOUT: %F1.decl.loc38: %F1.type.fe3 = fn_decl @F1.4 [concrete = constants.%F1.6a8] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: interface @D2 { -// CHECK:STDOUT: %Self: %D2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.8cf] -// CHECK:STDOUT: %D3.decl: type = class_decl @D3 [concrete = constants.%D3.b65] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C.3 [concrete = constants.%C.2fa] {} {} +// CHECK:STDOUT: fn @F1.1(); // CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .D3 = %D3.decl -// CHECK:STDOUT: .C = -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F1.2(); // CHECK:STDOUT: -// CHECK:STDOUT: interface @C.7 { -// CHECK:STDOUT: %Self: %C.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.b2a] +// CHECK:STDOUT: fn @F1.3(); // CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @D1 { -// CHECK:STDOUT: %D2.decl: type = interface_decl @D2 [concrete = constants.%D2.type] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C.4 [concrete = constants.%C.6f6] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%D1 -// CHECK:STDOUT: .D2 = %D2.decl -// CHECK:STDOUT: .C = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic class @D3(@D2.%Self: %D2.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self: %D2.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.8cf)] -// CHECK:STDOUT: %F.type: type = fn_type @F, @D3(%Self) [symbolic = %F.type (constants.%F.type)] -// CHECK:STDOUT: %F: @D3.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] -// CHECK:STDOUT: -// CHECK:STDOUT: class { -// CHECK:STDOUT: %F.decl: @D3.%F.type (%F.type) = fn_decl @F [symbolic = @D3.%F (constants.%F)] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C.2 [concrete = constants.%C.fef] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%D3.68e -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic class @C.2(@D2.%Self: %D2.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: class { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.5a3 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic class @C.3(@D2.%Self: %D2.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: class { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.4bd -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.4 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.6f6 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.5 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.0b8 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.6 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.6f1 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(@D2.%Self: %D2.type) { -// CHECK:STDOUT: fn(%x.param_patt: %C.f79); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @D3(constants.%Self.8cf) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%Self.8cf) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @C.2(constants.%Self.8cf) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @D3(%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @C.3(constants.%Self.8cf) {} +// CHECK:STDOUT: fn @F1.4(); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_alias.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: .N = %N // CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = // CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] -// CHECK:STDOUT: %C: type = bind_alias C, %C.decl [concrete = constants.%C] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, %F.decl [concrete = constants.%F] +// CHECK:STDOUT: %F: %F.type = bind_alias F, %F.decl [concrete = constants.%F] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F(); // CHECK:STDOUT: // CHECK:STDOUT: --- ignored_poison_in_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded +// CHECK:STDOUT: %Main.F1 = import_ref Main//poison, F1, unloaded // CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded // CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F1 = %Main.F1 -// CHECK:STDOUT: .C = file.%C.decl +// CHECK:STDOUT: .F2 = %Main.F2 +// CHECK:STDOUT: .F1 = file.%F1.decl // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = imports.%Main.C +// CHECK:STDOUT: .F1 = imports.%Main.F1 // CHECK:STDOUT: .N = imports.%N // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F1(); // CHECK:STDOUT: // CHECK:STDOUT: --- poison.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded +// CHECK:STDOUT: %Main.F1 = import_ref Main//poison, F1, unloaded // CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded // CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F1 = %Main.F1 -// CHECK:STDOUT: .C = file.%C.decl +// CHECK:STDOUT: .F2 = %Main.F2 +// CHECK:STDOUT: .F1 = file.%F1.decl // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = imports.%Main.C +// CHECK:STDOUT: .F1 = imports.%Main.F1 // CHECK:STDOUT: .N = imports.%N // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_6.1 = import // CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- using_poisoned_name_in_impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.type: type = facet_type <@C> [concrete] -// CHECK:STDOUT: %Self: %C.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %X: type = class_type @X [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = interface_decl @C [concrete = constants.%C.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .X = %X.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.type = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.type = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.type = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C.type] -// CHECK:STDOUT: %x: %C.type = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %X.decl: type = class_decl @X [concrete = constants.%X] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @C { -// CHECK:STDOUT: %Self: %C.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %Self.ref as %C.ref { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = @X.%impl_witness -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @X { -// CHECK:STDOUT: impl_decl @impl [concrete] {} { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%X -// CHECK:STDOUT: .C = -// CHECK:STDOUT: extend @impl.%C.ref +// CHECK:STDOUT: fn @F1() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.type); -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] +// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] +// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] +// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { // CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F1 = // CHECK:STDOUT: } // CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: .F1 = +// CHECK:STDOUT: .F2 = %F2 // CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] -// CHECK:STDOUT: %x: = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc22: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %C.decl.loc27: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} +// CHECK:STDOUT: %F1.ref: = name_ref F1, [concrete = ] +// CHECK:STDOUT: %F2: = bind_alias F2, [concrete = ] +// CHECK:STDOUT: %F1.decl.loc23: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} +// CHECK:STDOUT: %F1.decl.loc28: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.f79 -// CHECK:STDOUT: } +// CHECK:STDOUT: fn @F1.1(); // CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.9f4 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: ); +// CHECK:STDOUT: fn @F1.2(); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %A.666: type = class_type @A.1 [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %F2.type.028: type = fn_type @F2.1 [concrete] +// CHECK:STDOUT: %F2.18a: %F2.type.028 = struct_value () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %F2.type.c9e: type = fn_type @F2.2 [concrete] +// CHECK:STDOUT: %F2.c1c: %F2.type.c9e = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %B: type = class_type @B [concrete] -// CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %A.666 [concrete] -// CHECK:STDOUT: %A.9b6: type = class_type @A.2 [concrete] -// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %A.666} [concrete] -// CHECK:STDOUT: %complete_type.57e: = complete_type_witness %struct_type.v [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @A.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%A.666 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @B { -// CHECK:STDOUT: %.loc11_10: %B.elem = field_decl v, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc11_5: %B.elem = var_pattern %.loc11_10 +// CHECK:STDOUT: .F1 = %F1.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %B.elem = var -// CHECK:STDOUT: %A.decl: type = class_decl @A.2 [concrete = constants.%A.9b6] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type.57e] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%B -// CHECK:STDOUT: .A = -// CHECK:STDOUT: .v = %.loc11_10 +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @A.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %F2.ref: %F2.type.028 = name_ref F2, @F1.%F2.decl [concrete = constants.%F2.18a] +// CHECK:STDOUT: %F3: %F2.type.028 = bind_alias F3, @F1.%F2.decl [concrete = constants.%F2.18a] +// CHECK:STDOUT: %F2.decl: %F2.type.c9e = fn_decl @F2.2 [concrete = constants.%F2.c1c] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%A.9b6 +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .F2 = +// CHECK:STDOUT: .F3 = %F3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F1() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %A.decl: type = class_decl @A.1 [concrete = constants.%A.666] {} {} -// CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: %F2.decl: %F2.type.028 = fn_decl @F2.1 [concrete = constants.%F2.18a] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @F2.1(); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F2.2(); +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon new file mode 100644 index 0000000000000..8ea9a10e3f600 --- /dev/null +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -0,0 +1,871 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon + +// --- no_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +// `N.F` uses `N.I` and not `package.I`. +namespace N; +interface N.I {} +fn N.F(x: I*); + +fn TestCall(x: N.I*) { + // `N.F` accepts an `N.I*` not a `package.I*`. + N.F(x); +} + +// --- poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +fn N.F(x: I*); + +// --- fail_declare_after_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: I*); +// CHECK:STDERR: ^ +fn N.F(x: I*); + +// Failure: N.I declared after it was poisoned. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I {} +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I {} + +// --- fail_use_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +fn N.F1(x: I*); + +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:12: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x: N.I*); +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2(x: N.I*); + +// --- fail_use_declaration_after_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F1(x: I*); +// CHECK:STDERR: ^ +fn N.F1(x: I*); + +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I; + +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:12: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x: N.I*); +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2(x: N.I*); + +// --- fail_alias.carbon + +library "[[@TEST_NAME]]"; + +interface I; +namespace N; + +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.I = I; +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: alias N.I = I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +alias N.I = I; + +// --- fail_poison_multiple_scopes.carbon + +library "[[@TEST_NAME]]"; + +interface I1; + +interface I2 { + interface I3 { + interface I4 { + // Use `package.I1` and poison: + // * `I2.I1` + // * `I2.I3.I1` + // * `I2.I3.I4.I1` + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: I1*); + // CHECK:STDERR: ^~ + fn F(x: I1*); + + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: I1*); + // CHECK:STDERR: ^~ + interface I1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:15: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x: I1*); + // CHECK:STDERR: ^~ + interface I1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + interface I1; +} + +// --- ignored_poison_in_import.carbon + +library "[[@TEST_NAME]]"; +import library "poison"; + +// This doesn't fail. +interface N.I; + +// --- poison.impl.carbon + +impl library "[[@TEST_NAME]]"; + +// TODO: #4622 This should fail since `N.I` was poisoned in the api. +interface N.I; + +// --- fail_poison_when_lookup_fails.carbon + +library "[[@TEST_NAME]]"; + +namespace N; +// `package.I` and `N.I` poisoned when not found. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: error: name `I` not found [NameNotFound] +// CHECK:STDERR: fn N.F(x: I*); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: I*); +// CHECK:STDERR: ^ +fn N.F(x: I*); + +// TODO: We should ideally only produce one diagnostic here. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x: I*); +// CHECK:STDERR: ^ +interface I; +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I; + +// --- fail_poison_with_lexical_result.carbon + +library "[[@TEST_NAME]]"; + +fn F() { + interface I1 {} + + class C { + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:12: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: var v: I1; + // CHECK:STDERR: ^~ + var v: I1; + + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:15: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + interface I1; + } +} + +// --- using_poisoned_name_in_impl.carbon + +library "[[@TEST_NAME]]"; + +interface I {}; + +namespace N; +// Use `package.I` and poison `N.I`. +fn N.F1(x: I*); + +class N.C { + extend impl as I { + } +} + +// CHECK:STDOUT: --- no_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] +// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .TestCall = %TestCall.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc8 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc8: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc9: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2 { +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @TestCall(%x.param_patt: %ptr) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: %ptr = name_ref x, %x +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%x.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declare_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc18: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2 { +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %x.patt: = binding_pattern x +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param0 +// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F2(%x.param_patt: ); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %x.patt: = binding_pattern x +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param0 +// CHECK:STDOUT: %.loc23: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F2(%x.param_patt: ); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.ref: type = name_ref I, %I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %I: type = bind_alias I, %I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I1.type.80c: type = facet_type <@I1.1> [concrete] +// CHECK:STDOUT: %I2.type: type = facet_type <@I2> [concrete] +// CHECK:STDOUT: %Self.c7b: %I2.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %I3.type.07a: type = facet_type <@I3> [concrete] +// CHECK:STDOUT: %I3.type.b2f: type = facet_type <@I3, @I3(%Self.c7b)> [symbolic] +// CHECK:STDOUT: %Self.60c: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %I4.type.451: type = facet_type <@I4> [concrete] +// CHECK:STDOUT: %I4.type.78e: type = facet_type <@I4, @I4(%Self.c7b, %Self.60c)> [symbolic] +// CHECK:STDOUT: %Self.a4d: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic] +// CHECK:STDOUT: %ptr: type = ptr_type %I1.type.80c [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.c7b, %Self.60c) [symbolic] +// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] +// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type %I4.type.78e [symbolic] +// CHECK:STDOUT: %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%F.decl [symbolic] +// CHECK:STDOUT: %I1.type.f4e: type = facet_type <@I1.2> [concrete] +// CHECK:STDOUT: %I1.type.575: type = facet_type <@I1.3> [concrete] +// CHECK:STDOUT: %I1.type.e5b: type = facet_type <@I1.4> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I1 = %I1.decl +// CHECK:STDOUT: .I2 = %I2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.80c] {} {} +// CHECK:STDOUT: %I2.decl: type = interface_decl @I2 [concrete = constants.%I2.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I2 { +// CHECK:STDOUT: %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.c7b] +// CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [concrete = constants.%I3.type.07a] {} {} +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.4 [concrete = constants.%I1.type.e5b] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .I3 = %I3.decl +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I3(@I2.%Self: %I2.type) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] +// CHECK:STDOUT: %I3.type: type = facet_type <@I3, @I3(%Self.2)> [symbolic = %I3.type (constants.%I3.type.b2f)] +// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I3.%I3.type (%I3.type.b2f) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [concrete = constants.%I4.type.451] {} {} +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.3 [concrete = constants.%I1.type.575] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .I4 = %I4.decl +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I4(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] +// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: %I4.type: type = facet_type <@I4, @I4(%Self.2, %Self.3)> [symbolic = %I4.type (constants.%I4.type.78e)] +// CHECK:STDOUT: %Self.4: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] +// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.2, %Self.3) [symbolic = %F.type (constants.%F.type)] +// CHECK:STDOUT: %F: @I4.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type @I4.%I4.type (%I4.type.78e) [symbolic = %I4.assoc_type (constants.%I4.assoc_type)] +// CHECK:STDOUT: %assoc0.loc16_19.2: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I4.%I4.type (%I4.type.78e) = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] +// CHECK:STDOUT: %F.decl: @I4.%F.type (%F.type) = fn_decl @F [symbolic = @I4.%F (constants.%F)] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] +// CHECK:STDOUT: %ptr: type = ptr_type %I1.type.80c [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc16_19.1: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.f4e] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: .F = %assoc0.loc16_19.1 +// CHECK:STDOUT: witness = (%F.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.2(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.3(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.4(@I2.%Self: %I2.type) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { +// CHECK:STDOUT: fn(%x.param_patt: %ptr); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I3(constants.%Self.c7b) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I4(constants.%Self.c7b, constants.%Self.60c) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.2(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I4(%Self.2, %Self.3) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.3(constants.%Self.c7b, constants.%Self.60c) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I3(%Self.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.4(constants.%Self.c7b) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- ignored_poison_in_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .I = file.%I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .I = file.%I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .I = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt: = binding_pattern x +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param0 +// CHECK:STDOUT: %.loc13: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc23: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %I.decl.loc28: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%x.param_patt: ); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I1.type.06a: type = facet_type <@I1.1> [concrete] +// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I1.type.06a [concrete] +// CHECK:STDOUT: %I1.type.8ea: type = facet_type <@I1.2> [concrete] +// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %I1.type.06a} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.1 { +// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.2; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %.loc11_10: %C.elem = field_decl v, element0 [concrete] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %.loc11_5: %C.elem = var_pattern %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.var: ref %C.elem = var +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.8ea] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: .v = %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.06a] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- using_poisoned_name_in_impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 +// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl: %Self.ref as %I.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = @C.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete = constants.%impl_witness] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .I = +// CHECK:STDOUT: extend @impl.%I.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon new file mode 100644 index 0000000000000..1effdc4470cd7 --- /dev/null +++ b/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon @@ -0,0 +1,458 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon + +// --- no_poison.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; + +// `N2.N3` uses `N2.N1` and not `package.N1`. +namespace N2; +namespace N2.N1; +alias N2.N3 = N1; + +class N2.N1.C {} +class N1.C {} +fn TestNamespaces() { + var x: N2.N1.C; + var y: N2.N3.C* = &x; +} + +// --- poison.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; + +// Use `package.N1` and poison `N2.N1`. +namespace N2; +alias N2.N3 = N1; + +// --- fail_declare_after_poison.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; + +// Use `package.N1` and poison `N2.N1`. +namespace N2; +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:15: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N3 = N1; +// CHECK:STDERR: ^~ +alias N2.N3 = N1; + +// Failure: N2.N1 declared after it was poisoned. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:14: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N2.N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +namespace N2.N1; + +// --- fail_use_poison.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; + +// Use `package.N1` and poison `N2.N1`. +namespace N2; +alias N2.N3 = N1; + +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:15: error: member name `N1` not found in `N2` [MemberNameNotFoundInScope] +// CHECK:STDERR: alias N2.N4 = N2.N1; +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +alias N2.N4 = N2.N1; + +// --- fail_use_declaration_after_poison.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; + +// Use `package.N1` and poison `N2.N1`. +namespace N2; +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:15: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N3 = N1; +// CHECK:STDERR: ^~ +alias N2.N3 = N1; + +// Failure: `N2.N1` declared after it was poisoned. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:14: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N2.N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +namespace N2.N1; + +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:15: error: member name `N1` not found in `N2` [MemberNameNotFoundInScope] +// CHECK:STDERR: alias N2.N4 = N2.N1; +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +alias N2.N4 = N2.N1; + +// --- fail_alias.carbon + +namespace N1; + +namespace N2; +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:15: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N1 = N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:10: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: alias N2.N1 = N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +alias N2.N1 = N1; + +// --- fail_poison_multiple_scopes.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; +namespace N2; +namespace N2.N3; +namespace N2.N3.N4; +// Use `package.N1` and poison: +// * `N2.N1` +// * `N2.N3.N1` +// * `N2.N3.N4.N1` +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:21: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N3.N4.N5 = N1; +// CHECK:STDERR: ^~ +alias N2.N3.N4.N5 = N1; + +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:20: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N2.N3.N4.N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:21: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N3.N4.N5 = N1; +// CHECK:STDERR: ^~ +namespace N2.N3.N4.N1; +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N2.N3.N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-14]]:21: error: name `N1` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N2.N3.N4.N5 = N1; +// CHECK:STDERR: ^~ +namespace N2.N3.N1; +// CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:14: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N2.N1; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +namespace N2.N1; + +// --- ignored_poison_in_import.carbon + +library "[[@TEST_NAME]]"; +import library "poison"; + +// This doesn't fail. +namespace N2.N1; + +// --- poison.impl.carbon + +impl library "[[@TEST_NAME]]"; + +// TODO: #4622 This should fail since `N2.N1` was poisoned in the api. +namespace N2.N1; + +// --- fail_poison_when_lookup_fails.carbon + +library "[[@TEST_NAME]]"; + +namespace N1; +// `N1.N3` poisoned when not found. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:15: error: name `N3` not found [NameNotFound] +// CHECK:STDERR: alias N1.N2 = N3; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:15: error: name `N3` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N1.N2 = N3; +// CHECK:STDERR: ^~ +alias N1.N2 = N3; + +// TODO: We should ideally only produce one diagnostic here. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N3; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:15: error: name `N3` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N1.N2 = N3; +// CHECK:STDERR: ^~ +namespace N3; +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:14: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: namespace N1.N3; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +namespace N1.N3; + +// CHECK:STDOUT: --- no_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C.2a3: type = class_type @C.1 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C.0b8: type = class_type @C.2 [concrete] +// CHECK:STDOUT: %TestNamespaces.type: type = fn_type @TestNamespaces [concrete] +// CHECK:STDOUT: %TestNamespaces: %TestNamespaces.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.33b: type = ptr_type %C.2a3 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc4 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: .TestNamespaces = %TestNamespaces.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc4: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc12 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc8 +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc8: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl.loc11 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc8 [concrete = %N1.loc8] +// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc8 [concrete = %N1.loc8] +// CHECK:STDOUT: %C.decl.loc11: type = class_decl @C.1 [concrete = constants.%C.2a3] {} {} +// CHECK:STDOUT: %C.decl.loc12: type = class_decl @C.2 [concrete = constants.%C.0b8] {} {} +// CHECK:STDOUT: %TestNamespaces.decl: %TestNamespaces.type = fn_decl @TestNamespaces [concrete = constants.%TestNamespaces] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.1 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2a3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C.2 { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.0b8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @TestNamespaces() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %C.2a3 = binding_pattern x +// CHECK:STDOUT: %.loc14_3: %C.2a3 = var_pattern %x.patt +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.var: ref %C.2a3 = var x +// CHECK:STDOUT: %.loc14_15: type = splice_block %C.ref.loc14 [concrete = constants.%C.2a3] { +// CHECK:STDOUT: %N2.ref.loc14: = name_ref N2, file.%N2 [concrete = file.%N2] +// CHECK:STDOUT: %N1.ref: = name_ref N1, file.%N1.loc8 [concrete = file.%N1.loc8] +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, file.%C.decl.loc11 [concrete = constants.%C.2a3] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: ref %C.2a3 = bind_name x, %x.var +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %y.patt: %ptr.33b = binding_pattern y +// CHECK:STDOUT: %.loc15_3: %ptr.33b = var_pattern %y.patt +// CHECK:STDOUT: } +// CHECK:STDOUT: %y.var: ref %ptr.33b = var y +// CHECK:STDOUT: %x.ref: ref %C.2a3 = name_ref x, %x +// CHECK:STDOUT: %addr: %ptr.33b = addr_of %x.ref +// CHECK:STDOUT: assign %y.var, %addr +// CHECK:STDOUT: %.loc15_17: type = splice_block %ptr [concrete = constants.%ptr.33b] { +// CHECK:STDOUT: %N2.ref.loc15: = name_ref N2, file.%N2 [concrete = file.%N2] +// CHECK:STDOUT: %N3.ref: = name_ref N3, file.%N3 [concrete = file.%N1.loc8] +// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, file.%C.decl.loc11 [concrete = constants.%C.2a3] +// CHECK:STDOUT: %ptr: type = ptr_type %C.2a3 [concrete = constants.%ptr.33b] +// CHECK:STDOUT: } +// CHECK:STDOUT: %y: ref %ptr.33b = bind_name y, %y.var +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1 [concrete = %N1] +// CHECK:STDOUT: %N3: = bind_alias N3, %N1 [concrete = %N1] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declare_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc4 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N1.loc18: = namespace [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: .N2 = +// CHECK:STDOUT: .N4 = %N4 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref.loc8: = name_ref N1, %N1 [concrete = %N1] +// CHECK:STDOUT: %N3: = bind_alias N3, %N1 [concrete = %N1] +// CHECK:STDOUT: %N2.ref: = name_ref N2, %N2 [concrete = %N2] +// CHECK:STDOUT: %N1.ref.loc14: = name_ref N1, [concrete = ] +// CHECK:STDOUT: %N4: = bind_alias N4, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc4 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: .N2 = +// CHECK:STDOUT: .N4 = %N4 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref.loc11: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N1.loc18: = namespace [concrete] {} +// CHECK:STDOUT: %N2.ref: = name_ref N2, %N2 [concrete = %N2] +// CHECK:STDOUT: %N1.ref.loc24: = name_ref N1, [concrete = ] +// CHECK:STDOUT: %N4: = bind_alias N4, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc2 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc2: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc2 [concrete = %N1.loc2] +// CHECK:STDOUT: %N1.loc12: = bind_alias N1, %N1.loc2 [concrete = %N1.loc2] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1.loc4 +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} +// CHECK:STDOUT: %N2: = namespace [concrete] { +// CHECK:STDOUT: .N3 = %N3 +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N3: = namespace [concrete] { +// CHECK:STDOUT: .N4 = %N4 +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N4: = namespace [concrete] { +// CHECK:STDOUT: .N1 = +// CHECK:STDOUT: .N5 = %N5 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N5: = bind_alias N5, %N1.loc4 [concrete = %N1.loc4] +// CHECK:STDOUT: %N1.loc24: = namespace [concrete] {} +// CHECK:STDOUT: %N1.loc32: = namespace [concrete] {} +// CHECK:STDOUT: %N1.loc37: = namespace [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- ignored_poison_in_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.N1: = import_ref Main//poison, N1, loaded +// CHECK:STDOUT: %N1: = namespace %Main.N1, [concrete] {} +// CHECK:STDOUT: %Main.N2: = import_ref Main//poison, N2, loaded +// CHECK:STDOUT: %N2: = namespace %Main.N2, [concrete] { +// CHECK:STDOUT: .N3 = %Main.N3 +// CHECK:STDOUT: .N1 = file.%N1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = imports.%N1 +// CHECK:STDOUT: .N2 = imports.%N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %N1: = namespace [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.N2: = import_ref Main//poison, N2, loaded +// CHECK:STDOUT: %N2: = namespace %Main.N2, [concrete] { +// CHECK:STDOUT: .N3 = %Main.N3 +// CHECK:STDOUT: .N1 = file.%N1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Main.N1: = import_ref Main//poison, N1, loaded +// CHECK:STDOUT: %N1: = namespace %Main.N1, [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N2 = imports.%N2 +// CHECK:STDOUT: .N1 = imports.%N1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %N1: = namespace [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N1 = %N1 +// CHECK:STDOUT: .N3 = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N1: = namespace [concrete] { +// CHECK:STDOUT: .N3 = +// CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %N3.ref: = name_ref N3, [concrete = ] +// CHECK:STDOUT: %N2: = bind_alias N2, [concrete = ] +// CHECK:STDOUT: %N3.loc23: = namespace [concrete] {} +// CHECK:STDOUT: %N3.loc28: = namespace [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: From 2ca3f921319efb3016fb3a28567d88b8f67a29dd Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 24 Feb 2025 16:53:48 -0500 Subject: [PATCH 13/56] Don't incorrectly find cycle in a generic impl (#4990) If the `impl as` clause is on a generic interface, the parameters to the generic may be constrained by _other_ interfaces. This then requires another impl lookup, but it should be looking for a different impl since it's for a different interface. To avoid considering the same impl again, we discard it from consideration if the interface itself does not match the interface being queried. Note that the query FacetType can have more than one interface in it eventually, and a `context.TODO()` call is left to notify when we run into this. --- toolchain/check/impl_lookup.cpp | 40 +- ...value_to_generic_facet_value_value.carbon} | 469 +++++++++--------- .../impl/no_prelude/impl_cycle.carbon | 22 +- .../testdata/where_expr/equal_rewrite.carbon | 10 +- toolchain/sem_ir/file.h | 1 + toolchain/sem_ir/typed_insts.h | 1 + 6 files changed, 268 insertions(+), 275 deletions(-) rename toolchain/check/testdata/builtin_conversions/no_prelude/{fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon => convert_facet_value_value_to_generic_facet_value_value.carbon} (57%) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 8ffea78038b2b..139a7396ea3f3 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -7,6 +7,7 @@ #include "toolchain/check/deduce.h" #include "toolchain/check/generic.h" #include "toolchain/check/import_ref.h" +#include "toolchain/check/type_completion.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/impl.h" #include "toolchain/sem_ir/inst.h" @@ -115,6 +116,7 @@ static auto FindAssociatedImportIRs(Context& context, static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, SemIR::ConstantId type_const_id, SemIR::ConstantId interface_const_id, + SemIR::InterfaceId interface_id, const SemIR::Impl& impl) -> SemIR::InstId { // If impl.constraint_id is not symbolic, and doesn't match the query, then // we don't need to proceed. @@ -125,9 +127,15 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, return SemIR::InstId::None; } - // TODO: If the interface id of the `impl` and the query are not the same, - // then we can skip this `impl`. (The interface id is the root of the - // constraint, the unique `interface` declaration.) + // This is the (single) interface named in the query `interface_const_id`. + // If the impl's interface_id differs from the query, then this impl can not + // possibly provide the queried interface, and we don't need to proceed. + // Unlike the early-out above comparing the `impl.constraint_id`, this also + // elides looking at impls of generic interfaces where the interface itself + // does not match the query. + if (impl.interface.interface_id != interface_id) { + return SemIR::InstId::None; + } auto specific_id = SemIR::SpecificId::None; // This check comes first to avoid deduction with an invalid impl. We use an @@ -218,6 +226,30 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, } } + // The `interface_id` is the single interface in the `interface_const_id` + // facet type. In the future, a facet type may include more than a single + // interface, but for now that is unhandled with a TODO. + auto interface_id = [&] { + auto facet_type_inst_id = + context.constant_values().GetInstId(interface_const_id); + auto facet_type_id = context.insts() + .GetAs(facet_type_inst_id) + .facet_type_id; + const auto& facet_type_info = context.facet_types().Get(facet_type_id); + if (facet_type_info.impls_constraints.empty()) { + context.TODO(loc_id, + "impl lookup for a FacetType with no interface (using " + "`where .Self impls ...` instead?)"); + return SemIR::InterfaceId::None; + } + if (facet_type_info.impls_constraints.size() > 1) { + context.TODO(loc_id, + "impl lookup for a FacetType with more than one interface"); + return SemIR::InterfaceId::None; + } + return facet_type_info.impls_constraints[0].interface_id; + }(); + auto witness_id = SemIR::InstId::None; stack.push_back({ @@ -226,7 +258,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, }); for (const auto& impl : context.impls().array_ref()) { witness_id = GetWitnessIdForImpl(context, loc_id, type_const_id, - interface_const_id, impl); + interface_const_id, interface_id, impl); if (witness_id.has_value()) { // We found a matching impl, don't keep looking. break; diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon similarity index 57% rename from toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon rename to toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon index e862c5efcff3e..11df252a80d8f 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon @@ -4,9 +4,9 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon // --- core.carbon @@ -16,7 +16,7 @@ interface ImplicitAs(T:! type) { fn Convert[self: Self]() -> T; } -// --- fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +// --- convert_facet_value_value_to_generic_facet_value_value.carbon library "[[@TEST_NAME]]"; @@ -30,10 +30,9 @@ impl Grass as Edible {} interface Animal {} interface Eats(Food:! type) {} -// This impl is looked at for "does Goat impl Animal" first, which requires a -// recursive query in deduction that is the same "does Goat impl Animal", which -// can land us back looking at this impl again. So we require a way to eliminate -// this impl without doing deduction in order to avoid the cycle. +// When answering a query "does Goat impl Animal", we must avoid trying to deduce +// parameters for this impl. Not only is doing so unnecessary, it would start a new +// "does Goat impl Animal" query, leading to a "cycle in impl lookup" error. impl forall [T:! Animal, U:! Edible] T as Eats(U) {} class Goat {} @@ -43,26 +42,6 @@ fn Feed[Food:! Edible, T:! Eats(Food)](e: T, food: Food) {} fn HandleAnimal[T:! Animal, Food:! Edible](a: T, food: Food) { Feed(a, food); } fn F() { - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE+20]]:3: error: cycle found in lookup of interface for type `Goat` [ImplLookupCycle] - // CHECK:STDERR: HandleAnimal({} as Goat, {} as Grass); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE-12]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: impl forall [T:! Animal, U:! Edible] T as Eats(U) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE-9]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: fn HandleAnimal[T:! Animal, Food:! Edible](a: T, food: Food) { Feed(a, food); } - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE+10]]:3: error: cycle found in lookup of interface for type `Goat` [ImplLookupCycle] - // CHECK:STDERR: HandleAnimal({} as Goat, {} as Grass); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE-22]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: impl forall [T:! Animal, U:! Edible] T as Eats(U) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon:[[@LINE-19]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: fn HandleAnimal[T:! Animal, Food:! Edible](a: T, food: Food) { Feed(a, food); } - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: HandleAnimal({} as Goat, {} as Grass); } @@ -162,7 +141,7 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: specific @ImplicitAs(%T.loc4_22.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_convert_facet_value_value_to_generic_facet_value_value.carbon +// CHECK:STDOUT: --- convert_facet_value_value_to_generic_facet_value_value.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Edible.type: type = facet_type <@Edible> [concrete] @@ -262,100 +241,100 @@ fn F() { // CHECK:STDOUT: %Food.loc12_16.1: type = bind_symbolic_name Food, 0, %Food.param [symbolic = %Food.loc12_16.2 (constants.%Food.8b3)] // CHECK:STDOUT: } // CHECK:STDOUT: impl_decl @impl.2 [concrete] { -// CHECK:STDOUT: %T.patt.loc18_14.1: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc18_14.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %T.param_patt: %Animal.type = value_param_pattern %T.patt.loc18_14.1, runtime_param [symbolic = %T.patt.loc18_14.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %U.patt.loc18_26.1: %Edible.type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc18_26.2 (constants.%U.patt)] -// CHECK:STDOUT: %U.param_patt: %Edible.type = value_param_pattern %U.patt.loc18_26.1, runtime_param [symbolic = %U.patt.loc18_26.2 (constants.%U.patt)] +// CHECK:STDOUT: %T.patt.loc17_14.1: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %T.param_patt: %Animal.type = value_param_pattern %T.patt.loc17_14.1, runtime_param [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %U.patt.loc17_26.1: %Edible.type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_26.2 (constants.%U.patt)] +// CHECK:STDOUT: %U.param_patt: %Edible.type = value_param_pattern %U.patt.loc17_26.1, runtime_param [symbolic = %U.patt.loc17_26.2 (constants.%U.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %T.ref: %Animal.type = name_ref T, %T.loc18_14.1 [symbolic = %T.loc18_14.2 (constants.%T.fd4)] -// CHECK:STDOUT: %T.as_type.loc18_38.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc18_38.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %.loc18_38: type = converted %T.ref, %T.as_type.loc18_38.1 [symbolic = %T.as_type.loc18_38.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %T.ref: %Animal.type = name_ref T, %T.loc17_14.1 [symbolic = %T.loc17_14.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.as_type.loc17_38.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc17_38.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %.loc17_38: type = converted %T.ref, %T.as_type.loc17_38.1 [symbolic = %T.as_type.loc17_38.2 (constants.%T.as_type.2ad)] // CHECK:STDOUT: %Eats.ref: %Eats.type.ba2 = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.generic] -// CHECK:STDOUT: %U.ref: %Edible.type = name_ref U, %U.loc18_26.1 [symbolic = %U.loc18_26.2 (constants.%U)] -// CHECK:STDOUT: %U.as_type.loc18_49.1: type = facet_access_type %U.ref [symbolic = %U.as_type.loc18_49.2 (constants.%U.as_type)] -// CHECK:STDOUT: %.loc18_49: type = converted %U.ref, %U.as_type.loc18_49.1 [symbolic = %U.as_type.loc18_49.2 (constants.%U.as_type)] -// CHECK:STDOUT: %Eats.type.loc18_49.1: type = facet_type <@Eats, @Eats(constants.%U.as_type)> [symbolic = %Eats.type.loc18_49.2 (constants.%Eats.type.f54c3d.1)] +// CHECK:STDOUT: %U.ref: %Edible.type = name_ref U, %U.loc17_26.1 [symbolic = %U.loc17_26.2 (constants.%U)] +// CHECK:STDOUT: %U.as_type.loc17_49.1: type = facet_access_type %U.ref [symbolic = %U.as_type.loc17_49.2 (constants.%U.as_type)] +// CHECK:STDOUT: %.loc17_49: type = converted %U.ref, %U.as_type.loc17_49.1 [symbolic = %U.as_type.loc17_49.2 (constants.%U.as_type)] +// CHECK:STDOUT: %Eats.type.loc17_49.1: type = facet_type <@Eats, @Eats(constants.%U.as_type)> [symbolic = %Eats.type.loc17_49.2 (constants.%Eats.type.f54c3d.1)] // CHECK:STDOUT: %T.param: %Animal.type = value_param runtime_param // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] -// CHECK:STDOUT: %T.loc18_14.1: %Animal.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc18_14.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.loc17_14.1: %Animal.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc17_14.2 (constants.%T.fd4)] // CHECK:STDOUT: %U.param: %Edible.type = value_param runtime_param // CHECK:STDOUT: %Edible.ref: type = name_ref Edible, file.%Edible.decl [concrete = constants.%Edible.type] -// CHECK:STDOUT: %U.loc18_26.1: %Edible.type = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc18_26.2 (constants.%U)] +// CHECK:STDOUT: %U.loc17_26.1: %Edible.type = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc17_26.2 (constants.%U)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (), @impl.2(constants.%T.fd4, constants.%U) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.c7c36b.1)] +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (), @impl.2(constants.%T.fd4, constants.%U) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.c7c36b.1)] // CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} // CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc21: = impl_witness () [concrete = constants.%impl_witness.1bc] +// CHECK:STDOUT: %impl_witness.loc20: = impl_witness () [concrete = constants.%impl_witness.1bc] // CHECK:STDOUT: %Feed.decl: %Feed.type = fn_decl @Feed [concrete = constants.%Feed] { -// CHECK:STDOUT: %Food.patt.loc23_9.1: %Edible.type = symbolic_binding_pattern Food, 0 [symbolic = %Food.patt.loc23_9.2 (constants.%Food.patt.0b7)] -// CHECK:STDOUT: %Food.param_patt: %Edible.type = value_param_pattern %Food.patt.loc23_9.1, runtime_param [symbolic = %Food.patt.loc23_9.2 (constants.%Food.patt.0b7)] -// CHECK:STDOUT: %T.patt.loc23_24.1: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39) = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc23_24.2 (constants.%T.patt.f09)] -// CHECK:STDOUT: %T.param_patt: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39) = value_param_pattern %T.patt.loc23_24.1, runtime_param [symbolic = %T.patt.loc23_24.2 (constants.%T.patt.f09)] -// CHECK:STDOUT: %e.patt: @Feed.%T.as_type.loc23_43.2 (%T.as_type.212) = binding_pattern e -// CHECK:STDOUT: %e.param_patt: @Feed.%T.as_type.loc23_43.2 (%T.as_type.212) = value_param_pattern %e.patt, runtime_param0 -// CHECK:STDOUT: %food.patt: @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952) = binding_pattern food -// CHECK:STDOUT: %food.param_patt: @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952) = value_param_pattern %food.patt, runtime_param1 +// CHECK:STDOUT: %Food.patt.loc22_9.1: %Edible.type = symbolic_binding_pattern Food, 0 [symbolic = %Food.patt.loc22_9.2 (constants.%Food.patt.0b7)] +// CHECK:STDOUT: %Food.param_patt: %Edible.type = value_param_pattern %Food.patt.loc22_9.1, runtime_param [symbolic = %Food.patt.loc22_9.2 (constants.%Food.patt.0b7)] +// CHECK:STDOUT: %T.patt.loc22_24.1: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39) = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc22_24.2 (constants.%T.patt.f09)] +// CHECK:STDOUT: %T.param_patt: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39) = value_param_pattern %T.patt.loc22_24.1, runtime_param [symbolic = %T.patt.loc22_24.2 (constants.%T.patt.f09)] +// CHECK:STDOUT: %e.patt: @Feed.%T.as_type.loc22_43.2 (%T.as_type.212) = binding_pattern e +// CHECK:STDOUT: %e.param_patt: @Feed.%T.as_type.loc22_43.2 (%T.as_type.212) = value_param_pattern %e.patt, runtime_param0 +// CHECK:STDOUT: %food.patt: @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952) = binding_pattern food +// CHECK:STDOUT: %food.param_patt: @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952) = value_param_pattern %food.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %Food.param: %Edible.type = value_param runtime_param // CHECK:STDOUT: %Edible.ref: type = name_ref Edible, file.%Edible.decl [concrete = constants.%Edible.type] -// CHECK:STDOUT: %Food.loc23_9.1: %Edible.type = bind_symbolic_name Food, 0, %Food.param [symbolic = %Food.loc23_9.2 (constants.%Food.9af)] -// CHECK:STDOUT: %T.param: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39) = value_param runtime_param -// CHECK:STDOUT: %.loc23_37.1: type = splice_block %Eats.type.loc23_37.1 [symbolic = %Eats.type.loc23_37.2 (constants.%Eats.type.b39)] { +// CHECK:STDOUT: %Food.loc22_9.1: %Edible.type = bind_symbolic_name Food, 0, %Food.param [symbolic = %Food.loc22_9.2 (constants.%Food.9af)] +// CHECK:STDOUT: %T.param: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39) = value_param runtime_param +// CHECK:STDOUT: %.loc22_37.1: type = splice_block %Eats.type.loc22_37.1 [symbolic = %Eats.type.loc22_37.2 (constants.%Eats.type.b39)] { // CHECK:STDOUT: %Eats.ref: %Eats.type.ba2 = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.generic] -// CHECK:STDOUT: %Food.ref.loc23_33: %Edible.type = name_ref Food, %Food.loc23_9.1 [symbolic = %Food.loc23_9.2 (constants.%Food.9af)] -// CHECK:STDOUT: %Food.as_type.loc23_37.1: type = facet_access_type %Food.ref.loc23_33 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] -// CHECK:STDOUT: %.loc23_37.2: type = converted %Food.ref.loc23_33, %Food.as_type.loc23_37.1 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] -// CHECK:STDOUT: %Eats.type.loc23_37.1: type = facet_type <@Eats, @Eats(constants.%Food.as_type.952)> [symbolic = %Eats.type.loc23_37.2 (constants.%Eats.type.b39)] +// CHECK:STDOUT: %Food.ref.loc22_33: %Edible.type = name_ref Food, %Food.loc22_9.1 [symbolic = %Food.loc22_9.2 (constants.%Food.9af)] +// CHECK:STDOUT: %Food.as_type.loc22_37.1: type = facet_access_type %Food.ref.loc22_33 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] +// CHECK:STDOUT: %.loc22_37.2: type = converted %Food.ref.loc22_33, %Food.as_type.loc22_37.1 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] +// CHECK:STDOUT: %Eats.type.loc22_37.1: type = facet_type <@Eats, @Eats(constants.%Food.as_type.952)> [symbolic = %Eats.type.loc22_37.2 (constants.%Eats.type.b39)] // CHECK:STDOUT: } -// CHECK:STDOUT: %T.loc23_24.1: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39) = bind_symbolic_name T, 1, %T.param [symbolic = %T.loc23_24.2 (constants.%T.223)] -// CHECK:STDOUT: %e.param: @Feed.%T.as_type.loc23_43.2 (%T.as_type.212) = value_param runtime_param0 -// CHECK:STDOUT: %.loc23_43.1: type = splice_block %.loc23_43.2 [symbolic = %T.as_type.loc23_43.2 (constants.%T.as_type.212)] { -// CHECK:STDOUT: %T.ref: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39) = name_ref T, %T.loc23_24.1 [symbolic = %T.loc23_24.2 (constants.%T.223)] -// CHECK:STDOUT: %T.as_type.loc23_43.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc23_43.2 (constants.%T.as_type.212)] -// CHECK:STDOUT: %.loc23_43.2: type = converted %T.ref, %T.as_type.loc23_43.1 [symbolic = %T.as_type.loc23_43.2 (constants.%T.as_type.212)] +// CHECK:STDOUT: %T.loc22_24.1: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39) = bind_symbolic_name T, 1, %T.param [symbolic = %T.loc22_24.2 (constants.%T.223)] +// CHECK:STDOUT: %e.param: @Feed.%T.as_type.loc22_43.2 (%T.as_type.212) = value_param runtime_param0 +// CHECK:STDOUT: %.loc22_43.1: type = splice_block %.loc22_43.2 [symbolic = %T.as_type.loc22_43.2 (constants.%T.as_type.212)] { +// CHECK:STDOUT: %T.ref: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39) = name_ref T, %T.loc22_24.1 [symbolic = %T.loc22_24.2 (constants.%T.223)] +// CHECK:STDOUT: %T.as_type.loc22_43.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc22_43.2 (constants.%T.as_type.212)] +// CHECK:STDOUT: %.loc22_43.2: type = converted %T.ref, %T.as_type.loc22_43.1 [symbolic = %T.as_type.loc22_43.2 (constants.%T.as_type.212)] // CHECK:STDOUT: } -// CHECK:STDOUT: %e: @Feed.%T.as_type.loc23_43.2 (%T.as_type.212) = bind_name e, %e.param -// CHECK:STDOUT: %food.param: @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952) = value_param runtime_param1 -// CHECK:STDOUT: %.loc23_52.1: type = splice_block %.loc23_52.2 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] { -// CHECK:STDOUT: %Food.ref.loc23_52: %Edible.type = name_ref Food, %Food.loc23_9.1 [symbolic = %Food.loc23_9.2 (constants.%Food.9af)] -// CHECK:STDOUT: %Food.as_type.loc23_52: type = facet_access_type %Food.ref.loc23_52 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] -// CHECK:STDOUT: %.loc23_52.2: type = converted %Food.ref.loc23_52, %Food.as_type.loc23_52 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] +// CHECK:STDOUT: %e: @Feed.%T.as_type.loc22_43.2 (%T.as_type.212) = bind_name e, %e.param +// CHECK:STDOUT: %food.param: @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952) = value_param runtime_param1 +// CHECK:STDOUT: %.loc22_52.1: type = splice_block %.loc22_52.2 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] { +// CHECK:STDOUT: %Food.ref.loc22_52: %Edible.type = name_ref Food, %Food.loc22_9.1 [symbolic = %Food.loc22_9.2 (constants.%Food.9af)] +// CHECK:STDOUT: %Food.as_type.loc22_52: type = facet_access_type %Food.ref.loc22_52 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] +// CHECK:STDOUT: %.loc22_52.2: type = converted %Food.ref.loc22_52, %Food.as_type.loc22_52 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] // CHECK:STDOUT: } -// CHECK:STDOUT: %food: @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952) = bind_name food, %food.param +// CHECK:STDOUT: %food: @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952) = bind_name food, %food.param // CHECK:STDOUT: } // CHECK:STDOUT: %HandleAnimal.decl: %HandleAnimal.type = fn_decl @HandleAnimal [concrete = constants.%HandleAnimal] { -// CHECK:STDOUT: %T.patt.loc24_17.1: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc24_17.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %T.param_patt: %Animal.type = value_param_pattern %T.patt.loc24_17.1, runtime_param [symbolic = %T.patt.loc24_17.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %Food.patt.loc24_29.1: %Edible.type = symbolic_binding_pattern Food, 1 [symbolic = %Food.patt.loc24_29.2 (constants.%Food.patt.551)] -// CHECK:STDOUT: %Food.param_patt: %Edible.type = value_param_pattern %Food.patt.loc24_29.1, runtime_param [symbolic = %Food.patt.loc24_29.2 (constants.%Food.patt.551)] -// CHECK:STDOUT: %a.patt: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) = value_param_pattern %a.patt, runtime_param0 -// CHECK:STDOUT: %food.patt: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) = binding_pattern food -// CHECK:STDOUT: %food.param_patt: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) = value_param_pattern %food.patt, runtime_param1 +// CHECK:STDOUT: %T.patt.loc23_17.1: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc23_17.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %T.param_patt: %Animal.type = value_param_pattern %T.patt.loc23_17.1, runtime_param [symbolic = %T.patt.loc23_17.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %Food.patt.loc23_29.1: %Edible.type = symbolic_binding_pattern Food, 1 [symbolic = %Food.patt.loc23_29.2 (constants.%Food.patt.551)] +// CHECK:STDOUT: %Food.param_patt: %Edible.type = value_param_pattern %Food.patt.loc23_29.1, runtime_param [symbolic = %Food.patt.loc23_29.2 (constants.%Food.patt.551)] +// CHECK:STDOUT: %a.patt: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %food.patt: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) = binding_pattern food +// CHECK:STDOUT: %food.param_patt: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) = value_param_pattern %food.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: %Animal.type = value_param runtime_param // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] -// CHECK:STDOUT: %T.loc24_17.1: %Animal.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc24_17.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.loc23_17.1: %Animal.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc23_17.2 (constants.%T.fd4)] // CHECK:STDOUT: %Food.param: %Edible.type = value_param runtime_param // CHECK:STDOUT: %Edible.ref: type = name_ref Edible, file.%Edible.decl [concrete = constants.%Edible.type] -// CHECK:STDOUT: %Food.loc24_29.1: %Edible.type = bind_symbolic_name Food, 1, %Food.param [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %a.param: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) = value_param runtime_param0 -// CHECK:STDOUT: %.loc24_47.1: type = splice_block %.loc24_47.2 [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] { -// CHECK:STDOUT: %T.ref: %Animal.type = name_ref T, %T.loc24_17.1 [symbolic = %T.loc24_17.2 (constants.%T.fd4)] -// CHECK:STDOUT: %T.as_type.loc24_47.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %.loc24_47.2: type = converted %T.ref, %T.as_type.loc24_47.1 [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %Food.loc23_29.1: %Edible.type = bind_symbolic_name Food, 1, %Food.param [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %a.param: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) = value_param runtime_param0 +// CHECK:STDOUT: %.loc23_47.1: type = splice_block %.loc23_47.2 [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] { +// CHECK:STDOUT: %T.ref: %Animal.type = name_ref T, %T.loc23_17.1 [symbolic = %T.loc23_17.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.as_type.loc23_47.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %.loc23_47.2: type = converted %T.ref, %T.as_type.loc23_47.1 [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) = bind_name a, %a.param -// CHECK:STDOUT: %food.param: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) = value_param runtime_param1 -// CHECK:STDOUT: %.loc24_56.1: type = splice_block %.loc24_56.2 [symbolic = %Food.as_type.loc24_56.2 (constants.%Food.as_type.fae)] { -// CHECK:STDOUT: %Food.ref: %Edible.type = name_ref Food, %Food.loc24_29.1 [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %Food.as_type.loc24_56.1: type = facet_access_type %Food.ref [symbolic = %Food.as_type.loc24_56.2 (constants.%Food.as_type.fae)] -// CHECK:STDOUT: %.loc24_56.2: type = converted %Food.ref, %Food.as_type.loc24_56.1 [symbolic = %Food.as_type.loc24_56.2 (constants.%Food.as_type.fae)] +// CHECK:STDOUT: %a: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) = bind_name a, %a.param +// CHECK:STDOUT: %food.param: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) = value_param runtime_param1 +// CHECK:STDOUT: %.loc23_56.1: type = splice_block %.loc23_56.2 [symbolic = %Food.as_type.loc23_56.2 (constants.%Food.as_type.fae)] { +// CHECK:STDOUT: %Food.ref: %Edible.type = name_ref Food, %Food.loc23_29.1 [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %Food.as_type.loc23_56.1: type = facet_access_type %Food.ref [symbolic = %Food.as_type.loc23_56.2 (constants.%Food.as_type.fae)] +// CHECK:STDOUT: %.loc23_56.2: type = converted %Food.ref, %Food.as_type.loc23_56.1 [symbolic = %Food.as_type.loc23_56.2 (constants.%Food.as_type.fae)] // CHECK:STDOUT: } -// CHECK:STDOUT: %food: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) = bind_name food, %food.param +// CHECK:STDOUT: %food: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) = bind_name food, %food.param // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } @@ -398,28 +377,28 @@ fn F() { // CHECK:STDOUT: witness = file.%impl_witness.loc9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc18_14.1: %Animal.type, %U.loc18_26.1: %Edible.type) { -// CHECK:STDOUT: %T.loc18_14.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc18_14.2 (constants.%T.fd4)] -// CHECK:STDOUT: %T.patt.loc18_14.2: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc18_14.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %U.loc18_26.2: %Edible.type = bind_symbolic_name U, 1 [symbolic = %U.loc18_26.2 (constants.%U)] -// CHECK:STDOUT: %U.patt.loc18_26.2: %Edible.type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc18_26.2 (constants.%U.patt)] -// CHECK:STDOUT: %T.as_type.loc18_38.2: type = facet_access_type %T.loc18_14.2 [symbolic = %T.as_type.loc18_38.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %U.as_type.loc18_49.2: type = facet_access_type %U.loc18_26.2 [symbolic = %U.as_type.loc18_49.2 (constants.%U.as_type)] -// CHECK:STDOUT: %Eats.type.loc18_49.2: type = facet_type <@Eats, @Eats(%U.as_type.loc18_49.2)> [symbolic = %Eats.type.loc18_49.2 (constants.%Eats.type.f54c3d.1)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%Eats.type.loc18_49.2 (%Eats.type.f54c3d.1) [symbolic = %require_complete (constants.%require_complete.42532a.1)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc18_14.2, %U.loc18_26.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.1)] +// CHECK:STDOUT: generic impl @impl.2(%T.loc17_14.1: %Animal.type, %U.loc17_26.1: %Edible.type) { +// CHECK:STDOUT: %T.loc17_14.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc17_14.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.patt.loc17_14.2: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %U.loc17_26.2: %Edible.type = bind_symbolic_name U, 1 [symbolic = %U.loc17_26.2 (constants.%U)] +// CHECK:STDOUT: %U.patt.loc17_26.2: %Edible.type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_26.2 (constants.%U.patt)] +// CHECK:STDOUT: %T.as_type.loc17_38.2: type = facet_access_type %T.loc17_14.2 [symbolic = %T.as_type.loc17_38.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %U.as_type.loc17_49.2: type = facet_access_type %U.loc17_26.2 [symbolic = %U.as_type.loc17_49.2 (constants.%U.as_type)] +// CHECK:STDOUT: %Eats.type.loc17_49.2: type = facet_type <@Eats, @Eats(%U.as_type.loc17_49.2)> [symbolic = %Eats.type.loc17_49.2 (constants.%Eats.type.f54c3d.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%Eats.type.loc17_49.2 (%Eats.type.f54c3d.1) [symbolic = %require_complete (constants.%require_complete.42532a.1)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc17_14.2, %U.loc17_26.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: impl: %.loc18_38 as %Eats.type.loc18_49.1 { +// CHECK:STDOUT: impl: %.loc17_38 as %Eats.type.loc17_49.1 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness.loc18 +// CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @impl.3: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness.loc21 +// CHECK:STDOUT: witness = file.%impl_witness.loc20 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Grass { @@ -438,59 +417,59 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Feed(%Food.loc23_9.1: %Edible.type, %T.loc23_24.1: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39)) { -// CHECK:STDOUT: %Food.loc23_9.2: %Edible.type = bind_symbolic_name Food, 0 [symbolic = %Food.loc23_9.2 (constants.%Food.9af)] -// CHECK:STDOUT: %Food.patt.loc23_9.2: %Edible.type = symbolic_binding_pattern Food, 0 [symbolic = %Food.patt.loc23_9.2 (constants.%Food.patt.0b7)] -// CHECK:STDOUT: %Food.as_type.loc23_37.2: type = facet_access_type %Food.loc23_9.2 [symbolic = %Food.as_type.loc23_37.2 (constants.%Food.as_type.952)] -// CHECK:STDOUT: %Eats.type.loc23_37.2: type = facet_type <@Eats, @Eats(%Food.as_type.loc23_37.2)> [symbolic = %Eats.type.loc23_37.2 (constants.%Eats.type.b39)] -// CHECK:STDOUT: %T.loc23_24.2: %Eats.type.b39 = bind_symbolic_name T, 1 [symbolic = %T.loc23_24.2 (constants.%T.223)] -// CHECK:STDOUT: %T.patt.loc23_24.2: %Eats.type.b39 = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc23_24.2 (constants.%T.patt.f09)] -// CHECK:STDOUT: %T.as_type.loc23_43.2: type = facet_access_type %T.loc23_24.2 [symbolic = %T.as_type.loc23_43.2 (constants.%T.as_type.212)] +// CHECK:STDOUT: generic fn @Feed(%Food.loc22_9.1: %Edible.type, %T.loc22_24.1: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39)) { +// CHECK:STDOUT: %Food.loc22_9.2: %Edible.type = bind_symbolic_name Food, 0 [symbolic = %Food.loc22_9.2 (constants.%Food.9af)] +// CHECK:STDOUT: %Food.patt.loc22_9.2: %Edible.type = symbolic_binding_pattern Food, 0 [symbolic = %Food.patt.loc22_9.2 (constants.%Food.patt.0b7)] +// CHECK:STDOUT: %Food.as_type.loc22_37.2: type = facet_access_type %Food.loc22_9.2 [symbolic = %Food.as_type.loc22_37.2 (constants.%Food.as_type.952)] +// CHECK:STDOUT: %Eats.type.loc22_37.2: type = facet_type <@Eats, @Eats(%Food.as_type.loc22_37.2)> [symbolic = %Eats.type.loc22_37.2 (constants.%Eats.type.b39)] +// CHECK:STDOUT: %T.loc22_24.2: %Eats.type.b39 = bind_symbolic_name T, 1 [symbolic = %T.loc22_24.2 (constants.%T.223)] +// CHECK:STDOUT: %T.patt.loc22_24.2: %Eats.type.b39 = symbolic_binding_pattern T, 1 [symbolic = %T.patt.loc22_24.2 (constants.%T.patt.f09)] +// CHECK:STDOUT: %T.as_type.loc22_43.2: type = facet_access_type %T.loc22_24.2 [symbolic = %T.as_type.loc22_43.2 (constants.%T.as_type.212)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc23_41: = require_complete_type @Feed.%T.as_type.loc23_43.2 (%T.as_type.212) [symbolic = %require_complete.loc23_41 (constants.%require_complete.fe6)] -// CHECK:STDOUT: %require_complete.loc23_50: = require_complete_type @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952) [symbolic = %require_complete.loc23_50 (constants.%require_complete.005)] +// CHECK:STDOUT: %require_complete.loc22_41: = require_complete_type @Feed.%T.as_type.loc22_43.2 (%T.as_type.212) [symbolic = %require_complete.loc22_41 (constants.%require_complete.fe6)] +// CHECK:STDOUT: %require_complete.loc22_50: = require_complete_type @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952) [symbolic = %require_complete.loc22_50 (constants.%require_complete.005)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%Food.param_patt: %Edible.type, %T.param_patt: @Feed.%Eats.type.loc23_37.2 (%Eats.type.b39)](%e.param_patt: @Feed.%T.as_type.loc23_43.2 (%T.as_type.212), %food.param_patt: @Feed.%Food.as_type.loc23_37.2 (%Food.as_type.952)) { +// CHECK:STDOUT: fn[%Food.param_patt: %Edible.type, %T.param_patt: @Feed.%Eats.type.loc22_37.2 (%Eats.type.b39)](%e.param_patt: @Feed.%T.as_type.loc22_43.2 (%T.as_type.212), %food.param_patt: @Feed.%Food.as_type.loc22_37.2 (%Food.as_type.952)) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @HandleAnimal(%T.loc24_17.1: %Animal.type, %Food.loc24_29.1: %Edible.type) { -// CHECK:STDOUT: %T.loc24_17.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc24_17.2 (constants.%T.fd4)] -// CHECK:STDOUT: %T.patt.loc24_17.2: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc24_17.2 (constants.%T.patt.a9c)] -// CHECK:STDOUT: %Food.loc24_29.2: %Edible.type = bind_symbolic_name Food, 1 [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %Food.patt.loc24_29.2: %Edible.type = symbolic_binding_pattern Food, 1 [symbolic = %Food.patt.loc24_29.2 (constants.%Food.patt.551)] -// CHECK:STDOUT: %T.as_type.loc24_47.2: type = facet_access_type %T.loc24_17.2 [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %Food.as_type.loc24_56.2: type = facet_access_type %Food.loc24_29.2 [symbolic = %Food.as_type.loc24_56.2 (constants.%Food.as_type.fae)] +// CHECK:STDOUT: generic fn @HandleAnimal(%T.loc23_17.1: %Animal.type, %Food.loc23_29.1: %Edible.type) { +// CHECK:STDOUT: %T.loc23_17.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc23_17.2 (constants.%T.fd4)] +// CHECK:STDOUT: %T.patt.loc23_17.2: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc23_17.2 (constants.%T.patt.a9c)] +// CHECK:STDOUT: %Food.loc23_29.2: %Edible.type = bind_symbolic_name Food, 1 [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %Food.patt.loc23_29.2: %Edible.type = symbolic_binding_pattern Food, 1 [symbolic = %Food.patt.loc23_29.2 (constants.%Food.patt.551)] +// CHECK:STDOUT: %T.as_type.loc23_47.2: type = facet_access_type %T.loc23_17.2 [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %Food.as_type.loc23_56.2: type = facet_access_type %Food.loc23_29.2 [symbolic = %Food.as_type.loc23_56.2 (constants.%Food.as_type.fae)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc24_45: = require_complete_type @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) [symbolic = %require_complete.loc24_45 (constants.%require_complete.234)] -// CHECK:STDOUT: %require_complete.loc24_54: = require_complete_type @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) [symbolic = %require_complete.loc24_54 (constants.%require_complete.444)] -// CHECK:STDOUT: %Eats.type: type = facet_type <@Eats, @Eats(%Food.as_type.loc24_56.2)> [symbolic = %Eats.type (constants.%Eats.type.f54c3d.2)] -// CHECK:STDOUT: %require_complete.loc24_76: = require_complete_type @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) [symbolic = %require_complete.loc24_76 (constants.%require_complete.42532a.2)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc24_17.2, %Food.loc24_29.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.2)] -// CHECK:STDOUT: %Eats.facet.loc24_76.2: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value %T.as_type.loc24_47.2, %impl_witness [symbolic = %Eats.facet.loc24_76.2 (constants.%Eats.facet.b56)] -// CHECK:STDOUT: %Feed.specific_fn.loc24_64.2: = specific_function constants.%Feed, @Feed(%Food.loc24_29.2, %Eats.facet.loc24_76.2) [symbolic = %Feed.specific_fn.loc24_64.2 (constants.%Feed.specific_fn.f4b)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: %Animal.type, %Food.param_patt: %Edible.type](%a.param_patt: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad), %food.param_patt: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae)) { +// CHECK:STDOUT: %require_complete.loc23_45: = require_complete_type @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) [symbolic = %require_complete.loc23_45 (constants.%require_complete.234)] +// CHECK:STDOUT: %require_complete.loc23_54: = require_complete_type @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) [symbolic = %require_complete.loc23_54 (constants.%require_complete.444)] +// CHECK:STDOUT: %Eats.type: type = facet_type <@Eats, @Eats(%Food.as_type.loc23_56.2)> [symbolic = %Eats.type (constants.%Eats.type.f54c3d.2)] +// CHECK:STDOUT: %require_complete.loc23_76: = require_complete_type @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) [symbolic = %require_complete.loc23_76 (constants.%require_complete.42532a.2)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc23_17.2, %Food.loc23_29.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.2)] +// CHECK:STDOUT: %Eats.facet.loc23_76.2: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value %T.as_type.loc23_47.2, %impl_witness [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.b56)] +// CHECK:STDOUT: %Feed.specific_fn.loc23_64.2: = specific_function constants.%Feed, @Feed(%Food.loc23_29.2, %Eats.facet.loc23_76.2) [symbolic = %Feed.specific_fn.loc23_64.2 (constants.%Feed.specific_fn.f4b)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %Animal.type, %Food.param_patt: %Edible.type](%a.param_patt: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad), %food.param_patt: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae)) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Feed.ref: %Feed.type = name_ref Feed, file.%Feed.decl [concrete = constants.%Feed] -// CHECK:STDOUT: %a.ref: @HandleAnimal.%T.as_type.loc24_47.2 (%T.as_type.2ad) = name_ref a, %a -// CHECK:STDOUT: %food.ref: @HandleAnimal.%Food.as_type.loc24_56.2 (%Food.as_type.fae) = name_ref food, %food -// CHECK:STDOUT: %.loc24_76.1: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %.loc24_76.2: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %.loc24_76.3: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %T.as_type.loc24_76: type = facet_access_type constants.%T.fd4 [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %.loc24_76.4: type = converted constants.%T.fd4, %T.as_type.loc24_76 [symbolic = %T.as_type.loc24_47.2 (constants.%T.as_type.2ad)] -// CHECK:STDOUT: %.loc24_76.5: %Animal.type = converted %.loc24_76.4, constants.%T.fd4 [symbolic = %T.loc24_17.2 (constants.%T.fd4)] -// CHECK:STDOUT: %.loc24_76.6: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc24_29.2 (constants.%Food.5fe)] -// CHECK:STDOUT: %.loc24_76.7: %Animal.type = converted constants.%T.as_type.2ad, constants.%T.fd4 [symbolic = %T.loc24_17.2 (constants.%T.fd4)] -// CHECK:STDOUT: %Eats.facet.loc24_76.1: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value constants.%T.as_type.2ad, constants.%impl_witness.c7c36b.2 [symbolic = %Eats.facet.loc24_76.2 (constants.%Eats.facet.b56)] -// CHECK:STDOUT: %.loc24_76.8: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = converted constants.%T.as_type.2ad, %Eats.facet.loc24_76.1 [symbolic = %Eats.facet.loc24_76.2 (constants.%Eats.facet.b56)] -// CHECK:STDOUT: %Feed.specific_fn.loc24_64.1: = specific_function %Feed.ref, @Feed(constants.%Food.5fe, %.loc24_76.8) [symbolic = %Feed.specific_fn.loc24_64.2 (constants.%Feed.specific_fn.f4b)] -// CHECK:STDOUT: %Feed.call: init %empty_tuple.type = call %Feed.specific_fn.loc24_64.1(%a.ref, %food.ref) +// CHECK:STDOUT: %a.ref: @HandleAnimal.%T.as_type.loc23_47.2 (%T.as_type.2ad) = name_ref a, %a +// CHECK:STDOUT: %food.ref: @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) = name_ref food, %food +// CHECK:STDOUT: %.loc23_76.1: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %.loc23_76.2: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %.loc23_76.3: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %T.as_type.loc23_76: type = facet_access_type constants.%T.fd4 [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %.loc23_76.4: type = converted constants.%T.fd4, %T.as_type.loc23_76 [symbolic = %T.as_type.loc23_47.2 (constants.%T.as_type.2ad)] +// CHECK:STDOUT: %.loc23_76.5: %Animal.type = converted %.loc23_76.4, constants.%T.fd4 [symbolic = %T.loc23_17.2 (constants.%T.fd4)] +// CHECK:STDOUT: %.loc23_76.6: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc23_29.2 (constants.%Food.5fe)] +// CHECK:STDOUT: %.loc23_76.7: %Animal.type = converted constants.%T.as_type.2ad, constants.%T.fd4 [symbolic = %T.loc23_17.2 (constants.%T.fd4)] +// CHECK:STDOUT: %Eats.facet.loc23_76.1: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value constants.%T.as_type.2ad, constants.%impl_witness.c7c36b.2 [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.b56)] +// CHECK:STDOUT: %.loc23_76.8: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = converted constants.%T.as_type.2ad, %Eats.facet.loc23_76.1 [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.b56)] +// CHECK:STDOUT: %Feed.specific_fn.loc23_64.1: = specific_function %Feed.ref, @Feed(constants.%Food.5fe, %.loc23_76.8) [symbolic = %Feed.specific_fn.loc23_64.2 (constants.%Feed.specific_fn.f4b)] +// CHECK:STDOUT: %Feed.call: init %empty_tuple.type = call %Feed.specific_fn.loc23_64.1(%a.ref, %food.ref) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -498,34 +477,30 @@ fn F() { // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %HandleAnimal.ref: %HandleAnimal.type = name_ref HandleAnimal, file.%HandleAnimal.decl [concrete = constants.%HandleAnimal] -// CHECK:STDOUT: %.loc47_17.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc26_17.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] -// CHECK:STDOUT: %.loc47_17.2: ref %Goat = temporary_storage -// CHECK:STDOUT: %.loc47_17.3: init %Goat = class_init (), %.loc47_17.2 [concrete = constants.%Goat.val] -// CHECK:STDOUT: %.loc47_17.4: ref %Goat = temporary %.loc47_17.2, %.loc47_17.3 -// CHECK:STDOUT: %.loc47_19.1: ref %Goat = converted %.loc47_17.1, %.loc47_17.4 -// CHECK:STDOUT: %.loc47_29.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc26_17.2: ref %Goat = temporary_storage +// CHECK:STDOUT: %.loc26_17.3: init %Goat = class_init (), %.loc26_17.2 [concrete = constants.%Goat.val] +// CHECK:STDOUT: %.loc26_17.4: ref %Goat = temporary %.loc26_17.2, %.loc26_17.3 +// CHECK:STDOUT: %.loc26_19.1: ref %Goat = converted %.loc26_17.1, %.loc26_17.4 +// CHECK:STDOUT: %.loc26_29.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %Grass.ref: type = name_ref Grass, file.%Grass.decl [concrete = constants.%Grass] -// CHECK:STDOUT: %.loc47_29.2: ref %Grass = temporary_storage -// CHECK:STDOUT: %.loc47_29.3: init %Grass = class_init (), %.loc47_29.2 [concrete = constants.%Grass.val] -// CHECK:STDOUT: %.loc47_29.4: ref %Grass = temporary %.loc47_29.2, %.loc47_29.3 -// CHECK:STDOUT: %.loc47_31.1: ref %Grass = converted %.loc47_29.1, %.loc47_29.4 -// CHECK:STDOUT: %Animal.facet.loc47_39.1: %Animal.type = facet_value constants.%Goat, [concrete = ] -// CHECK:STDOUT: %.loc47_39.1: %Animal.type = converted constants.%Goat, %Animal.facet.loc47_39.1 [concrete = ] -// CHECK:STDOUT: %Animal.facet.loc47_39.2: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] -// CHECK:STDOUT: %.loc47_39.2: %Animal.type = converted constants.%Goat, %Animal.facet.loc47_39.2 [concrete = constants.%Animal.facet] -// CHECK:STDOUT: %Animal.facet.loc47_39.3: %Animal.type = facet_value constants.%Goat, [concrete = ] -// CHECK:STDOUT: %.loc47_39.3: %Animal.type = converted constants.%Goat, %Animal.facet.loc47_39.3 [concrete = ] -// CHECK:STDOUT: %Animal.facet.loc47_39.4: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] -// CHECK:STDOUT: %.loc47_39.4: %Animal.type = converted constants.%Goat, %Animal.facet.loc47_39.4 [concrete = constants.%Animal.facet] -// CHECK:STDOUT: %Edible.facet.loc47_39.1: %Edible.type = facet_value constants.%Grass, constants.%impl_witness.1bc [concrete = constants.%Edible.facet] -// CHECK:STDOUT: %.loc47_39.5: %Edible.type = converted constants.%Grass, %Edible.facet.loc47_39.1 [concrete = constants.%Edible.facet] -// CHECK:STDOUT: %Edible.facet.loc47_39.2: %Edible.type = facet_value constants.%Grass, constants.%impl_witness.1bc [concrete = constants.%Edible.facet] -// CHECK:STDOUT: %.loc47_39.6: %Edible.type = converted constants.%Grass, %Edible.facet.loc47_39.2 [concrete = constants.%Edible.facet] +// CHECK:STDOUT: %.loc26_29.2: ref %Grass = temporary_storage +// CHECK:STDOUT: %.loc26_29.3: init %Grass = class_init (), %.loc26_29.2 [concrete = constants.%Grass.val] +// CHECK:STDOUT: %.loc26_29.4: ref %Grass = temporary %.loc26_29.2, %.loc26_29.3 +// CHECK:STDOUT: %.loc26_31.1: ref %Grass = converted %.loc26_29.1, %.loc26_29.4 +// CHECK:STDOUT: %Animal.facet.loc26_39.1: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc26_39.1: %Animal.type = converted constants.%Goat, %Animal.facet.loc26_39.1 [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %Animal.facet.loc26_39.2: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc26_39.2: %Animal.type = converted constants.%Goat, %Animal.facet.loc26_39.2 [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %Edible.facet.loc26_39.1: %Edible.type = facet_value constants.%Grass, constants.%impl_witness.1bc [concrete = constants.%Edible.facet] +// CHECK:STDOUT: %.loc26_39.3: %Edible.type = converted constants.%Grass, %Edible.facet.loc26_39.1 [concrete = constants.%Edible.facet] +// CHECK:STDOUT: %Edible.facet.loc26_39.2: %Edible.type = facet_value constants.%Grass, constants.%impl_witness.1bc [concrete = constants.%Edible.facet] +// CHECK:STDOUT: %.loc26_39.4: %Edible.type = converted constants.%Grass, %Edible.facet.loc26_39.2 [concrete = constants.%Edible.facet] // CHECK:STDOUT: %HandleAnimal.specific_fn: = specific_function %HandleAnimal.ref, @HandleAnimal(constants.%Animal.facet, constants.%Edible.facet) [concrete = constants.%HandleAnimal.specific_fn] -// CHECK:STDOUT: %.loc47_19.2: %Goat = bind_value %.loc47_19.1 -// CHECK:STDOUT: %.loc47_31.2: %Grass = bind_value %.loc47_31.1 -// CHECK:STDOUT: %HandleAnimal.call: init %empty_tuple.type = call %HandleAnimal.specific_fn(%.loc47_19.2, %.loc47_31.2) +// CHECK:STDOUT: %.loc26_19.2: %Goat = bind_value %.loc26_19.1 +// CHECK:STDOUT: %.loc26_31.2: %Grass = bind_value %.loc26_31.1 +// CHECK:STDOUT: %HandleAnimal.call: init %empty_tuple.type = call %HandleAnimal.specific_fn(%.loc26_19.2, %.loc26_31.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -546,20 +521,20 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @impl.2(constants.%T.fd4, constants.%U) { -// CHECK:STDOUT: %T.loc18_14.2 => constants.%T.fd4 -// CHECK:STDOUT: %T.patt.loc18_14.2 => constants.%T.fd4 -// CHECK:STDOUT: %U.loc18_26.2 => constants.%U -// CHECK:STDOUT: %U.patt.loc18_26.2 => constants.%U -// CHECK:STDOUT: %T.as_type.loc18_38.2 => constants.%T.as_type.2ad -// CHECK:STDOUT: %U.as_type.loc18_49.2 => constants.%U.as_type -// CHECK:STDOUT: %Eats.type.loc18_49.2 => constants.%Eats.type.f54c3d.1 +// CHECK:STDOUT: %T.loc17_14.2 => constants.%T.fd4 +// CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%T.fd4 +// CHECK:STDOUT: %U.loc17_26.2 => constants.%U +// CHECK:STDOUT: %U.patt.loc17_26.2 => constants.%U +// CHECK:STDOUT: %T.as_type.loc17_38.2 => constants.%T.as_type.2ad +// CHECK:STDOUT: %U.as_type.loc17_49.2 => constants.%U.as_type +// CHECK:STDOUT: %Eats.type.loc17_49.2 => constants.%Eats.type.f54c3d.1 // CHECK:STDOUT: %require_complete => constants.%require_complete.42532a.1 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.c7c36b.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Eats(@impl.2.%U.as_type.loc18_49.2) {} +// CHECK:STDOUT: specific @Eats(@impl.2.%U.as_type.loc17_49.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc18_14.2, %U.loc18_26.2) {} +// CHECK:STDOUT: specific @impl.2(%T.loc17_14.2, %U.loc17_26.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Eats(constants.%Food.as_type.952) { // CHECK:STDOUT: %Food.loc12_16.2 => constants.%Food.as_type.952 @@ -567,24 +542,24 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Feed(constants.%Food.9af, constants.%T.223) { -// CHECK:STDOUT: %Food.loc23_9.2 => constants.%Food.9af -// CHECK:STDOUT: %Food.patt.loc23_9.2 => constants.%Food.9af -// CHECK:STDOUT: %Food.as_type.loc23_37.2 => constants.%Food.as_type.952 -// CHECK:STDOUT: %Eats.type.loc23_37.2 => constants.%Eats.type.b39 -// CHECK:STDOUT: %T.loc23_24.2 => constants.%T.223 -// CHECK:STDOUT: %T.patt.loc23_24.2 => constants.%T.223 -// CHECK:STDOUT: %T.as_type.loc23_43.2 => constants.%T.as_type.212 +// CHECK:STDOUT: %Food.loc22_9.2 => constants.%Food.9af +// CHECK:STDOUT: %Food.patt.loc22_9.2 => constants.%Food.9af +// CHECK:STDOUT: %Food.as_type.loc22_37.2 => constants.%Food.as_type.952 +// CHECK:STDOUT: %Eats.type.loc22_37.2 => constants.%Eats.type.b39 +// CHECK:STDOUT: %T.loc22_24.2 => constants.%T.223 +// CHECK:STDOUT: %T.patt.loc22_24.2 => constants.%T.223 +// CHECK:STDOUT: %T.as_type.loc22_43.2 => constants.%T.as_type.212 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Eats(@Feed.%Food.as_type.loc23_37.2) {} +// CHECK:STDOUT: specific @Eats(@Feed.%Food.as_type.loc22_37.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @HandleAnimal(constants.%T.fd4, constants.%Food.5fe) { -// CHECK:STDOUT: %T.loc24_17.2 => constants.%T.fd4 -// CHECK:STDOUT: %T.patt.loc24_17.2 => constants.%T.fd4 -// CHECK:STDOUT: %Food.loc24_29.2 => constants.%Food.5fe -// CHECK:STDOUT: %Food.patt.loc24_29.2 => constants.%Food.5fe -// CHECK:STDOUT: %T.as_type.loc24_47.2 => constants.%T.as_type.2ad -// CHECK:STDOUT: %Food.as_type.loc24_56.2 => constants.%Food.as_type.fae +// CHECK:STDOUT: %T.loc23_17.2 => constants.%T.fd4 +// CHECK:STDOUT: %T.patt.loc23_17.2 => constants.%T.fd4 +// CHECK:STDOUT: %Food.loc23_29.2 => constants.%Food.5fe +// CHECK:STDOUT: %Food.patt.loc23_29.2 => constants.%Food.5fe +// CHECK:STDOUT: %T.as_type.loc23_47.2 => constants.%T.as_type.2ad +// CHECK:STDOUT: %Food.as_type.loc23_56.2 => constants.%Food.as_type.fae // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Eats(constants.%Food.as_type.fae) { @@ -597,65 +572,65 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @impl.2(constants.%T.fd4, constants.%Food.5fe) { -// CHECK:STDOUT: %T.loc18_14.2 => constants.%T.fd4 -// CHECK:STDOUT: %T.patt.loc18_14.2 => constants.%T.fd4 -// CHECK:STDOUT: %U.loc18_26.2 => constants.%Food.5fe -// CHECK:STDOUT: %U.patt.loc18_26.2 => constants.%Food.5fe -// CHECK:STDOUT: %T.as_type.loc18_38.2 => constants.%T.as_type.2ad -// CHECK:STDOUT: %U.as_type.loc18_49.2 => constants.%Food.as_type.fae -// CHECK:STDOUT: %Eats.type.loc18_49.2 => constants.%Eats.type.f54c3d.2 +// CHECK:STDOUT: %T.loc17_14.2 => constants.%T.fd4 +// CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%T.fd4 +// CHECK:STDOUT: %U.loc17_26.2 => constants.%Food.5fe +// CHECK:STDOUT: %U.patt.loc17_26.2 => constants.%Food.5fe +// CHECK:STDOUT: %T.as_type.loc17_38.2 => constants.%T.as_type.2ad +// CHECK:STDOUT: %U.as_type.loc17_49.2 => constants.%Food.as_type.fae +// CHECK:STDOUT: %Eats.type.loc17_49.2 => constants.%Eats.type.f54c3d.2 // CHECK:STDOUT: %require_complete => constants.%require_complete.42532a.2 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.c7c36b.2 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Feed(constants.%Food.5fe, @HandleAnimal.%.loc24_76.8) { -// CHECK:STDOUT: %Food.loc23_9.2 => constants.%Food.5fe -// CHECK:STDOUT: %Food.patt.loc23_9.2 => constants.%Food.5fe -// CHECK:STDOUT: %Food.as_type.loc23_37.2 => constants.%Food.as_type.fae -// CHECK:STDOUT: %Eats.type.loc23_37.2 => constants.%Eats.type.f54c3d.2 -// CHECK:STDOUT: %T.loc23_24.2 => constants.%Eats.facet.b56 -// CHECK:STDOUT: %T.patt.loc23_24.2 => constants.%Eats.facet.b56 -// CHECK:STDOUT: %T.as_type.loc23_43.2 => constants.%T.as_type.2ad +// CHECK:STDOUT: specific @Feed(constants.%Food.5fe, @HandleAnimal.%.loc23_76.8) { +// CHECK:STDOUT: %Food.loc22_9.2 => constants.%Food.5fe +// CHECK:STDOUT: %Food.patt.loc22_9.2 => constants.%Food.5fe +// CHECK:STDOUT: %Food.as_type.loc22_37.2 => constants.%Food.as_type.fae +// CHECK:STDOUT: %Eats.type.loc22_37.2 => constants.%Eats.type.f54c3d.2 +// CHECK:STDOUT: %T.loc22_24.2 => constants.%Eats.facet.b56 +// CHECK:STDOUT: %T.patt.loc22_24.2 => constants.%Eats.facet.b56 +// CHECK:STDOUT: %T.as_type.loc22_43.2 => constants.%T.as_type.2ad // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc23_41 => constants.%require_complete.234 -// CHECK:STDOUT: %require_complete.loc23_50 => constants.%require_complete.444 +// CHECK:STDOUT: %require_complete.loc22_41 => constants.%require_complete.234 +// CHECK:STDOUT: %require_complete.loc22_50 => constants.%require_complete.444 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Feed(constants.%Food.5fe, constants.%Eats.facet.b56) { -// CHECK:STDOUT: %Food.loc23_9.2 => constants.%Food.5fe -// CHECK:STDOUT: %Food.patt.loc23_9.2 => constants.%Food.5fe -// CHECK:STDOUT: %Food.as_type.loc23_37.2 => constants.%Food.as_type.fae -// CHECK:STDOUT: %Eats.type.loc23_37.2 => constants.%Eats.type.f54c3d.2 -// CHECK:STDOUT: %T.loc23_24.2 => constants.%Eats.facet.b56 -// CHECK:STDOUT: %T.patt.loc23_24.2 => constants.%Eats.facet.b56 -// CHECK:STDOUT: %T.as_type.loc23_43.2 => constants.%T.as_type.2ad +// CHECK:STDOUT: %Food.loc22_9.2 => constants.%Food.5fe +// CHECK:STDOUT: %Food.patt.loc22_9.2 => constants.%Food.5fe +// CHECK:STDOUT: %Food.as_type.loc22_37.2 => constants.%Food.as_type.fae +// CHECK:STDOUT: %Eats.type.loc22_37.2 => constants.%Eats.type.f54c3d.2 +// CHECK:STDOUT: %T.loc22_24.2 => constants.%Eats.facet.b56 +// CHECK:STDOUT: %T.patt.loc22_24.2 => constants.%Eats.facet.b56 +// CHECK:STDOUT: %T.as_type.loc22_43.2 => constants.%T.as_type.2ad // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Eats(@HandleAnimal.%Food.as_type.loc24_56.2) {} +// CHECK:STDOUT: specific @Eats(@HandleAnimal.%Food.as_type.loc23_56.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(@HandleAnimal.%T.loc24_17.2, @HandleAnimal.%Food.loc24_29.2) {} +// CHECK:STDOUT: specific @impl.2(@HandleAnimal.%T.loc23_17.2, @HandleAnimal.%Food.loc23_29.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @Feed(@HandleAnimal.%Food.loc24_29.2, @HandleAnimal.%Eats.facet.loc24_76.2) {} +// CHECK:STDOUT: specific @Feed(@HandleAnimal.%Food.loc23_29.2, @HandleAnimal.%Eats.facet.loc23_76.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @HandleAnimal(constants.%Animal.facet, constants.%Edible.facet) { -// CHECK:STDOUT: %T.loc24_17.2 => constants.%Animal.facet -// CHECK:STDOUT: %T.patt.loc24_17.2 => constants.%Animal.facet -// CHECK:STDOUT: %Food.loc24_29.2 => constants.%Edible.facet -// CHECK:STDOUT: %Food.patt.loc24_29.2 => constants.%Edible.facet -// CHECK:STDOUT: %T.as_type.loc24_47.2 => constants.%Goat -// CHECK:STDOUT: %Food.as_type.loc24_56.2 => constants.%Grass +// CHECK:STDOUT: %T.loc23_17.2 => constants.%Animal.facet +// CHECK:STDOUT: %T.patt.loc23_17.2 => constants.%Animal.facet +// CHECK:STDOUT: %Food.loc23_29.2 => constants.%Edible.facet +// CHECK:STDOUT: %Food.patt.loc23_29.2 => constants.%Edible.facet +// CHECK:STDOUT: %T.as_type.loc23_47.2 => constants.%Goat +// CHECK:STDOUT: %Food.as_type.loc23_56.2 => constants.%Grass // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc24_45 => constants.%complete_type.357 -// CHECK:STDOUT: %require_complete.loc24_54 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc23_45 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc23_54 => constants.%complete_type.357 // CHECK:STDOUT: %Eats.type => constants.%Eats.type.1ae -// CHECK:STDOUT: %require_complete.loc24_76 => constants.%complete_type.004 +// CHECK:STDOUT: %require_complete.loc23_76 => constants.%complete_type.004 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.15d -// CHECK:STDOUT: %Eats.facet.loc24_76.2 => constants.%Eats.facet.c76 -// CHECK:STDOUT: %Feed.specific_fn.loc24_64.2 => constants.%Feed.specific_fn.e8d +// CHECK:STDOUT: %Eats.facet.loc23_76.2 => constants.%Eats.facet.c76 +// CHECK:STDOUT: %Feed.specific_fn.loc23_64.2 => constants.%Feed.specific_fn.e8d // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Eats(constants.%Grass) { @@ -668,24 +643,24 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @impl.2(constants.%Animal.facet, constants.%Edible.facet) { -// CHECK:STDOUT: %T.loc18_14.2 => constants.%Animal.facet -// CHECK:STDOUT: %T.patt.loc18_14.2 => constants.%Animal.facet -// CHECK:STDOUT: %U.loc18_26.2 => constants.%Edible.facet -// CHECK:STDOUT: %U.patt.loc18_26.2 => constants.%Edible.facet -// CHECK:STDOUT: %T.as_type.loc18_38.2 => constants.%Goat -// CHECK:STDOUT: %U.as_type.loc18_49.2 => constants.%Grass -// CHECK:STDOUT: %Eats.type.loc18_49.2 => constants.%Eats.type.1ae +// CHECK:STDOUT: %T.loc17_14.2 => constants.%Animal.facet +// CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%Animal.facet +// CHECK:STDOUT: %U.loc17_26.2 => constants.%Edible.facet +// CHECK:STDOUT: %U.patt.loc17_26.2 => constants.%Edible.facet +// CHECK:STDOUT: %T.as_type.loc17_38.2 => constants.%Goat +// CHECK:STDOUT: %U.as_type.loc17_49.2 => constants.%Grass +// CHECK:STDOUT: %Eats.type.loc17_49.2 => constants.%Eats.type.1ae // CHECK:STDOUT: %require_complete => constants.%complete_type.004 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.15d // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Feed(constants.%Edible.facet, constants.%Eats.facet.c76) { -// CHECK:STDOUT: %Food.loc23_9.2 => constants.%Edible.facet -// CHECK:STDOUT: %Food.patt.loc23_9.2 => constants.%Edible.facet -// CHECK:STDOUT: %Food.as_type.loc23_37.2 => constants.%Grass -// CHECK:STDOUT: %Eats.type.loc23_37.2 => constants.%Eats.type.1ae -// CHECK:STDOUT: %T.loc23_24.2 => constants.%Eats.facet.c76 -// CHECK:STDOUT: %T.patt.loc23_24.2 => constants.%Eats.facet.c76 -// CHECK:STDOUT: %T.as_type.loc23_43.2 => constants.%Goat +// CHECK:STDOUT: %Food.loc22_9.2 => constants.%Edible.facet +// CHECK:STDOUT: %Food.patt.loc22_9.2 => constants.%Edible.facet +// CHECK:STDOUT: %Food.as_type.loc22_37.2 => constants.%Grass +// CHECK:STDOUT: %Eats.type.loc22_37.2 => constants.%Eats.type.1ae +// CHECK:STDOUT: %T.loc22_24.2 => constants.%Eats.facet.c76 +// CHECK:STDOUT: %T.patt.loc22_24.2 => constants.%Eats.facet.c76 +// CHECK:STDOUT: %T.as_type.loc22_43.2 => constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon index ffc19bdfb0d67..dd33f507d2495 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon @@ -197,7 +197,7 @@ fn F() { ({} as C) as (C as First); } -// --- fail_todo_deduce_cycle_with_symbolic.carbon +// --- deduce_cycle_with_symbolic.carbon library "[[@TEST_NAME]]"; interface First(T:! type) {} @@ -211,27 +211,7 @@ impl forall [T:! type] T as Second {} class C {} -// TODO: See the TODO in impl_lookup.cpp to reject impls where the interface -// does not match the query. fn F() { - // CHECK:STDERR: fail_todo_deduce_cycle_with_symbolic.carbon:[[@LINE+7]]:17: error: cycle found in lookup of interface for type `C` [ImplLookupCycle] - // CHECK:STDERR: ({} as C) as (C as Second); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_todo_deduce_cycle_with_symbolic.carbon:[[@LINE-11]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: impl forall [T:! Second, U:! type] T as First(U) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: ({} as C) as (C as Second); - - // CHECK:STDERR: fail_todo_deduce_cycle_with_symbolic.carbon:[[@LINE+10]]:17: error: cycle found in lookup of interface for type `C` [ImplLookupCycle] - // CHECK:STDERR: ({} as C) as (C as First(C)); - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_deduce_cycle_with_symbolic.carbon:[[@LINE-20]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: impl forall [T:! Second, U:! type] T as First(U) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_deduce_cycle_with_symbolic.carbon:[[@LINE-23]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: impl forall [T:! Second, U:! type] T as First(U) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: ({} as C) as (C as First(C)); } diff --git a/toolchain/check/testdata/where_expr/equal_rewrite.carbon b/toolchain/check/testdata/where_expr/equal_rewrite.carbon index 0600f675a21a2..b80237072d58e 100644 --- a/toolchain/check/testdata/where_expr/equal_rewrite.carbon +++ b/toolchain/check/testdata/where_expr/equal_rewrite.carbon @@ -172,6 +172,10 @@ interface A {} class D {} impl D as A {} // TODO: This should be a compile-time binding, once that is supported. +// CHECK:STDERR: fail_todo_let.carbon:[[@LINE+11]]:35: error: semantics TODO: `impl lookup for a FacetType with no interface (using `where .Self impls ...` instead?)` [SemanticsTodo] +// CHECK:STDERR: let B: type where .Self impls A = D; +// CHECK:STDERR: ^ +// CHECK:STDERR: // CHECK:STDERR: fail_todo_let.carbon:[[@LINE+7]]:35: error: cannot implicitly convert from `type` to `type where...` [ImplicitAsConversionFailure] // CHECK:STDERR: let B: type where .Self impls A = D; // CHECK:STDERR: ^ @@ -1422,15 +1426,15 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %B.patt: %type_where = binding_pattern B // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc15_13.1: type = splice_block %.loc15_13.2 [concrete = constants.%type_where] { +// CHECK:STDOUT: %.loc19_13.1: type = splice_block %.loc19_13.2 [concrete = constants.%type_where] { // CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %A.ref: type = name_ref A, %A.decl [concrete = constants.%A.type] -// CHECK:STDOUT: %.loc15_13.2: type = where_expr %.Self [concrete = constants.%type_where] { +// CHECK:STDOUT: %.loc19_13.2: type = where_expr %.Self [concrete = constants.%type_where] { // CHECK:STDOUT: requirement_impls %.Self.ref, %A.ref // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc15_35: %type_where = converted @__global_init.%D.ref, [concrete = ] +// CHECK:STDOUT: %.loc19_35: %type_where = converted @__global_init.%D.ref, [concrete = ] // CHECK:STDOUT: %B: %type_where = bind_name B, // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 132cfb9cc5cb4..257b04fc602f3 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -153,6 +153,7 @@ class File : public Printable { auto associated_constants() const -> const ValueStore& { return associated_constants_; } + // TODO: Rename these to `facet_type_infos`. auto facet_types() -> CanonicalValueStore& { return facet_types_; } diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index b201457c27caf..186bc24e9b657 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -651,6 +651,7 @@ struct FacetType { .deduce_through = true}); TypeId type_id; + // TODO: Rename this to facet_type_info_id. FacetTypeId facet_type_id; }; From 21252b5e94fda279caf6cf10a551774d148c9071 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 24 Feb 2025 14:41:59 -0800 Subject: [PATCH 14/56] Add missing trailing return types (#5006) Noted CopyNameFromImportIR while glancing around (this one's interesting because it's NameId, not void nor auto), did a scan just for a few other cases. Not an exhaustive fix, and TBH assuming we'd prefer `auto ... -> auto` since equivalent Carbon syntax would probably be `fn ... -> auto` --- common/check_internal.h | 2 +- testing/base/capture_std_streams.h | 2 +- testing/file_test/test_file.cpp | 2 +- testing/file_test/test_file.h | 2 +- toolchain/check/import.cpp | 3 ++- toolchain/lower/constant.cpp | 2 +- toolchain/lower/function_context.cpp | 2 +- toolchain/lower/function_context.h | 4 ++-- toolchain/parse/extract.cpp | 4 +++- toolchain/parse/node_kind.h | 2 +- toolchain/parse/precedence.cpp | 12 ++++++------ toolchain/sem_ir/inst.h | 2 +- 12 files changed, 21 insertions(+), 18 deletions(-) diff --git a/common/check_internal.h b/common/check_internal.h index ff76ed13429a4..8ff1e932ab78c 100644 --- a/common/check_internal.h +++ b/common/check_internal.h @@ -61,7 +61,7 @@ auto ConvertFormatValue(T&& t) -> T&& { // without the user writing a cast. template requires(std::is_enum_v>) -auto ConvertFormatValue(T&& t) { +auto ConvertFormatValue(T&& t) -> auto { if constexpr (std::is_signed_v< std::underlying_type_t>>) { return static_cast(t); diff --git a/testing/base/capture_std_streams.h b/testing/base/capture_std_streams.h index b8073bb13f337..7e33822216a5d 100644 --- a/testing/base/capture_std_streams.h +++ b/testing/base/capture_std_streams.h @@ -25,7 +25,7 @@ auto EndStdStreamCapture(std::string& out, std::string& err) -> void; // that are needed when debugging. template static auto CallWithCapturedOutput(std::string& out, std::string& err, - FnT function) { + FnT function) -> auto { Internal::BeginStdStreamCapture(); auto result = function(); Internal::EndStdStreamCapture(out, err); diff --git a/testing/file_test/test_file.cpp b/testing/file_test/test_file.cpp index 742ec46f15276..a19db6db27b7d 100644 --- a/testing/file_test/test_file.cpp +++ b/testing/file_test/test_file.cpp @@ -301,7 +301,7 @@ static auto TryConsumeSplit(llvm::StringRef line, llvm::StringRef line_trimmed, // Converts a `FileCheck`-style expectation string into a single complete regex // string by escaping all regex characters outside of the designated `{{...}}` // regex sequences, and switching those to a normal regex sub-pattern syntax. -static void ConvertExpectationStringToRegex(std::string& str) { +static auto ConvertExpectationStringToRegex(std::string& str) -> void { for (int pos = 0; pos < static_cast(str.size());) { switch (str[pos]) { case '(': diff --git a/testing/file_test/test_file.h b/testing/file_test/test_file.h index fe691f08ba835..0037f57e8b549 100644 --- a/testing/file_test/test_file.h +++ b/testing/file_test/test_file.h @@ -23,7 +23,7 @@ namespace Carbon::Testing { struct TestFile { // Represents a split within the test file. struct Split { - friend void PrintTo(const Split& f, std::ostream* os) { + friend auto PrintTo(const Split& f, std::ostream* os) -> void { // Print content escaped. llvm::raw_os_ostream os_wrap(*os); os_wrap << "Split(" << f.filename << ", \"" << FormatEscaped(f.content) diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index 18e653ae06d53..c708f2e22f80a 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -79,7 +79,8 @@ static auto GetImportName(const SemIR::File& import_sem_ir, // could also be a builtin name ID which is equivalent cross-IR. static auto CopyNameFromImportIR(Context& context, const SemIR::File& import_sem_ir, - SemIR::NameId import_name_id) { + SemIR::NameId import_name_id) + -> SemIR::NameId { if (auto import_identifier_id = import_name_id.AsIdentifierId(); import_identifier_id.has_value()) { auto name = import_sem_ir.identifiers().Get(import_identifier_id); diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index 89cdd05deaa22..8d81bcc82de1a 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -72,7 +72,7 @@ class ConstantContext { // Sets the index of the constant we most recently lowered. This is used to // check we don't look at constants that we've not lowered yet. - auto SetLastLoweredConstantIndex(int32_t index) { + auto SetLastLoweredConstantIndex(int32_t index) -> void { last_lowered_constant_index_ = index; } diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index d54c8e859801f..64d6c79dad441 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -64,7 +64,7 @@ auto FunctionContext::LowerBlockContents(SemIR::InstBlockId block_id) -> void { // types, which would make getting the right overload resolution complex. template static auto LowerInstHelper(FunctionContext& context, SemIR::InstId inst_id, - InstT inst) { + InstT inst) -> void { if constexpr (!InstT::Kind.is_lowered()) { CARBON_FATAL( "Encountered an instruction that isn't expected to lower. It's " diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index 5cdacda9a3561..d0ec940d5e77f 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -62,7 +62,7 @@ class FunctionContext { } // Sets the value for the given instruction. - auto SetLocal(SemIR::InstId inst_id, llvm::Value* value) { + auto SetLocal(SemIR::InstId inst_id, llvm::Value* value) -> void { bool added = locals_.Insert(inst_id, value).is_inserted(); CARBON_CHECK(added, "Duplicate local insert: {0} {1}", inst_id, sem_ir().insts().Get(inst_id)); @@ -102,7 +102,7 @@ class FunctionContext { // Sets the instruction after static allocas. This should be called once, // after the first alloca is created. - auto SetInstructionAfterAllocas(llvm::Instruction* after_allocas) { + auto SetInstructionAfterAllocas(llvm::Instruction* after_allocas) -> void { CARBON_CHECK(!after_allocas_); after_allocas_ = after_allocas; } diff --git a/toolchain/parse/extract.cpp b/toolchain/parse/extract.cpp index c18d9a1bd6d19..adebeb9f30190 100644 --- a/toolchain/parse/extract.cpp +++ b/toolchain/parse/extract.cpp @@ -48,7 +48,9 @@ class NodeExtractor { // Saves a checkpoint of our current position so we can return later if // extraction of a child node fails. auto Checkpoint() const -> CheckpointState { return {.it = it_}; } - auto RestoreCheckpoint(CheckpointState checkpoint) { it_ = checkpoint.it; } + auto RestoreCheckpoint(CheckpointState checkpoint) -> void { + it_ = checkpoint.it; + } // Determines whether the current position matches the specified node kind. If // not, produces a suitable trace message. diff --git a/toolchain/parse/node_kind.h b/toolchain/parse/node_kind.h index 12c8899ced7e9..1ad2abbe056d5 100644 --- a/toolchain/parse/node_kind.h +++ b/toolchain/parse/node_kind.h @@ -196,7 +196,7 @@ class NodeKind::Definition : public NodeKind { // This is factored out and non-constexpr to improve the compile-time error // message if the check below fails. - auto MustSpecifyEitherBracketingNodeOrChildCount() { + auto MustSpecifyEitherBracketingNodeOrChildCount() -> void { CARBON_FATAL("Must specify either bracketing node or fixed child count."); } diff --git a/toolchain/parse/precedence.cpp b/toolchain/parse/precedence.cpp index f62c118d40a87..c81f0155d75d2 100644 --- a/toolchain/parse/precedence.cpp +++ b/toolchain/parse/precedence.cpp @@ -51,9 +51,9 @@ struct PrecedenceGroup::OperatorPriorityTable { ConsistencyCheck(); } - constexpr void MarkHigherThan( + constexpr auto MarkHigherThan( std::initializer_list higher_group, - std::initializer_list lower_group) { + std::initializer_list lower_group) -> void { for (auto higher : higher_group) { for (auto lower : lower_group) { table[higher][lower] = OperatorPriority::LeftFirst; @@ -61,7 +61,7 @@ struct PrecedenceGroup::OperatorPriorityTable { } } - constexpr void MakeTransitivelyClosed() { + constexpr auto MakeTransitivelyClosed() -> void { // A naive algorithm compiles acceptably fast for now (~0.5s). This should // be revisited if we see compile time problems after adding precedence // groups; it's easy to do this faster. @@ -85,7 +85,7 @@ struct PrecedenceGroup::OperatorPriorityTable { } while (changed); } - constexpr void MakeSymmetric() { + constexpr auto MakeSymmetric() -> void { for (int8_t a = 0; a != NumPrecedenceLevels; ++a) { for (int8_t b = 0; b != NumPrecedenceLevels; ++b) { if (table[a][b] == OperatorPriority::LeftFirst) { @@ -97,7 +97,7 @@ struct PrecedenceGroup::OperatorPriorityTable { } } - constexpr void AddAssociativityRules() { + constexpr auto AddAssociativityRules() -> void { // Associativity rules occupy the diagonal // For prefix operators, RightFirst would mean `@@x` is `@(@x)` and @@ -122,7 +122,7 @@ struct PrecedenceGroup::OperatorPriorityTable { // For other operators, we require explicit parentheses. } - constexpr void ConsistencyCheck() { + constexpr auto ConsistencyCheck() -> void { for (int8_t level = 0; level != NumPrecedenceLevels; ++level) { if (level != Highest) { CARBON_CHECK(table[Highest][level] == OperatorPriority::LeftFirst && diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index fff6f9cc88a93..1afbca504a65a 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -251,7 +251,7 @@ class Inst : public Printable { auto SetType(TypeId type_id) -> void { type_id_ = type_id; } // Sets the arguments of this instruction. - auto SetArgs(int32_t arg0, int32_t arg1) { + auto SetArgs(int32_t arg0, int32_t arg1) -> void { arg0_ = arg0; arg1_ = arg1; } From 961f20e859da2947c6bfdd503a947b75ba591a62 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 24 Feb 2025 15:20:08 -0800 Subject: [PATCH 15/56] Make FileTest run tests async by default (#4991) This takes the mechanism currently used for autoupdate and expands it to the regular tests (deliberately trying to unify logic for test/autoupdate/dump to deliver consistent behavior). I'm seeing about a 85% reduction in test time, though results will vary based on test system. This does some small edits to test output to make it fit better with the new flow. Note I'm stopping printing of the "here's how to run" on every test by default, since it's autoupdated into file content by default. However, it's still there for test failures. --------- Co-authored-by: Geoff Romer --- explorer/file_test.cpp | 7 +- testing/file_test/BUILD | 1 + testing/file_test/autoupdate_testdata.sh | 2 +- testing/file_test/file_test_base.cpp | 389 +++++++++++++--------- testing/file_test/file_test_base.h | 40 +-- testing/file_test/file_test_base_test.cpp | 5 +- testing/file_test/rules.bzl | 3 + toolchain/testing/BUILD | 2 - toolchain/testing/file_test.cpp | 5 +- 9 files changed, 263 insertions(+), 191 deletions(-) diff --git a/explorer/file_test.cpp b/explorer/file_test.cpp index e7dec0ef20735..a255d26b85f7d 100644 --- a/explorer/file_test.cpp +++ b/explorer/file_test.cpp @@ -19,8 +19,8 @@ namespace { class ExplorerFileTest : public FileTestBase { public: explicit ExplorerFileTest(llvm::StringRef /*exe_path*/, - std::mutex* output_mutex, llvm::StringRef test_name) - : FileTestBase(output_mutex, test_name), + llvm::StringRef test_name) + : FileTestBase(test_name), prelude_line_re_(R"(prelude.carbon:(\d+))"), timing_re_(R"((Time elapsed in \w+: )\d+(ms))") { CARBON_CHECK(prelude_line_re_.ok(), "{0}", prelude_line_re_.error()); @@ -96,6 +96,9 @@ class ExplorerFileTest : public FileTestBase { } } + // Cannot execute in parallel. + auto AllowParallelRun() const -> bool override { return false; } + private: // Trace output is directly checked for a few tests. auto check_trace_output() -> bool { diff --git a/testing/file_test/BUILD b/testing/file_test/BUILD index 26b14eb9723d8..db3e9d72d3586 100644 --- a/testing/file_test/BUILD +++ b/testing/file_test/BUILD @@ -48,6 +48,7 @@ cc_library( "//testing/base:file_helpers", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/flags:parse", + "@abseil-cpp//absl/strings", "@googletest//:gtest", "@llvm-project//llvm:Support", ], diff --git a/testing/file_test/autoupdate_testdata.sh b/testing/file_test/autoupdate_testdata.sh index e3bca94919afe..0014b424dea02 100755 --- a/testing/file_test/autoupdate_testdata.sh +++ b/testing/file_test/autoupdate_testdata.sh @@ -5,6 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception "$(dirname "$0")/../../scripts/run_bazel.py" \ - run -c opt --experimental_convenience_symlinks=ignore \ + run --experimental_convenience_symlinks=ignore \ --ui_event_filters=-info,-stdout,-stderr,-finish \ //testing/file_test:file_test_base_test -- --autoupdate "$@" diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index f418bd5c2d96e..a8ad338b930b7 100644 --- a/testing/file_test/file_test_base.cpp +++ b/testing/file_test/file_test_base.cpp @@ -2,6 +2,23 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Implementation-wise, this: +// +// - Uses the registered `FileTestFactory` to construct `FileTestBase` +// instances. +// - Constructs a `FileTestCase` that wraps each `FileTestBase` instance to +// register with googletest, and to provide the actual `TestBody`. +// - Using `FileTestEventListener`, runs tests in parallel prior to normal +// googletest execution. +// - This is required to support `--gtest_filter` and access `should_run`. +// - Runs each `FileTestBase` instance to cache the `TestFile` on +// `FileTestInfo`. +// - Determines whether autoupdate would make changes, autoupdating if +// requested. +// - When googletest would normally execute the test, `FileTestCase::TestBody` +// instead uses the cached state on `FileTestInfo`. +// - This only occurs when neither autoupdating nor dumping output. + #include "testing/file_test/file_test_base.h" #include @@ -11,6 +28,8 @@ #include "absl/flags/flag.h" #include "absl/flags/parse.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_split.h" #include "common/check.h" #include "common/error.h" #include "common/exe_path.h" @@ -30,7 +49,8 @@ ABSL_FLAG(std::vector, file_tests, {}, "A comma-separated list of repo-relative names of test files. " - "Overrides test_targets_file."); + "Similar to and overrides `--gtest_filter`, but doesn't require the " + "test class name to be known."); ABSL_FLAG(std::string, test_targets_file, "", "A path to a file containing repo-relative names of test files."); ABSL_FLAG(bool, autoupdate, false, @@ -45,6 +65,39 @@ ABSL_FLAG(bool, dump_output, false, namespace Carbon::Testing { +// Information for a test case. +struct FileTestInfo { + // The name. + std::string test_name; + + // A factory function for creating the test object. + std::functionFileTestBase*> factory_fn; + + // gtest's information about the test. + ::testing::TestInfo* registered_test; + + // The test result, set after running. + std::optional> test_result; + + // Whether running autoupdate would change (or when autoupdating, already + // changed) the test file. This may be true even if output passes test + // expectations. + bool autoupdate_differs = false; +}; + +// Adapts a `FileTestBase` instance to gtest for outputting results. +class FileTestCase : public testing::Test { + public: + explicit FileTestCase(FileTestInfo* test_info) : test_info_(test_info) {} + + // Runs a test and compares output. This keeps output split by line so that + // issues are a little easier to identify by the different line. + auto TestBody() -> void final; + + private: + FileTestInfo* test_info_; +}; + // Splits outputs to string_view because gtest handles string_view by default. static auto SplitOutput(llvm::StringRef output) -> llvm::SmallVector { @@ -144,28 +197,27 @@ static auto RunAutoupdater(FileTestBase* test_base, const TestFile& test_file, .Run(dry_run); } -// Runs a test and compares output. This keeps output split by line so that -// issues are a little easier to identify by the different line. -auto FileTestBase::TestBody() -> void { - // Add a crash trace entry with the single-file test command. - std::string test_command = GetBazelCommand(BazelMode::Test, test_name_); - llvm::PrettyStackTraceString stack_trace_entry(test_command.c_str()); - llvm::errs() << "\nTo test this file alone, run:\n " << test_command - << "\n\n"; - - ErrorOr test_file = - ProcessTestFileAndRun(this, output_mutex_, /*dump_output=*/false, - absl::GetFlag(FLAGS_autoupdate)); - ASSERT_TRUE(test_file.ok()) << test_file.error(); - auto test_filename = std::filesystem::path(test_name_.str()).filename(); +auto FileTestCase::TestBody() -> void { + if (absl::GetFlag(FLAGS_autoupdate) || absl::GetFlag(FLAGS_dump_output)) { + return; + } + + CARBON_CHECK(test_info_->test_result, + "Expected test to be run prior to TestBody: {0}", + test_info_->test_name); + + ASSERT_TRUE(test_info_->test_result->ok()) + << test_info_->test_result->error(); + auto test_filename = std::filesystem::path(test_info_->test_name).filename(); // Check success/failure against `fail_` prefixes. - if (test_file->run_result.per_file_success.empty()) { - CompareFailPrefix(test_filename.string(), test_file->run_result.success); + TestFile& test_file = **(test_info_->test_result); + if (test_file.run_result.per_file_success.empty()) { + CompareFailPrefix(test_filename.string(), test_file.run_result.success); } else { bool require_overall_failure = false; for (const auto& [filename, success] : - test_file->run_result.per_file_success) { + test_file.run_result.per_file_success) { CompareFailPrefix(filename, success); if (!success) { require_overall_failure = true; @@ -173,76 +225,50 @@ auto FileTestBase::TestBody() -> void { } if (require_overall_failure) { - EXPECT_FALSE(test_file->run_result.success) + EXPECT_FALSE(test_file.run_result.success) << "There is a per-file failure expectation, so the overall result " "should have been a failure."; } else { // Individual files all succeeded, so the prefix is enforced on the main // test file. - CompareFailPrefix(test_filename.string(), test_file->run_result.success); + CompareFailPrefix(test_filename.string(), test_file.run_result.success); } } - // Check results. Include a reminder of the autoupdate command for any - // stdout/stderr differences. - std::string update_message; - if (test_file->autoupdate_line_number) { - update_message = llvm::formatv( - "If these differences are expected, try the autoupdater:\n {0}", - GetBazelCommand(BazelMode::Autoupdate, test_name_)); - } else { - update_message = - "If these differences are expected, content must be updated manually."; + // Check results. Include a reminder for NOAUTOUPDATE tests. + std::unique_ptr scoped_trace; + if (!test_file.autoupdate_line_number) { + scoped_trace = std::make_unique( + __FILE__, __LINE__, + "This file is NOAUTOUPDATE, so expected differences require manual " + "updates."); } - SCOPED_TRACE(update_message); - if (test_file->check_subset) { - EXPECT_THAT(SplitOutput(test_file->actual_stdout), - IsSupersetOf(test_file->expected_stdout)); - EXPECT_THAT(SplitOutput(test_file->actual_stderr), - IsSupersetOf(test_file->expected_stderr)); + if (test_file.check_subset) { + EXPECT_THAT(SplitOutput(test_file.actual_stdout), + IsSupersetOf(test_file.expected_stdout)); + EXPECT_THAT(SplitOutput(test_file.actual_stderr), + IsSupersetOf(test_file.expected_stderr)); } else { - EXPECT_THAT(SplitOutput(test_file->actual_stdout), - ElementsAreArray(test_file->expected_stdout)); - EXPECT_THAT(SplitOutput(test_file->actual_stderr), - ElementsAreArray(test_file->expected_stderr)); + EXPECT_THAT(SplitOutput(test_file.actual_stdout), + ElementsAreArray(test_file.expected_stdout)); + EXPECT_THAT(SplitOutput(test_file.actual_stderr), + ElementsAreArray(test_file.expected_stderr)); } - // If there are no other test failures, check if autoupdate would make - // changes. We don't do this when there _are_ failures because the - // SCOPED_TRACE already contains the autoupdate reminder. - if (!HasFailure() && RunAutoupdater(this, *test_file, /*dry_run=*/true)) { - ADD_FAILURE() << "Autoupdate would make changes to the file content."; + if (HasFailure()) { + llvm::errs() << "\nTo test this file alone, run:\n " + << GetBazelCommand(BazelMode::Test, test_info_->test_name) + << "\n\n"; + if (test_file.autoupdate_line_number) { + llvm::errs() << "\nThis test is NOAUTOUPDATE.\n\n"; + } + } + if (test_info_->autoupdate_differs) { + ADD_FAILURE() << "Autoupdate would make changes to the file content. Run:\n" + << GetBazelCommand(BazelMode::Autoupdate, + test_info_->test_name); } -} - -auto FileTestBase::Autoupdate() -> ErrorOr { - // Add a crash trace entry mentioning which file we're updating. - std::string stack_trace_string = - llvm::formatv("performing autoupdate for {0}", test_name_); - llvm::PrettyStackTraceString stack_trace_entry(stack_trace_string.c_str()); - - CARBON_ASSIGN_OR_RETURN( - TestFile test_file, - ProcessTestFileAndRun(this, output_mutex_, /*dump_output=*/false, - absl::GetFlag(FLAGS_autoupdate))); - return RunAutoupdater(this, test_file, /*dry_run=*/false); -} - -auto FileTestBase::DumpOutput() -> ErrorOr { - std::string banner(79, '='); - banner.append("\n"); - llvm::errs() << banner << "= " << test_name_ << "\n"; - - CARBON_ASSIGN_OR_RETURN( - TestFile test_file, - ProcessTestFileAndRun(this, output_mutex_, /*dump_output=*/true, - absl::GetFlag(FLAGS_autoupdate))); - llvm::errs() << banner << test_file.actual_stdout << banner - << "= Exit with success: " - << (test_file.run_result.success ? "true" : "false") << "\n" - << banner; - return Success(); } auto FileTestBase::GetLineNumberReplacements( @@ -254,48 +280,91 @@ auto FileTestBase::GetLineNumberReplacements( .line_formatv = R"({0})"}}; } -// Returns the tests to run. -static auto GetTests() -> llvm::SmallVector { - // Prefer a user-specified list if present. - auto specific_tests = absl::GetFlag(FLAGS_file_tests); - if (!specific_tests.empty()) { - return llvm::SmallVector(specific_tests.begin(), - specific_tests.end()); +// If `--file_tests` is set, transform it into a `--gtest_filter`. +static auto MaybeApplyFileTestsFlag(llvm::StringRef factory_name) -> void { + if (absl::GetFlag(FLAGS_file_tests).empty()) { + return; + } + RawStringOstream filter; + llvm::ListSeparator sep(":"); + for (const auto& file : absl::GetFlag(FLAGS_file_tests)) { + filter << sep << factory_name << "." << file; } + absl::SetFlag(&FLAGS_gtest_filter, filter.TakeStr()); +} - // Extracts tests from the target file. - CARBON_CHECK(!absl::GetFlag(FLAGS_test_targets_file).empty(), - "Missing --test_targets_file."); - auto content = ReadFile(absl::GetFlag(FLAGS_test_targets_file)); - CARBON_CHECK(content.ok(), "{0}", content.error()); - llvm::SmallVector all_tests; - for (llvm::StringRef file_ref : llvm::split(*content, "\n")) { - if (file_ref.empty()) { - continue; - } - all_tests.push_back(file_ref.str()); +// Loads tests from the manifest file, and registers them for execution. The +// vector is taken as an output parameter so that the address of entries is +// stable for the factory. +static auto RegisterTests(FileTestFactory* test_factory, + llvm::StringRef exe_path, + llvm::SmallVectorImpl& tests) + -> ErrorOr { + if (absl::GetFlag(FLAGS_test_targets_file).empty()) { + return Error("Missing --test_targets_file."); + } + CARBON_ASSIGN_OR_RETURN(auto test_manifest, + ReadFile(absl::GetFlag(FLAGS_test_targets_file))); + + // Prepare the vector first, so that the location of entries won't change. + for (const auto& test_name : + absl::StrSplit(test_manifest, "\n", absl::SkipEmpty())) { + tests.push_back({.test_name = std::string(test_name)}); + } + + // Amend entries with factory functions. + for (auto& test : tests) { + llvm::StringRef test_name = test.test_name; + test.factory_fn = [test_factory, exe_path, test_name]() { + return test_factory->factory_fn(exe_path, test_name); + }; + test.registered_test = testing::RegisterTest( + test_factory->name, test_name.data(), nullptr, test_name.data(), + __FILE__, __LINE__, [&test]() { return new FileTestCase(&test); }); } - return all_tests; + return Success(); } -// Runs autoupdate for the given tests. This is multi-threaded to try to get a -// little extra speed. -static auto RunAutoupdate(llvm::StringRef exe_path, - llvm::ArrayRef tests, - FileTestFactory& test_factory) -> int { +// Implements the parallel test execution through gtest's listener support. +class FileTestEventListener : public testing::EmptyTestEventListener { + public: + explicit FileTestEventListener(llvm::MutableArrayRef tests) + : tests_(tests) {} + + // Runs test during start, after `should_run` is initialized. This is + // multi-threaded to get extra speed. + auto OnTestProgramStart(const testing::UnitTest& /*unit_test*/) + -> void override; + + private: + llvm::MutableArrayRef tests_; +}; + +auto FileTestEventListener::OnTestProgramStart( + const testing::UnitTest& /*unit_test*/) -> void { llvm::CrashRecoveryContext::Enable(); llvm::DefaultThreadPool pool( - {.ThreadsRequested = absl::GetFlag(FLAGS_threads)}); + {.ThreadsRequested = absl::GetFlag(FLAGS_dump_output) + ? 1 + : absl::GetFlag(FLAGS_threads)}); + if (!absl::GetFlag(FLAGS_dump_output)) { + llvm::errs() << "Running tests with " << pool.getMaxConcurrency() + << " thread(s)\n"; + } // Guard access to both `llvm::errs` and `crashed`. - std::mutex mutex; bool crashed = false; + std::mutex output_mutex; + + for (auto& test : tests_) { + if (!test.registered_test->should_run()) { + continue; + } - for (const auto& test_name : tests) { - pool.async([&test_factory, &mutex, &exe_path, &crashed, test_name] { + pool.async([&output_mutex, &crashed, &test] { // If any thread crashed, don't try running more. { - std::unique_lock lock(mutex); + std::unique_lock lock(output_mutex); if (crashed) { return; } @@ -307,19 +376,46 @@ static auto RunAutoupdate(llvm::StringRef exe_path, llvm::CrashRecoveryContext crc; crc.DumpStackAndCleanupOnFailure = true; bool thread_crashed = !crc.RunSafely([&] { - std::unique_ptr test( - test_factory.factory_fn(exe_path, &mutex, test_name)); - auto result = test->Autoupdate(); + std::unique_ptr test_instance(test.factory_fn()); + + // Add a crash trace entry with the single-file test command. + std::string test_command = + GetBazelCommand(BazelMode::Test, test.test_name); + llvm::PrettyStackTraceString stack_trace_entry(test_command.c_str()); + + if (absl::GetFlag(FLAGS_dump_output)) { + std::unique_lock lock(output_mutex); + llvm::errs() << "\n--- Dumping: " << test.test_name << "\n\n"; + } + + test.test_result = ProcessTestFileAndRun( + test_instance.get(), &output_mutex, + absl::GetFlag(FLAGS_dump_output), absl::GetFlag(FLAGS_autoupdate)); + + if (!test.test_result->ok()) { + std::unique_lock lock(output_mutex); + llvm::errs() << "\n" << test.test_result->error().message() << "\n"; + return; + } - std::unique_lock lock(mutex); - if (result.ok()) { - llvm::errs() << (*result ? "!" : "."); + test.autoupdate_differs = + RunAutoupdater(test_instance.get(), **test.test_result, + /*dry_run=*/!absl::GetFlag(FLAGS_autoupdate)); + + std::unique_lock lock(output_mutex); + if (absl::GetFlag(FLAGS_dump_output)) { + llvm::outs().flush(); + const TestFile& test_file = **test.test_result; + llvm::errs() << "\n--- Exit with success: " + << (test_file.run_result.success ? "true" : "false") + << "\n--- Autoupdate differs: " + << (test.autoupdate_differs ? "true" : "false") << "\n"; } else { - llvm::errs() << "\n" << result.error().message() << "\n"; + llvm::errs() << (test.autoupdate_differs ? "!" : "."); } }); if (thread_crashed) { - std::unique_lock lock(mutex); + std::unique_lock lock(output_mutex); crashed = true; } }); @@ -332,23 +428,21 @@ static auto RunAutoupdate(llvm::StringRef exe_path, std::abort(); } llvm::errs() << "\nDone!\n"; - return EXIT_SUCCESS; } // Implements main() within the Carbon::Testing namespace for convenience. -static auto Main(int argc, char** argv) -> int { +static auto Main(int argc, char** argv) -> ErrorOr { Carbon::InitLLVM init_llvm(argc, argv); testing::InitGoogleTest(&argc, argv); auto args = absl::ParseCommandLine(argc, argv); if (args.size() > 1) { - llvm::errs() << "Unexpected arguments:"; + ErrorBuilder b; + b << "Unexpected arguments:"; for (char* arg : llvm::ArrayRef(args).drop_front()) { - llvm::errs() << " "; - llvm::errs().write_escaped(arg); + b << " " << FormatEscaped(arg); } - llvm::errs() << "\n"; - return EXIT_FAILURE; + return b; } std::string exe_path = FindExecutablePath(argv[0]); @@ -358,51 +452,44 @@ static auto Main(int argc, char** argv) -> int { // on Windows, but POSIX requires it to be 0. if (std::error_code error = llvm::sys::Process::SafelyCloseFileDescriptor(0)) { - llvm::errs() << "Unable to close standard input: " << error.message() - << "\n"; - return EXIT_FAILURE; + return Error("Unable to close standard input: " + error.message()); } if (std::error_code error = llvm::sys::Process::FixupStandardFileDescriptors()) { - llvm::errs() << "Unable to correct standard file descriptors: " - << error.message() << "\n"; - return EXIT_FAILURE; + return Error("Unable to correct standard file descriptors: " + + error.message()); } if (absl::GetFlag(FLAGS_autoupdate) && absl::GetFlag(FLAGS_dump_output)) { - llvm::errs() << "--autoupdate and --dump_output are mutually exclusive.\n"; - return EXIT_FAILURE; + return Error("--autoupdate and --dump_output are mutually exclusive."); } - llvm::SmallVector tests = GetTests(); auto test_factory = GetFileTestFactory(); - if (absl::GetFlag(FLAGS_autoupdate)) { - return RunAutoupdate(exe_path, tests, test_factory); - } else if (absl::GetFlag(FLAGS_dump_output)) { - for (const auto& test_name : tests) { - std::unique_ptr test( - test_factory.factory_fn(exe_path, nullptr, test_name)); - auto result = test->DumpOutput(); - if (!result.ok()) { - llvm::errs() << "\n" << result.error().message() << "\n"; - } - } - llvm::errs() << "\nDone!\n"; - return EXIT_SUCCESS; - } else { - for (const std::string& test_name : tests) { - testing::RegisterTest( - test_factory.name, test_name.c_str(), nullptr, test_name.c_str(), - __FILE__, __LINE__, - [&test_factory, &exe_path, test_name = test_name]() { - return test_factory.factory_fn(exe_path, nullptr, test_name); - }); - } - return RUN_ALL_TESTS(); + + MaybeApplyFileTestsFlag(test_factory.name); + + // Inline 0 entries because it will always be too large to store on the stack. + llvm::SmallVector tests; + CARBON_RETURN_IF_ERROR(RegisterTests(&test_factory, exe_path, tests)); + + testing::TestEventListeners& listeners = + testing::UnitTest::GetInstance()->listeners(); + if (absl::GetFlag(FLAGS_autoupdate) || absl::GetFlag(FLAGS_dump_output)) { + // Suppress all of the default output. + delete listeners.Release(listeners.default_result_printer()); } + // Use a listener to run tests in parallel. + listeners.Append(new FileTestEventListener(tests)); + + return RUN_ALL_TESTS(); } } // namespace Carbon::Testing auto main(int argc, char** argv) -> int { - return Carbon::Testing::Main(argc, argv); + if (auto result = Carbon::Testing::Main(argc, argv); result.ok()) { + return *result; + } else { + llvm::errs() << result.error() << "\n"; + return EXIT_FAILURE; + } } diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index 7e9890d69d65e..390452ab0f690 100644 --- a/testing/file_test/file_test_base.h +++ b/testing/file_test/file_test_base.h @@ -23,7 +23,7 @@ namespace Carbon::Testing { // A framework for testing files. See README.md for documentation. -class FileTestBase : public testing::Test { +class FileTestBase { public: // Provided for child class convenience. using LineNumberReplacement = FileTestAutoupdater::LineNumberReplacement; @@ -52,8 +52,8 @@ class FileTestBase : public testing::Test { llvm::SmallVector> per_file_success; }; - explicit FileTestBase(std::mutex* output_mutex, llvm::StringRef test_name) - : output_mutex_(output_mutex), test_name_(test_name) {} + explicit FileTestBase(llvm::StringRef test_name) : test_name_(test_name) {} + virtual ~FileTestBase() = default; // Implemented by children to run the test. The framework will validate the // content written to `output_stream` and `error_stream`. Children should use @@ -105,25 +105,10 @@ class FileTestBase : public testing::Test { // run. virtual auto AllowParallelRun() const -> bool { return true; } - // Runs a test and compares output. This keeps output split by line so that - // issues are a little easier to identify by the different line. - auto TestBody() -> void final; - - // Runs the test and autoupdates checks. Returns true if updated. - auto Autoupdate() -> ErrorOr; - - // Runs the test and dumps output. - auto DumpOutput() -> ErrorOr; - // Returns the name of the test (relative to the repo root). auto test_name() const -> llvm::StringRef { return test_name_; } private: - // An optional mutex for output. If provided, it will be locked during `Run` - // when stderr/stdout are being captured (SET-CAPTURE-CONSOLE-OUTPUT), in - // order to avoid output conflicts. - std::mutex* output_mutex_; - llvm::StringRef test_name_; }; @@ -132,11 +117,9 @@ struct FileTestFactory { // The test fixture name. const char* name; - // A factory function for tests. The output_mutex is optional; see - // `FileTestBase::output_mutex_`. - std::functionFileTestBase*> + // A factory function for tests. + std::function< + auto(llvm::StringRef exe_path, llvm::StringRef test_name)->FileTestBase*> factory_fn; }; @@ -151,12 +134,11 @@ struct FileTestFactory { extern auto GetFileTestFactory() -> FileTestFactory; // Provides a standard GetFileTestFactory implementation. -#define CARBON_FILE_TEST_FACTORY(Name) \ - auto GetFileTestFactory() -> FileTestFactory { \ - return {#Name, [](llvm::StringRef exe_path, std::mutex* output_mutex, \ - llvm::StringRef test_name) { \ - return new Name(exe_path, output_mutex, test_name); \ - }}; \ +#define CARBON_FILE_TEST_FACTORY(Name) \ + auto GetFileTestFactory() -> FileTestFactory { \ + return {#Name, [](llvm::StringRef exe_path, llvm::StringRef test_name) { \ + return new Name(exe_path, test_name); \ + }}; \ } } // namespace Carbon::Testing diff --git a/testing/file_test/file_test_base_test.cpp b/testing/file_test/file_test_base_test.cpp index 37d2f5d56b039..5a4ae5edaca8c 100644 --- a/testing/file_test/file_test_base_test.cpp +++ b/testing/file_test/file_test_base_test.cpp @@ -17,9 +17,8 @@ namespace { class FileTestBaseTest : public FileTestBase { public: - FileTestBaseTest(llvm::StringRef /*exe_path*/, std::mutex* output_mutex, - llvm::StringRef test_name) - : FileTestBase(output_mutex, test_name) {} + FileTestBaseTest(llvm::StringRef /*exe_path*/, llvm::StringRef test_name) + : FileTestBase(test_name) {} auto Run(const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, diff --git a/testing/file_test/rules.bzl b/testing/file_test/rules.bzl index e7daea2f976ad..5bdc721bcabef 100644 --- a/testing/file_test/rules.bzl +++ b/testing/file_test/rules.bzl @@ -9,6 +9,7 @@ a file which can be accessed as a list. This avoids long argument parsing. """ load("@rules_cc//cc:defs.bzl", "cc_test") +load("//bazel/cc_toolchains:defs.bzl", "cc_env") load("//bazel/manifest:defs.bzl", "manifest") def file_test( @@ -50,6 +51,7 @@ def file_test( srcs = [prebuilt_binary], data = data, args = args, + env = cc_env(), **kwargs ) else: @@ -57,5 +59,6 @@ def file_test( name = name, data = data, args = args, + env = cc_env(), **kwargs ) diff --git a/toolchain/testing/BUILD b/toolchain/testing/BUILD index c3ab3e713e0f8..50ecc2049ed96 100644 --- a/toolchain/testing/BUILD +++ b/toolchain/testing/BUILD @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load("//bazel/cc_toolchains:defs.bzl", "cc_env") load("//testing/file_test:rules.bzl", "file_test") package(default_visibility = ["//visibility:public"]) @@ -55,7 +54,6 @@ file_test( size = "small", timeout = "moderate", # Taking >60 seconds in GitHub actions srcs = ["file_test.cpp"], - env = cc_env(), tests = [":all_testdata"], deps = [ "//common:all_llvm_targets", diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 3fb8a36524b84..77f44eea40c5e 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -23,7 +23,7 @@ namespace { // component subdirectories. class ToolchainFileTest : public FileTestBase { public: - explicit ToolchainFileTest(llvm::StringRef exe_path, std::mutex* output_mutex, + explicit ToolchainFileTest(llvm::StringRef exe_path, llvm::StringRef test_name); // Adds a replacement for `core_package_dir`. @@ -89,9 +89,8 @@ static auto GetComponent(llvm::StringRef test_name) -> llvm::StringRef { } ToolchainFileTest::ToolchainFileTest(llvm::StringRef exe_path, - std::mutex* output_mutex, llvm::StringRef test_name) - : FileTestBase(output_mutex, test_name), + : FileTestBase(test_name), component_(GetComponent(test_name)), installation_(InstallPaths::MakeForBazelRunfiles(exe_path)) {} From de0cab1e660250d60c882ec35866accd658c0b34 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 24 Feb 2025 18:05:07 -0800 Subject: [PATCH 16/56] Move ChoiceDeferredBinding for style (#5002) https://google.github.io/styleguide/cppguide.html#Declaration_Order says types go first. Also moving the accessor to match the order of members (`choice_deferred_bindings_` was added between `var_storage_map_` and `region_stack_`). --- toolchain/check/context.h | 50 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/toolchain/check/context.h b/toolchain/check/context.h index c3d4b625995eb..bd9a5b71ab968 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -55,20 +55,6 @@ class Context { // add contextual notes as appropriate. using BuildDiagnosticFn = llvm::function_refDiagnosticBuilder>; - // Pre-computed parts of a binding pattern. - struct BindingPatternInfo { - // The corresponding AnyBindName inst. - SemIR::InstId bind_name_id; - // The region of insts that computes the type of the binding. - SemIR::ExprRegionId type_expr_region_id; - }; - - // An ongoing impl lookup, used to ensure termination. - struct ImplLookupStackEntry { - SemIR::ConstantId type_const_id; - SemIR::ConstantId interface_const_id; - }; - // Stores references for work. explicit Context(DiagnosticEmitter* emitter, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, @@ -179,8 +165,15 @@ class Context { return import_ref_ids_; } + // Pre-computed parts of a binding pattern. // TODO: Consider putting this behind a narrower API to guard against emitting // multiple times. + struct BindingPatternInfo { + // The corresponding AnyBindName inst. + SemIR::InstId bind_name_id; + // The region of insts that computes the type of the binding. + SemIR::ExprRegionId type_expr_region_id; + }; auto bind_name_map() -> Map& { return bind_name_map_; } @@ -189,8 +182,25 @@ class Context { return var_storage_map_; } + // During Choice typechecking, each alternative turns into a name binding on + // the Choice type, but this can't be done until the full Choice type is + // known. This represents each binding to be done at the end of checking the + // Choice type. + struct ChoiceDeferredBinding { + Parse::NodeId node_id; + NameComponent name_component; + }; + auto choice_deferred_bindings() -> llvm::SmallVector& { + return choice_deferred_bindings_; + } + auto region_stack() -> RegionStack& { return region_stack_; } + // An ongoing impl lookup, used to ensure termination. + struct ImplLookupStackEntry { + SemIR::ConstantId type_const_id; + SemIR::ConstantId interface_const_id; + }; auto impl_lookup_stack() -> llvm::SmallVector& { return impl_lookup_stack_; } @@ -262,18 +272,6 @@ class Context { // End of SemIR::File members. // -------------------------------------------------------------------------- - // During Choice typechecking, each alternative turns into a name binding on - // the Choice type, but this can't be done until the full Choice type is - // known. This represents each binding to be done at the end of checking the - // Choice type. - struct ChoiceDeferredBinding { - Parse::NodeId node_id; - NameComponent name_component; - }; - auto choice_deferred_bindings() -> llvm::SmallVector& { - return choice_deferred_bindings_; - } - private: // Handles diagnostics. DiagnosticEmitter* emitter_; From 197e7841401a3daec02cfddd0282eafc223a7c64 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 24 Feb 2025 18:07:10 -0800 Subject: [PATCH 17/56] Add parsing for partial types (#5009) --- toolchain/check/handle_operator.cpp | 5 +++++ toolchain/parse/node_kind.def | 1 + toolchain/parse/precedence.cpp | 2 ++ .../parse/testdata/operators/prefix.carbon | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/toolchain/check/handle_operator.cpp b/toolchain/check/handle_operator.cpp index 403fbc3ab750f..ada2c8c88293a 100644 --- a/toolchain/check/handle_operator.cpp +++ b/toolchain/check/handle_operator.cpp @@ -300,6 +300,11 @@ auto HandleParseNode(Context& context, Parse::PrefixOperatorNotId node_id) return true; } +auto HandleParseNode(Context& context, Parse::PrefixOperatorPartialId node_id) + -> bool { + return context.TODO(node_id, "partial operator"); +} + auto HandleParseNode(Context& context, Parse::PrefixOperatorPlusPlusId node_id) -> bool { return HandleUnaryOperator(context, node_id, {"Inc"}); diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index 1ff2fc68d40cc..bf54e99969a20 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -244,6 +244,7 @@ CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Const) CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Not) CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Minus) CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(MinusMinus) +CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Partial) CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(PlusPlus) CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Star) diff --git a/toolchain/parse/precedence.cpp b/toolchain/parse/precedence.cpp index c81f0155d75d2..7500232a58352 100644 --- a/toolchain/parse/precedence.cpp +++ b/toolchain/parse/precedence.cpp @@ -164,6 +164,7 @@ auto PrecedenceGroup::ForLeading(Lex::TokenKind kind) return PrecedenceGroup(If); case Lex::TokenKind::Const: + case Lex::TokenKind::Partial: return PrecedenceGroup(TypePrefix); default: @@ -243,6 +244,7 @@ auto PrecedenceGroup::ForTrailing(Lex::TokenKind kind, bool infix) case Lex::TokenKind::Const: case Lex::TokenKind::MinusMinus: case Lex::TokenKind::Not: + case Lex::TokenKind::Partial: case Lex::TokenKind::PlusPlus: break; diff --git a/toolchain/parse/testdata/operators/prefix.carbon b/toolchain/parse/testdata/operators/prefix.carbon index 29d1f295ba748..f3d372ba06469 100644 --- a/toolchain/parse/testdata/operators/prefix.carbon +++ b/toolchain/parse/testdata/operators/prefix.carbon @@ -11,6 +11,9 @@ var n: i8 = -n; var b: bool = not true; +var c: const bool; +var d: partial C*; + // CHECK:STDOUT: - filename: prefix.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, @@ -32,5 +35,20 @@ var b: bool = not true; // CHECK:STDOUT: {kind: 'BoolLiteralTrue', text: 'true'}, // CHECK:STDOUT: {kind: 'PrefixOperatorNot', text: 'not', subtree_size: 2}, // CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'c'}, +// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'}, +// CHECK:STDOUT: {kind: 'PrefixOperatorConst', text: 'const', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'd'}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'C'}, +// CHECK:STDOUT: {kind: 'PrefixOperatorPartial', text: 'partial', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'PostfixOperatorStar', text: '*', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 8}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] From e7b68572fa242d34c0b0db12b950e95631ada351 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 24 Feb 2025 18:07:43 -0800 Subject: [PATCH 18/56] Consolidate post-check logic (#5003) Right now, some post-run logic is does in `Run()` (`CheckRequiredDefinitions();` and `context_.sem_ir().set_has_errors(unit_and_imports_->err_tracker.seen_error());`) whereas other parts are done by `Finalize`. Noting the goal to move things off `Context`, this consolidates into a new `FinishRun`. Note #4962 is adding another bit of post-run that can be consolidated in; this seems likely to keep growing slowly. Note this also creates more parity with mutation source, like the `context_.scope_stack().Pop();` matches the push done by `CheckUnit::ImportCurrentPackage` and `context_.inst_block_stack().Pop()` was pushed in `CheckUnit::Run()`. Also makes `exports()` more consistent with other Context APIs. Makes `VerifyOnFinish` `const` so that it can't accidentally mutate state, and is instead only validating that the Context is in its expected configuration at completion. --- toolchain/check/check_unit.cpp | 39 +++++++++++++--------- toolchain/check/check_unit.h | 12 ++++--- toolchain/check/context.cpp | 20 ++++------- toolchain/check/context.h | 9 ++--- toolchain/check/decl_name_stack.cpp | 2 +- toolchain/check/handle_export.cpp | 2 +- toolchain/check/param_and_arg_refs_stack.h | 2 +- toolchain/check/scope_stack.cpp | 2 +- toolchain/check/scope_stack.h | 2 +- 9 files changed, 46 insertions(+), 44 deletions(-) diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index b7ff88304a00e..5854a5091ed8b 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -76,22 +76,7 @@ auto CheckUnit::Run() -> void { return; } - CheckRequiredDefinitions(); - - CheckRequiredDeclarations(); - - context_.Finalize(); - - context_.VerifyOnFinish(); - - context_.sem_ir().set_has_errors(unit_and_imports_->err_tracker.seen_error()); - -#ifndef NDEBUG - if (auto verify = context_.sem_ir().Verify(); !verify.ok()) { - CARBON_FATAL("{0}Built invalid semantics IR: {1}\n", context_.sem_ir(), - verify.error()); - } -#endif + FinishRun(); } auto CheckUnit::InitPackageScopeAndImports() -> void { @@ -505,4 +490,26 @@ auto CheckUnit::CheckRequiredDefinitions() -> void { } } +auto CheckUnit::FinishRun() -> void { + CheckRequiredDeclarations(); + CheckRequiredDefinitions(); + + // Pop information for the file-level scope. + context_.sem_ir().set_top_inst_block_id(context_.inst_block_stack().Pop()); + context_.scope_stack().Pop(); + + // Finalizes the list of exports on the IR. + context_.inst_blocks().Set(SemIR::InstBlockId::Exports, context_.exports()); + // Finalizes the ImportRef inst block. + context_.inst_blocks().Set(SemIR::InstBlockId::ImportRefs, + context_.import_ref_ids()); + // Finalizes __global_init. + context_.global_init().Finalize(); + + context_.sem_ir().set_has_errors(unit_and_imports_->err_tracker.seen_error()); + + // Verify that Context cleanly finished. + context_.VerifyOnFinish(); +} + } // namespace Carbon::Check diff --git a/toolchain/check/check_unit.h b/toolchain/check/check_unit.h index 9c2060e123621..f5ae799655d02 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -153,16 +153,20 @@ class CheckUnit { // Imports all other Carbon packages (excluding the current package). auto ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void; + // Checks that each required declaration is available. This applies for + // declarations that should exist in an owning library, for which an extern + // declaration exists that assigns ownership to the current API. + auto CheckRequiredDeclarations() -> void; + // Checks that each required definition is available. If the definition can be // generated by resolving a specific, does so, otherwise emits a diagnostic // for each declaration in context.definitions_required() that doesn't have a // definition. auto CheckRequiredDefinitions() -> void; - // Checks that each required declaration is available. This applies for - // declarations that should exist in an owning library, for which an extern - // declaration exists that assigns ownership to the current API. - auto CheckRequiredDeclarations() -> void; + // Does work after processing the parse tree, such as finishing the IR and + // checking for missing contents. + auto FinishRun() -> void; // Loops over all nodes in the tree. On some errors, this may return early, // for example if an unrecoverable state is encountered. diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index ffaaf026593d1..26fe5c15bbb2a 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -75,7 +75,7 @@ auto Context::TODO(SemIRLoc loc, std::string label) -> bool { return false; } -auto Context::VerifyOnFinish() -> void { +auto Context::VerifyOnFinish() const -> void { // Information in all the various context objects should be cleaned up as // various pieces of context go out of scope. At this point, nothing should // remain. @@ -89,19 +89,13 @@ auto Context::VerifyOnFinish() -> void { // decl_introducer_state_stack_. scope_stack_.VerifyOnFinish(); // TODO: Add verification for generic_region_stack_. -} - -auto Context::Finalize() -> void { - // Pop information for the file-level scope. - sem_ir().set_top_inst_block_id(inst_block_stack().Pop()); - scope_stack().Pop(); - // Finalizes the list of exports on the IR. - inst_blocks().Set(SemIR::InstBlockId::Exports, exports_); - // Finalizes the ImportRef inst block. - inst_blocks().Set(SemIR::InstBlockId::ImportRefs, import_ref_ids_); - // Finalizes __global_init. - global_init_.Finalize(); +#ifndef NDEBUG + if (auto verify = sem_ir_->Verify(); !verify.ok()) { + CARBON_FATAL("{0}Built invalid semantics IR: {1}\n", sem_ir_, + verify.error()); + } +#endif } auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void { diff --git a/toolchain/check/context.h b/toolchain/check/context.h index bd9a5b71ab968..58d8d11b9d9ae 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -65,12 +65,7 @@ class Context { auto TODO(SemIRLoc loc, std::string label) -> bool; // Runs verification that the processing cleanly finished. - auto VerifyOnFinish() -> void; - - // Adds an exported name. - auto AddExport(SemIR::InstId inst_id) -> void { exports_.push_back(inst_id); } - - auto Finalize() -> void; + auto VerifyOnFinish() const -> void; // Prints information for a stack dump. auto PrintForStackDump(llvm::raw_ostream& output) const -> void; @@ -146,6 +141,8 @@ class Context { auto vtable_stack() -> InstBlockStack& { return vtable_stack_; } + auto exports() -> llvm::SmallVector& { return exports_; } + auto check_ir_map() -> llvm::MutableArrayRef { return check_ir_map_; } diff --git a/toolchain/check/decl_name_stack.cpp b/toolchain/check/decl_name_stack.cpp index 9045065f46a92..3ab9c52446a28 100644 --- a/toolchain/check/decl_name_stack.cpp +++ b/toolchain/check/decl_name_stack.cpp @@ -158,7 +158,7 @@ auto DeclNameStack::AddName(NameContext name_context, SemIR::InstId target_id, // scope. Otherwise, it's in some other entity, such as a class. if (access_kind == SemIR::AccessKind::Public && name_context.initial_scope_index == ScopeIndex::Package) { - context_->AddExport(target_id); + context_->exports().push_back(target_id); } name_scope.AddRequired({.name_id = name_context.name_id, diff --git a/toolchain/check/handle_export.cpp b/toolchain/check/handle_export.cpp index 1a11e3900361f..4ce47f73b94e8 100644 --- a/toolchain/check/handle_export.cpp +++ b/toolchain/check/handle_export.cpp @@ -75,7 +75,7 @@ auto HandleParseNode(Context& context, Parse::ExportDeclId node_id) -> bool { {.type_id = import_ref->type_id, .entity_name_id = import_ref->entity_name_id, .value_id = inst_id}); - context.AddExport(export_id); + context.exports().push_back(export_id); // Replace the ImportRef in name lookup, both for the above duplicate // diagnostic and so that cross-package imports can find it easily. diff --git a/toolchain/check/param_and_arg_refs_stack.h b/toolchain/check/param_and_arg_refs_stack.h index 41f631482af82..7cafa93b3ef57 100644 --- a/toolchain/check/param_and_arg_refs_stack.h +++ b/toolchain/check/param_and_arg_refs_stack.h @@ -69,7 +69,7 @@ class ParamAndArgRefsStack { } // Runs verification that the processing cleanly finished. - auto VerifyOnFinish() -> void { stack_.VerifyOnFinish(); } + auto VerifyOnFinish() const -> void { stack_.VerifyOnFinish(); } // Prints the stack for a stack dump. auto PrintForStackDump(int indent, llvm::raw_ostream& output) const -> void { diff --git a/toolchain/check/scope_stack.cpp b/toolchain/check/scope_stack.cpp index 5f31128d58694..ff6fa16214879 100644 --- a/toolchain/check/scope_stack.cpp +++ b/toolchain/check/scope_stack.cpp @@ -9,7 +9,7 @@ namespace Carbon::Check { -auto ScopeStack::VerifyOnFinish() -> void { +auto ScopeStack::VerifyOnFinish() const -> void { CARBON_CHECK(scope_stack_.empty(), "{0}", scope_stack_.size()); } diff --git a/toolchain/check/scope_stack.h b/toolchain/check/scope_stack.h index 2169578e60636..cae4d4b902601 100644 --- a/toolchain/check/scope_stack.h +++ b/toolchain/check/scope_stack.h @@ -155,7 +155,7 @@ class ScopeStack { auto Restore(SuspendedScope scope) -> void; // Runs verification that the processing cleanly finished. - auto VerifyOnFinish() -> void; + auto VerifyOnFinish() const -> void; auto return_scope_stack() -> llvm::SmallVector& { return return_scope_stack_; From 29c1f552c7323f28df05252e1910c789d29e6c81 Mon Sep 17 00:00:00 2001 From: josh11b <15258583+josh11b@users.noreply.github.com> Date: Tue, 25 Feb 2025 10:22:03 -0800 Subject: [PATCH 19/56] InvalidIndex -> NoneIndex in comments (#5012) Co-authored-by: Josh L --- toolchain/sem_ir/inst.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 1afbca504a65a..2393263ab1653 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -239,12 +239,12 @@ class Inst : public Printable { return ArgKinds(kind()); } - // Gets the first argument of the instruction. InvalidIndex if there is no - // such argument. + // Gets the first argument of the instruction. NoneIndex if there is no such + // argument. auto arg0() const -> int32_t { return arg0_; } - // Gets the second argument of the instruction. InvalidIndex if there is no - // such argument. + // Gets the second argument of the instruction. NoneIndex if there is no such + // argument. auto arg1() const -> int32_t { return arg1_; } // Sets the type of this instruction. From 9d85b23b4bf3e9185a5a4b2b6547d9f2a6169e9f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Tue, 25 Feb 2025 18:23:22 -0800 Subject: [PATCH 20/56] Use an x-macro for special NameId values. (#5018) Doing an in-file X-macro, though maybe we'll want to move it out to a #include if we keep piling on more. I know there's `destroy` to add, and possibly `copy` and `move`, but I don't know what threshold we'll want for a separate file. Note this does set up for an advantage where we can `switch` instead of repeated `if` for special names, shifting to compile errors for new values. I also considered a simpler enum approach (with an implicit conversion to `NameId`) but that runs into issues with things like `Id::Kind::For<...>` as a consequence of calls like `name_id == special_name_id` (just requires another `operator==`) and `context.node_stack().Push(node_id, SemIR::NameId::SelfType);` (a little more complex how we'd want to handle it). --- toolchain/sem_ir/ids.cpp | 32 ++++++-------- toolchain/sem_ir/ids.h | 89 ++++++++++++++++++++++++++------------- toolchain/sem_ir/name.cpp | 34 ++++++++------- 3 files changed, 90 insertions(+), 65 deletions(-) diff --git a/toolchain/sem_ir/ids.cpp b/toolchain/sem_ir/ids.cpp index e809f512af47b..555e6ef6b22ad 100644 --- a/toolchain/sem_ir/ids.cpp +++ b/toolchain/sem_ir/ids.cpp @@ -77,6 +77,9 @@ auto IntKind::Print(llvm::raw_ostream& out) const -> void { } } +// Double-check the special value mapping and constexpr evaluation. +static_assert(NameId::SpecialNameId::Vptr == *NameId::Vptr.AsSpecialNameId()); + auto NameId::ForIdentifier(IdentifierId id) -> NameId { if (id.index >= 0) { return NameId(id.index); @@ -105,25 +108,16 @@ auto NameId::Print(llvm::raw_ostream& out) const -> void { return; } out << Label << "("; - if (*this == Base) { - out << "Base"; - } else if (*this == Core) { - out << "Core"; - } else if (*this == PackageNamespace) { - out << "PackageNamespace"; - } else if (*this == PeriodSelf) { - out << "PeriodSelf"; - } else if (*this == ReturnSlot) { - out << "ReturnSlot"; - } else if (*this == SelfType) { - out << "SelfType"; - } else if (*this == SelfValue) { - out << "SelfValue"; - } else if (*this == Vptr) { - out << "Vptr"; - } else { - CARBON_FATAL("Unknown index {0}", index); - IdBase::Print(out); + auto special_name_id = AsSpecialNameId(); + CARBON_CHECK(special_name_id, "Unknown index {0}", index); + + switch (*special_name_id) { +#define CARBON_SPECIAL_NAME_ID_FOR_PRINT(Name) \ + case SpecialNameId::Name: \ + out << #Name; \ + break; + CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_PRINT) +#undef CARBON_SPECIAL_NAME_ID_FOR_PRINT } out << ")"; } diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 3711937e0b399..b4e0a9b6667cf 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -481,6 +481,31 @@ struct FloatKind : public IdBase { auto Print(llvm::raw_ostream& out) const -> void { out << "float"; } }; +// An X-macro for special names. Uses should look like: +// +// #define CARBON_SPECIAL_NAME_ID_FOR_XYZ(Name) ... +// CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_XYZ) +// #undef CARBON_SPECIAL_NAME_ID_FOR_XYZ +#define CARBON_SPECIAL_NAME_ID(X) \ + /* The name of `base`. */ \ + X(Base) \ + /* The name of the discriminant field (if any) in a choice. */ \ + X(ChoiceDiscriminant) \ + /* The name of the package `Core`. */ \ + X(Core) \ + /* The name of `package`. */ \ + X(PackageNamespace) \ + /* The name of `.Self`. */ \ + X(PeriodSelf) \ + /* The name of the return slot in a function. */ \ + X(ReturnSlot) \ + /* The name of `Self`. */ \ + X(SelfType) \ + /* The name of `self`. */ \ + X(SelfValue) \ + /* The name of `vptr`. */ \ + X(Vptr) + // The ID of a name. A name is either a string or a special name such as // `self`, `Self`, or `base`. struct NameId : public IdBase { @@ -491,24 +516,19 @@ struct NameId : public IdBase { // An ID with no value. static const NameId None; - // The name of `base`. - static const NameId Base; - // The name of the package `Core`. - static const NameId Core; - // The name of `package`. - static const NameId PackageNamespace; - // The name of `.Self`. - static const NameId PeriodSelf; - // The name of the return slot in a function. - static const NameId ReturnSlot; - // The name of `Self`. - static const NameId SelfType; - // The name of `self`. - static const NameId SelfValue; - // The name of `vptr`. - static const NameId Vptr; - // The name of the discriminant field (if any) in a choice. - static const NameId ChoiceDiscriminant; + + // An enum of special names. + enum class SpecialNameId : uint8_t { +#define CARBON_SPECIAL_NAME_ID_FOR_ENUM(Name) Name, + CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_ENUM) +#undef CARBON_SPECIAL_NAME_ID_FOR_ENUM + }; + + // For each SpecialNameId, provide a matching `NameId` instance for + // convenience. +#define CARBON_SPECIAL_NAME_ID_FOR_DECL(Name) static const NameId Name; + CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_DECL) +#undef CARBON_SPECIAL_NAME_ID_FOR_DECL // The number of non-index (<0) that exist, and will need storage in name // lookup. @@ -529,22 +549,31 @@ struct NameId : public IdBase { return index >= 0 ? IdentifierId(index) : IdentifierId::None; } + // Expose special names for `switch`. + constexpr auto AsSpecialNameId() const -> std::optional { + if (index >= NoneIndex) { + return std::nullopt; + } + return static_cast(NoneIndex - 1 - index); + } + auto Print(llvm::raw_ostream& out) const -> void; }; constexpr NameId NameId::None = NameId(NoneIndex); -constexpr NameId NameId::Base = NameId(NoneIndex - 1); -constexpr NameId NameId::Core = NameId(NoneIndex - 2); -constexpr NameId NameId::PackageNamespace = NameId(NoneIndex - 3); -constexpr NameId NameId::PeriodSelf = NameId(NoneIndex - 4); -constexpr NameId NameId::ReturnSlot = NameId(NoneIndex - 5); -constexpr NameId NameId::SelfType = NameId(NoneIndex - 6); -constexpr NameId NameId::SelfValue = NameId(NoneIndex - 7); -constexpr NameId NameId::Vptr = NameId(NoneIndex - 8); -constexpr NameId NameId::ChoiceDiscriminant = NameId(NoneIndex - 9); -constexpr int NameId::NonIndexValueCount = 10; -// Enforce the link between SpecialValueCount and the last special value. -static_assert(NameId::NonIndexValueCount == -NameId::ChoiceDiscriminant.index); + +// Define the special `static const NameId` values. +#define CARBON_SPECIAL_NAME_ID_FOR_DEF(Name) \ + constexpr NameId NameId::Name = \ + NameId(NoneIndex - 1 - static_cast(NameId::SpecialNameId::Name)); +CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_DEF) +#undef CARBON_SPECIAL_NAME_ID_FOR_DEF + +// Count non-index values, including `None` and special names. +#define CARBON_SPECIAL_NAME_ID_FOR_COUNT(...) +1 +constexpr int NameId::NonIndexValueCount = + 1 CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_COUNT); +#undef CARBON_SPECIAL_NAME_ID_FOR_COUNT // The ID of a name scope. struct NameScopeId : public IdBase { diff --git a/toolchain/sem_ir/name.cpp b/toolchain/sem_ir/name.cpp index d51a224f6ee52..9484e7993798c 100644 --- a/toolchain/sem_ir/name.cpp +++ b/toolchain/sem_ir/name.cpp @@ -10,29 +10,31 @@ namespace Carbon::SemIR { // Get the spelling to use for a special name. static auto GetSpecialName(NameId name_id, bool for_ir) -> llvm::StringRef { - switch (name_id.index) { - case NameId::None.index: - return for_ir ? "" : ""; - case NameId::Base.index: + if (name_id == NameId::None) { + return for_ir ? "" : ""; + } + + auto special_name_id = name_id.AsSpecialNameId(); + CARBON_CHECK(special_name_id, "Not a special name"); + switch (*special_name_id) { + case NameId::SpecialNameId::Base: return "base"; - case NameId::Core.index: + case NameId::SpecialNameId::ChoiceDiscriminant: + return "discriminant"; + case NameId::SpecialNameId::Core: return "Core"; - case NameId::PeriodSelf.index: + case NameId::SpecialNameId::PackageNamespace: + return "package"; + case NameId::SpecialNameId::PeriodSelf: return ".Self"; - case NameId::ReturnSlot.index: + case NameId::SpecialNameId::ReturnSlot: return for_ir ? "return" : ""; - case NameId::PackageNamespace.index: - return "package"; - case NameId::SelfType.index: + case NameId::SpecialNameId::SelfType: return "Self"; - case NameId::SelfValue.index: + case NameId::SpecialNameId::SelfValue: return "self"; - case NameId::Vptr.index: + case NameId::SpecialNameId::Vptr: return for_ir ? "vptr" : ""; - case NameId::ChoiceDiscriminant.index: - return "discriminant"; - default: - CARBON_FATAL("Unknown special name"); } } From dbfb133fed89048ba6029ef2230ef0b2c8fe6e94 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 25 Feb 2025 23:10:59 -0800 Subject: [PATCH 21/56] Disable misc-confusable-identifiers clang-tidy check for now. (#5019) This check is very slow. See https://github.com/llvm/llvm-project/issues/128797 --- .clang-tidy | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index f5484bfcd6c51..44ac20a831ed0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -65,6 +65,9 @@ WarningsAsErrors: '*' # - '-google-readability-function-size' # # Suggests usernames on TODOs, which we don't want. # - '-google-readability-todo' +# # Extremely slow. TODO: Re-enable once +# # https://github.com/llvm/llvm-project/issues/128797 is fixed. +# - '-misc-confusable-identifiers' # # Overlaps with `-Wno-missing-prototypes`. # - '-misc-use-internal-linkage' # # Suggests `std::array`, which we could migrate to, but conflicts with the @@ -107,11 +110,12 @@ Checks: -bugprone-macro-parentheses, -bugprone-narrowing-conversions, -bugprone-switch-missing-default-case, -bugprone-unchecked-optional-access, -google-readability-function-size, -google-readability-todo, - -misc-use-internal-linkage, -modernize-avoid-c-arrays, - -modernize-use-designated-initializers, -modernize-use-nodiscard, - -performance-unnecessary-value-param, -readability-enum-initial-value, - -readability-function-cognitive-complexity, -readability-magic-numbers, - -readability-redundant-member-init, -readability-suspicious-call-argument + -misc-confusable-identifiers, -misc-use-internal-linkage, + -modernize-avoid-c-arrays, -modernize-use-designated-initializers, + -modernize-use-nodiscard, -performance-unnecessary-value-param, + -readability-enum-initial-value, -readability-function-cognitive-complexity, + -readability-magic-numbers, -readability-redundant-member-init, + -readability-suspicious-call-argument CheckOptions: # Don't warn on structs; done by ignoring when there are only public members. - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic From 3573763def343d0f7e74b340fdbc6648e1a9e32d Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Wed, 26 Feb 2025 18:41:11 +0100 Subject: [PATCH 22/56] Use Generics in `no_poison` test instead of pointers. (#5011) Followup of [#4987 comment](https://github.com/carbon-language/carbon-lang/pull/4987/files/b015f99d0e86f5dfe3b1709bec8a426a584f7804#r1964119857). Part of #4622. --- .../impl/no_prelude/name_poisoning.carbon | 397 +++++++++++------- 1 file changed, 247 insertions(+), 150 deletions(-) diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon index 8ea9a10e3f600..7b234a90ad251 100644 --- a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -17,10 +17,10 @@ interface I; // `N.F` uses `N.I` and not `package.I`. namespace N; interface N.I {} -fn N.F(x: I*); +fn N.F(x:! I) {} -fn TestCall(x: N.I*) { - // `N.F` accepts an `N.I*` not a `package.I*`. +fn TestCall(x:! N.I) { + // `N.F` accepts an `N.I` not a `package.I`. N.F(x); } @@ -32,7 +32,7 @@ interface I; namespace N; // Use `package.I` and poison `N.I`. -fn N.F(x: I*); +fn N.F(x:! I); // --- fail_declare_after_poison.carbon @@ -42,10 +42,10 @@ interface I; namespace N; // Use `package.I` and poison `N.I`. -// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x: I*); -// CHECK:STDERR: ^ -fn N.F(x: I*); +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +fn N.F(x:! I); // Failure: N.I declared after it was poisoned. // CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] @@ -62,13 +62,13 @@ interface I; namespace N; // Use `package.I` and poison `N.I`. -fn N.F1(x: I*); +fn N.F1(x:! I); -// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:12: error: member name `I` not found in `N` [MemberNameNotFoundInScope] -// CHECK:STDERR: fn N.F2(x: N.I*); -// CHECK:STDERR: ^~~ +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x:! N.I); +// CHECK:STDERR: ^~~ // CHECK:STDERR: -fn N.F2(x: N.I*); +fn N.F2(x:! N.I); // --- fail_use_declaration_after_poison.carbon @@ -78,10 +78,10 @@ interface I; namespace N; // Use `package.I` and poison `N.I`. -// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x: I*); -// CHECK:STDERR: ^ -fn N.F1(x: I*); +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F1(x:! I); +// CHECK:STDERR: ^ +fn N.F1(x:! I); // CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] // CHECK:STDERR: interface N.I; @@ -89,11 +89,11 @@ fn N.F1(x: I*); // CHECK:STDERR: interface N.I; -// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:12: error: member name `I` not found in `N` [MemberNameNotFoundInScope] -// CHECK:STDERR: fn N.F2(x: N.I*); -// CHECK:STDERR: ^~~ +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x:! N.I); +// CHECK:STDERR: ^~~ // CHECK:STDERR: -fn N.F2(x: N.I*); +fn N.F2(x:! N.I); // --- fail_alias.carbon @@ -124,27 +124,27 @@ interface I2 { // * `I2.I1` // * `I2.I3.I1` // * `I2.I3.I4.I1` - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: I1*); - // CHECK:STDERR: ^~ - fn F(x: I1*); + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ + fn F(x:! I1); // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] // CHECK:STDERR: interface I1; // CHECK:STDERR: ^~ // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: I1*); - // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ interface I1; } // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:15: note: declared here [NameUseBeforeDeclNote] // CHECK:STDERR: interface I1; // CHECK:STDERR: ^~ // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:15: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x: I1*); - // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ interface I1; } // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] @@ -175,23 +175,23 @@ library "[[@TEST_NAME]]"; namespace N; // `package.I` and `N.I` poisoned when not found. -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: error: name `I` not found [NameNotFound] -// CHECK:STDERR: fn N.F(x: I*); -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:12: error: name `I` not found [NameNotFound] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x: I*); -// CHECK:STDERR: ^ -fn N.F(x: I*); +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +fn N.F(x:! I); // TODO: We should ideally only produce one diagnostic here. // CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] // CHECK:STDERR: interface I; // CHECK:STDERR: ^ // CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:11: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x: I*); -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ interface I; // CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] // CHECK:STDERR: interface N.I; @@ -228,7 +228,7 @@ interface I {}; namespace N; // Use `package.I` and poison `N.I`. -fn N.F1(x: I*); +fn N.F1(x:! I); class N.C { extend impl as I { @@ -241,12 +241,14 @@ class N.C { // CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] // CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] // CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete] +// CHECK:STDOUT: %x: %I.type.4da = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] // CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] +// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%x) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -262,27 +264,23 @@ class N.C { // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl.loc8: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc9_8.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc9_8.1, runtime_param [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc9: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] +// CHECK:STDOUT: %x.loc9_8.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc9_8.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc11_13.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc11_13.1, runtime_param [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param +// CHECK:STDOUT: %.loc11: type = splice_block %I.ref [concrete = constants.%I.type.4da] { // CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.4da [concrete = constants.%ptr] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.loc11_13.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_13.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -296,22 +294,56 @@ class N.C { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F(%x.loc9_8.1: %I.type.4da) { +// CHECK:STDOUT: %x.loc9_8.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc9_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc9_8.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] // CHECK:STDOUT: -// CHECK:STDOUT: fn @TestCall(%x.param_patt: %ptr) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %x.ref: %ptr = name_ref x, %x -// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%x.ref) -// CHECK:STDOUT: return +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @TestCall(%x.loc11_13.1: %I.type.4da) { +// CHECK:STDOUT: %x.loc11_13.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc11_13.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_13.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %F.specific_fn.loc13_4.2: = specific_function constants.%F, @F(%x.loc11_13.2) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: %I.type.4da = name_ref x, %x.loc11_13.1 [symbolic = %x.loc11_13.2 (constants.%x)] +// CHECK:STDOUT: %F.specific_fn.loc13_4.1: = specific_function %F.ref, @F(constants.%x) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn.loc13_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc9_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc9_8.2 => constants.%x +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @TestCall(constants.%x) { +// CHECK:STDOUT: %x.loc11_13.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_13.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(@TestCall.%x.loc11_13.2) {} +// CHECK:STDOUT: // CHECK:STDOUT: --- poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -327,27 +359,35 @@ class N.C { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc8_8.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_8.1, runtime_param [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %x.loc8_8.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_8.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I; // CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F(%x.loc8_8.1: %I.type) { +// CHECK:STDOUT: %x.loc8_8.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc8_8.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc8_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc8_8.2 => constants.%x +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_declare_after_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete] +// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] @@ -365,15 +405,12 @@ class N.C { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc11_8.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_8.1, runtime_param [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %x.loc11_8.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_8.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl.loc18: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} // CHECK:STDOUT: } @@ -388,15 +425,27 @@ class N.C { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F(%x.loc11_8.1: %I.type.733) { +// CHECK:STDOUT: %x.loc11_8.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_8.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc11_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_8.2 => constants.%x +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_use_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt.3ad: %I.type = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] // CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] // CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -414,44 +463,60 @@ class N.C { // CHECK:STDOUT: .F2 = %F2.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc14_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %.1: = splice_block [concrete = ] { // CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] // CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I; // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { +// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type); +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F2(%x.param_patt: ); +// CHECK:STDOUT: generic fn @F2(%x: ) { +// CHECK:STDOUT: %x.patt.loc14_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F1(constants.%x) { +// CHECK:STDOUT: %x.loc8_9.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F2() { +// CHECK:STDOUT: %x.patt.loc14_9.2 => +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete] +// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt.3ad: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] // CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] // CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] // CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -469,28 +534,24 @@ class N.C { // CHECK:STDOUT: .F2 = %F2.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc11_9.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_9.1, runtime_param [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type.733 [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %x.loc11_9.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_9.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} // CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc23_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %.loc23: type = splice_block %ptr [concrete = ] { +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %.1: = splice_block [concrete = ] { // CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] // CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -498,9 +559,27 @@ class N.C { // CHECK:STDOUT: // CHECK:STDOUT: interface @I.2; // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F1(%x.loc11_9.1: %I.type.733) { +// CHECK:STDOUT: %x.loc11_9.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_9.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_9.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] // CHECK:STDOUT: -// CHECK:STDOUT: fn @F2(%x.param_patt: ); +// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F2(%x: ) { +// CHECK:STDOUT: %x.patt.loc23_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F1(constants.%x) { +// CHECK:STDOUT: %x.loc11_9.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_9.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F2() { +// CHECK:STDOUT: %x.patt.loc23_9.2 => +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_alias.carbon // CHECK:STDOUT: @@ -535,7 +614,8 @@ class N.C { // CHECK:STDOUT: %I4.type.451: type = facet_type <@I4> [concrete] // CHECK:STDOUT: %I4.type.78e: type = facet_type <@I4, @I4(%Self.c7b, %Self.60c)> [symbolic] // CHECK:STDOUT: %Self.a4d: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type %I1.type.80c [concrete] +// CHECK:STDOUT: %x: %I1.type.80c = bind_symbolic_name x, 3 [symbolic] +// CHECK:STDOUT: %x.patt: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.c7b, %Self.60c) [symbolic] // CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] // CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type %I4.type.78e [symbolic] @@ -601,15 +681,12 @@ class N.C { // CHECK:STDOUT: interface { // CHECK:STDOUT: %Self.1: @I4.%I4.type (%I4.type.78e) = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] // CHECK:STDOUT: %F.decl: @I4.%F.type (%F.type) = fn_decl @F [symbolic = @I4.%F (constants.%F)] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc16_12.2: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I1.type.80c = value_param_pattern %x.patt.loc16_12.2, runtime_param [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] -// CHECK:STDOUT: %ptr: type = ptr_type %I1.type.80c [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I1.type.80c = value_param runtime_param +// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] +// CHECK:STDOUT: %x.loc16_12.2: %I1.type.80c = bind_symbolic_name x, 3, %x.param [symbolic = %x.loc16_12.1 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0.loc16_19.1: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] // CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.f4e] {} {} @@ -634,15 +711,21 @@ class N.C { // CHECK:STDOUT: interface; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { -// CHECK:STDOUT: fn(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e), %x.loc16_12.2: %I1.type.80c) { +// CHECK:STDOUT: %x.loc16_12.1: %I1.type.80c = bind_symbolic_name x, 3 [symbolic = %x.loc16_12.1 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc16_12.1: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I1.type.80c); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @I3(constants.%Self.c7b) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I4(constants.%Self.c7b, constants.%Self.60c) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} +// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d, constants.%x) { +// CHECK:STDOUT: %x.loc16_12.1 => constants.%x +// CHECK:STDOUT: %x.patt.loc16_12.1 => constants.%x +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @I1.2(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} // CHECK:STDOUT: @@ -710,6 +793,7 @@ class N.C { // CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %x.patt: = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] @@ -726,15 +810,12 @@ class N.C { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc13_8.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %.loc13: type = splice_block %ptr [concrete = ] { -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_name x, %x.param +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl.loc23: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} // CHECK:STDOUT: %I.decl.loc28: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} @@ -744,7 +825,15 @@ class N.C { // CHECK:STDOUT: // CHECK:STDOUT: interface @I.2; // CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: ); +// CHECK:STDOUT: generic fn @F(%x: ) { +// CHECK:STDOUT: %x.patt.loc13_8.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F() { +// CHECK:STDOUT: %x.patt.loc13_8.2 => +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon // CHECK:STDOUT: @@ -805,7 +894,8 @@ class N.C { // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete] +// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] // CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] // CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -826,15 +916,12 @@ class N.C { // CHECK:STDOUT: .C = %C.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %ptr = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %ptr = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %ptr = value_param runtime_param0 -// CHECK:STDOUT: %.loc8: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %ptr: type = ptr_type %I.type [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %ptr = bind_name x, %x.param +// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } @@ -867,5 +954,15 @@ class N.C { // CHECK:STDOUT: extend @impl.%I.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %ptr); +// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { +// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F1(constants.%x) { +// CHECK:STDOUT: %x.loc8_9.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x +// CHECK:STDOUT: } // CHECK:STDOUT: From ebc1080c5d8344b7e543cafebad5a26bfe581325 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 26 Feb 2025 13:37:43 -0500 Subject: [PATCH 23/56] Improve diagnostics for impl lookup cycles (#4998) And add a couple more tests that fail currently but should pass in the future. --- toolchain/check/context.h | 2 + toolchain/check/deduce.cpp | 14 +- toolchain/check/impl_lookup.cpp | 136 +++++++++++------- .../impl/no_prelude/impl_cycle.carbon | 97 ++++++++++++- toolchain/diagnostics/diagnostic_kind.def | 1 + 5 files changed, 186 insertions(+), 64 deletions(-) diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 58d8d11b9d9ae..57094049e90a9 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -197,6 +197,8 @@ class Context { struct ImplLookupStackEntry { SemIR::ConstantId type_const_id; SemIR::ConstantId interface_const_id; + // The location of the impl being looked at for the stack entry. + SemIR::InstId impl_loc = SemIR::InstId::None; }; auto impl_lookup_stack() -> llvm::SmallVector& { return impl_lookup_stack_; diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index e0adbf41236be..f1ac487b86771 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -333,8 +333,11 @@ auto DeductionContext::Deduce() -> bool { // So we do this conversion here, even though we will later try convert // again when we have deduced all of the bindings. DiagnosticAnnotationScope annotate_diagnostics( - &context().emitter(), - [&](auto& builder) { NoteInitializingParam(param_id, builder); }); + &context().emitter(), [&](auto& builder) { + if (diagnose_) { + NoteInitializingParam(param_id, builder); + } + }); // TODO: The call logic should reuse the conversion here (if any) instead // of doing the same conversion again. At the moment we throw away the // converted arg_id. @@ -558,8 +561,11 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool { context().types().GetTypeIdForTypeConstantId(param_type_const_id); DiagnosticAnnotationScope annotate_diagnostics( - &context().emitter(), - [&](auto& builder) { NoteInitializingParam(binding_id, builder); }); + &context().emitter(), [&](auto& builder) { + if (diagnose_) { + NoteInitializingParam(binding_id, builder); + } + }); auto converted_arg_id = diagnose_ ? ConvertToValueOfType(context(), loc_id_, deduced_arg_id, binding_type_id) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 139a7396ea3f3..95358fc50db61 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -113,6 +113,76 @@ static auto FindAssociatedImportIRs(Context& context, return result; } +// Returns true if a cycle was found and diagnosed. +static auto FindAndDiagnoseImplLookupCycle( + Context& context, + const llvm::SmallVector& stack, + SemIR::LocId loc_id, SemIR::ConstantId type_const_id, + SemIR::ConstantId interface_const_id) -> bool { + // Deduction of the interface parameters can do further impl lookups, and we + // need to ensure we terminate. + // + // https://docs.carbon-lang.dev/docs/design/generics/details.html#acyclic-rule + // - We look for violations of the acyclic rule by seeing if a previous lookup + // had all the same type inputs. + // - The `interface_const_id` encodes the entire facet type being looked up, + // including any specific parameters for a generic interface. + // + // TODO: Implement the termination rule, which requires looking at the + // complexity of the types on the top of (or throughout?) the stack: + // https://docs.carbon-lang.dev/docs/design/generics/details.html#termination-rule + for (auto [i, entry] : llvm::enumerate(stack)) { + if (entry.type_const_id == type_const_id && + entry.interface_const_id == interface_const_id) { + auto facet_type_type_id = + context.types().GetTypeIdForTypeConstantId(interface_const_id); + CARBON_DIAGNOSTIC(ImplLookupCycle, Error, + "cycle found in search for impl of {0} for type {1}", + SemIR::TypeId, SemIR::TypeId); + auto builder = context.emitter().Build( + loc_id, ImplLookupCycle, facet_type_type_id, + context.types().GetTypeIdForTypeConstantId(type_const_id)); + for (const auto& active_entry : llvm::drop_begin(stack, i)) { + if (active_entry.impl_loc.has_value()) { + CARBON_DIAGNOSTIC(ImplLookupCycleNote, Note, + "determining if this impl clause matches", ); + builder.Note(active_entry.impl_loc, ImplLookupCycleNote); + } + } + builder.Emit(); + return true; + } + } + return false; +} + +// Gets the `SemIR::InterfaceId` for a facet type (as a constant value). +// +// The facet type requires only one `InterfaceId` right now. But in the future, +// a facet type may include more than a single interface. For now that is +// unhandled with a TODO. +static auto GetInterfaceIdFromConstantId(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId interface_const_id) + -> SemIR::InterfaceId { + auto facet_type_inst_id = + context.constant_values().GetInstId(interface_const_id); + auto facet_type_id = + context.insts().GetAs(facet_type_inst_id).facet_type_id; + const auto& facet_type_info = context.facet_types().Get(facet_type_id); + if (facet_type_info.impls_constraints.empty()) { + context.TODO(loc_id, + "impl lookup for a FacetType with no interface (using " + "`where .Self impls ...` instead?)"); + return SemIR::InterfaceId::None; + } + if (facet_type_info.impls_constraints.size() > 1) { + context.TODO(loc_id, + "impl lookup for a FacetType with more than one interface"); + return SemIR::InterfaceId::None; + } + return facet_type_info.impls_constraints[0].interface_id; +} + static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, SemIR::ConstantId type_const_id, SemIR::ConstantId interface_const_id, @@ -199,74 +269,34 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, } } - auto& stack = context.impl_lookup_stack(); - // Deduction of the interface parameters can do further impl lookups, and we - // need to ensure we terminate. - // - // https://docs.carbon-lang.dev/docs/design/generics/details.html#acyclic-rule - // - We look for violations of the acyclic rule by seeing if a previous lookup - // had all the same type inputs. - // - The `interface_const_id` encodes the entire facet type being looked up, - // including any specific parameters for a generic interface. - // - // TODO: Implement the termination rule, which requires looking at the - // complexity of the types on the top of (or throughout?) the stack: - // https://docs.carbon-lang.dev/docs/design/generics/details.html#termination-rule - for (auto entry : stack) { - if (entry.type_const_id == type_const_id && - entry.interface_const_id == interface_const_id) { - CARBON_DIAGNOSTIC(ImplLookupCycle, Error, - "cycle found in lookup of interface {0} for type {1}", - std::string, SemIR::TypeId); - context.emitter() - .Build(loc_id, ImplLookupCycle, "", - context.types().GetTypeIdForTypeConstantId(type_const_id)) - .Emit(); - return SemIR::ErrorInst::SingletonInstId; - } + if (FindAndDiagnoseImplLookupCycle(context, context.impl_lookup_stack(), + loc_id, type_const_id, + interface_const_id)) { + return SemIR::ErrorInst::SingletonInstId; } - // The `interface_id` is the single interface in the `interface_const_id` - // facet type. In the future, a facet type may include more than a single - // interface, but for now that is unhandled with a TODO. - auto interface_id = [&] { - auto facet_type_inst_id = - context.constant_values().GetInstId(interface_const_id); - auto facet_type_id = context.insts() - .GetAs(facet_type_inst_id) - .facet_type_id; - const auto& facet_type_info = context.facet_types().Get(facet_type_id); - if (facet_type_info.impls_constraints.empty()) { - context.TODO(loc_id, - "impl lookup for a FacetType with no interface (using " - "`where .Self impls ...` instead?)"); - return SemIR::InterfaceId::None; - } - if (facet_type_info.impls_constraints.size() > 1) { - context.TODO(loc_id, - "impl lookup for a FacetType with more than one interface"); - return SemIR::InterfaceId::None; - } - return facet_type_info.impls_constraints[0].interface_id; - }(); + auto interface_id = + GetInterfaceIdFromConstantId(context, loc_id, interface_const_id); - auto witness_id = SemIR::InstId::None; + auto result_witness_id = SemIR::InstId::None; + auto& stack = context.impl_lookup_stack(); stack.push_back({ .type_const_id = type_const_id, .interface_const_id = interface_const_id, }); for (const auto& impl : context.impls().array_ref()) { - witness_id = GetWitnessIdForImpl(context, loc_id, type_const_id, - interface_const_id, interface_id, impl); - if (witness_id.has_value()) { + stack.back().impl_loc = impl.definition_id; + result_witness_id = GetWitnessIdForImpl( + context, loc_id, type_const_id, interface_const_id, interface_id, impl); + if (result_witness_id.has_value()) { // We found a matching impl, don't keep looking. break; } } stack.pop_back(); - return witness_id; + return result_witness_id; } } // namespace Carbon::Check diff --git a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon index dd33f507d2495..69d454e4a09d1 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon @@ -24,6 +24,8 @@ interface ImplicitAs(Dest:! type) { // --- fail_impl_simple_cycle.carbon library "[[@TEST_NAME]]"; +import Core; + interface Z {} // This creates a dependency cycle with itself. @@ -34,16 +36,97 @@ class Point { } fn F() { - // CHECK:STDERR: fail_impl_simple_cycle.carbon:[[@LINE+7]]:21: error: cycle found in lookup of interface for type `Point` [ImplLookupCycle] + // CHECK:STDERR: fail_impl_simple_cycle.carbon:[[@LINE+7]]:21: error: cycle found in search for impl of `Z` for type `Point` [ImplLookupCycle] // CHECK:STDERR: ({} as Point) as (Point as Z); // CHECK:STDERR: ^~~~~~~~~~ - // CHECK:STDERR: fail_impl_simple_cycle.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fail_impl_simple_cycle.carbon:[[@LINE-10]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] // CHECK:STDERR: impl forall [T:! Z] T as Z {} // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: ({} as Point) as (Point as Z); } +// --- fail_impl_simple_where_cycle.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface Z {} + +// This creates a dependency cycle with itself. +impl forall [T:! type where .Self impls Z] T as Z {} + +class Point { + impl as Z {} +} + +fn F() { + // TODO: A cycle should be found in the `impl forall T as Z` above. + // CHECK:STDERR: fail_impl_simple_where_cycle.carbon:[[@LINE+4]]:21: error: semantics TODO: `impl lookup for a FacetType with no interface (using `where .Self impls ...` instead?)` [SemanticsTodo] + // CHECK:STDERR: ({} as Point) as (Point as Z); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: + ({} as Point) as (Point as Z); +} + +// --- fail_impl_simple_two_interfaces.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface Z {} +interface Y {} + +// This creates a dependency cycle with itself. +// CHECK:STDERR: fail_impl_simple_two_interfaces.carbon:[[@LINE+4]]:18: error: name `Core.BitAnd` implicitly referenced here, but not found [CoreNameNotFound] +// CHECK:STDERR: impl forall [T:! Z & Y] T as Z {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +impl forall [T:! Z & Y] T as Z {} + +class Point { + impl as Z {} +} + +fn F() { + // TODO: A cycle should be found in the `impl forall T as Z` above. + ({} as Point) as (Point as Z); +} + +// --- fail_impl_long_cycle.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface X {} +interface Y {} +interface Z {} + +// This creates a dependency cycle with itself. +impl forall [T:! X] T as Y {} +impl forall [T:! Y] T as Z {} +impl forall [T:! Z] T as X {} + +class C {} +impl C as Z {} + +fn F() { + // CHECK:STDERR: fail_impl_long_cycle.carbon:[[@LINE+13]]:17: error: cycle found in search for impl of `Z` for type `C` [ImplLookupCycle] + // CHECK:STDERR: ({} as C) as (C as Z); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_impl_long_cycle.carbon:[[@LINE-10]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] + // CHECK:STDERR: impl forall [T:! Y] T as Z {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_long_cycle.carbon:[[@LINE-14]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] + // CHECK:STDERR: impl forall [T:! X] T as Y {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_long_cycle.carbon:[[@LINE-15]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] + // CHECK:STDERR: impl forall [T:! Z] T as X {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + ({} as C) as (C as Z); +} + // --- fail_impl_cycle_one_generic_param.carbon library "[[@TEST_NAME]]"; @@ -62,10 +145,10 @@ impl C as ComparableWith(D) {} fn Compare[T:! type, U:! ComparableWith(T)](t: T, u: U) {} fn F() { - // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE+20]]:3: error: cycle found in lookup of interface for type `C` [ImplLookupCycle] + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE+20]]:3: error: cycle found in search for impl of `ComparableWith(C)` for type `C` [ImplLookupCycle] // CHECK:STDERR: Compare({} as C, {} as C); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-13]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-13]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] // CHECK:STDERR: impl forall [U:! type, T:! ComparableWith(U)] // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-9]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] @@ -84,13 +167,13 @@ fn F() { // CHECK:STDERR: Compare({} as C, {} as C); - // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE+13]]:3: error: cycle found in lookup of interface for type `D` [ImplLookupCycle] + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE+13]]:3: error: cycle found in search for impl of `ComparableWith(C)` for type `D` [ImplLookupCycle] // CHECK:STDERR: Compare({} as C, {} as D); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-35]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-35]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] // CHECK:STDERR: impl forall [U:! type, T:! ComparableWith(U)] // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-38]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-38]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] // CHECK:STDERR: impl forall [U:! type, T:! ComparableWith(U)] // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-34]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 43a954a096445..6a8888df10984 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -290,6 +290,7 @@ CARBON_DIAGNOSTIC_KIND(ImplAsOutsideClass) CARBON_DIAGNOSTIC_KIND(ImplAssociatedConstantNeedsValue) CARBON_DIAGNOSTIC_KIND(ImplFunctionWithNonFunction) CARBON_DIAGNOSTIC_KIND(ImplLookupCycle) +CARBON_DIAGNOSTIC_KIND(ImplLookupCycleNote) CARBON_DIAGNOSTIC_KIND(ImplMissingDefinition) CARBON_DIAGNOSTIC_KIND(ImplMissingFunction) CARBON_DIAGNOSTIC_KIND(ImplPreviousDefinition) From 422cc3d48a43b46ef760ba98ef114b301638501c Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 10:44:36 -0800 Subject: [PATCH 24/56] Move diagnostic usings off Context (#5007) There aren't remaining uses on `Context` other than `DiagnosticEmitter` itself. I'm adding `SemIRLoc` because I feel odd about having both `Carbon::Check::DiagnosticBuilder` and `Carbon::DiagnosticEmitter::DiagnosticBuilder`, but it seems relatively little additional typing outside the handful of `DiagnosticEmitter` uses on `Context` itself: ``` Context::DiagnosticEmitter DiagnosticEmitter Context::DiagnosticBuilder SemIRLocDiagnosticBuilder Context::BuildDiagnosticFn BuildSemIRLocDiagnosticFn ``` Also clean up #include's while I'm finishing here. --- toolchain/check/BUILD | 1 + toolchain/check/context.cpp | 34 +--------------------------- toolchain/check/context.h | 21 ++++++----------- toolchain/check/deduce.cpp | 2 +- toolchain/check/diagnostic_helpers.h | 7 ++++++ toolchain/check/eval.cpp | 2 +- toolchain/check/impl.cpp | 3 +-- toolchain/check/member_access.cpp | 12 +++++----- toolchain/check/member_access.h | 3 +-- toolchain/check/operator.cpp | 4 ++-- toolchain/check/operator.h | 16 ++++++------- toolchain/check/return.cpp | 6 ++--- toolchain/check/type_completion.cpp | 32 ++++++++++++-------------- toolchain/check/type_completion.h | 23 +++++++++---------- 14 files changed, 65 insertions(+), 101 deletions(-) diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 9ff786751c9d2..186ffbd387c9c 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -91,6 +91,7 @@ cc_library( "//common:array_stack", "//common:check", "//common:map", + "//common:ostream", "//common:raw_string_ostream", "//common:set", "//common:vlog", diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 26fe5c15bbb2a..4ab257f3331fa 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -4,43 +4,11 @@ #include "toolchain/check/context.h" -#include -#include -#include - #include "common/check.h" -#include "common/vlog.h" -#include "llvm/ADT/Sequence.h" -#include "toolchain/check/convert.h" -#include "toolchain/check/decl_name_stack.h" -#include "toolchain/check/eval.h" -#include "toolchain/check/generic.h" -#include "toolchain/check/generic_region_stack.h" -#include "toolchain/check/import.h" -#include "toolchain/check/import_ref.h" -#include "toolchain/check/inst_block_stack.h" -#include "toolchain/check/interface.h" -#include "toolchain/check/merge.h" -#include "toolchain/check/type_completion.h" -#include "toolchain/diagnostics/diagnostic_emitter.h" -#include "toolchain/diagnostics/format_providers.h" -#include "toolchain/lex/tokenized_buffer.h" -#include "toolchain/parse/node_ids.h" -#include "toolchain/parse/node_kind.h" -#include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/formatter.h" -#include "toolchain/sem_ir/generic.h" -#include "toolchain/sem_ir/ids.h" -#include "toolchain/sem_ir/import_ir.h" -#include "toolchain/sem_ir/inst.h" -#include "toolchain/sem_ir/inst_kind.h" -#include "toolchain/sem_ir/name_scope.h" -#include "toolchain/sem_ir/type_info.h" -#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { -Context::Context(DiagnosticEmitter* emitter, +Context::Context(DiagnosticEmitter* emitter, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, SemIR::File* sem_ir, int imported_ir_count, int total_ir_count, llvm::raw_ostream* vlog_stream) diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 57094049e90a9..db50476a47c53 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -5,12 +5,13 @@ #ifndef CARBON_TOOLCHAIN_CHECK_CONTEXT_H_ #define CARBON_TOOLCHAIN_CHECK_CONTEXT_H_ +#include + #include "common/map.h" -#include "llvm/ADT/FoldingSet.h" +#include "common/ostream.h" #include "llvm/ADT/SmallVector.h" #include "toolchain/check/decl_introducer_state.h" #include "toolchain/check/decl_name_stack.h" -#include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/full_pattern_stack.h" #include "toolchain/check/generic_region_stack.h" #include "toolchain/check/global_init.h" @@ -18,8 +19,8 @@ #include "toolchain/check/node_stack.h" #include "toolchain/check/param_and_arg_refs_stack.h" #include "toolchain/check/region_stack.h" -#include "toolchain/check/scope_index.h" #include "toolchain/check/scope_stack.h" +#include "toolchain/diagnostics/diagnostic_emitter.h" #include "toolchain/parse/node_ids.h" #include "toolchain/parse/tree.h" #include "toolchain/parse/tree_and_subtrees.h" @@ -47,16 +48,8 @@ namespace Carbon::Check { // (for example, shared with lowering). class Context { public: - using DiagnosticEmitter = Carbon::DiagnosticEmitter; - using DiagnosticBuilder = DiagnosticEmitter::DiagnosticBuilder; - - // A function that forms a diagnostic for some kind of problem. The - // DiagnosticBuilder is returned rather than emitted so that the caller can - // add contextual notes as appropriate. - using BuildDiagnosticFn = llvm::function_refDiagnosticBuilder>; - // Stores references for work. - explicit Context(DiagnosticEmitter* emitter, + explicit Context(DiagnosticEmitter* emitter, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, SemIR::File* sem_ir, int imported_ir_count, int total_ir_count, llvm::raw_ostream* vlog_stream); @@ -75,7 +68,7 @@ class Context { return tokens().GetKind(parse_tree().node_token(node_id)); } - auto emitter() -> DiagnosticEmitter& { return *emitter_; } + auto emitter() -> DiagnosticEmitter& { return *emitter_; } auto parse_tree_and_subtrees() -> const Parse::TreeAndSubtrees& { return tree_and_subtrees_getter_(); @@ -273,7 +266,7 @@ class Context { private: // Handles diagnostics. - DiagnosticEmitter* emitter_; + DiagnosticEmitter* emitter_; // Returns a lazily constructed TreeAndSubtrees. Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter_; diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index f1ac487b86771..98341f2b0fb15 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -256,7 +256,7 @@ class DeductionContext { } // namespace static auto NoteGenericHere(Context& context, SemIR::GenericId generic_id, - Context::DiagnosticBuilder& diag) -> void { + DiagnosticBuilder& diag) -> void { CARBON_DIAGNOSTIC(DeductionGenericHere, Note, "while deducing parameters of generic declared here"); diag.Note(context.generics().Get(generic_id).decl_id, DeductionGenericHere); diff --git a/toolchain/check/diagnostic_helpers.h b/toolchain/check/diagnostic_helpers.h index 0c1973d0d52f7..db37acf162f59 100644 --- a/toolchain/check/diagnostic_helpers.h +++ b/toolchain/check/diagnostic_helpers.h @@ -44,6 +44,13 @@ class SemIRLoc { bool token_only_; }; +using DiagnosticBuilder = DiagnosticEmitter::DiagnosticBuilder; + +// A function that forms a diagnostic for some kind of problem. The +// DiagnosticBuilder is returned rather than emitted so that the caller +// can add contextual notes as appropriate. +using MakeDiagnosticBuilderFn = llvm::function_refDiagnosticBuilder>; + inline auto TokenOnly(SemIR::LocId loc_id) -> SemIRLoc { return SemIRLoc(loc_id, true); } diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 1a97f526e6af7..5747dcbb9e7f0 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -180,7 +180,7 @@ class EvalContext { auto sem_ir() -> SemIR::File& { return context().sem_ir(); } - auto emitter() -> Context::DiagnosticEmitter& { return context().emitter(); } + auto emitter() -> DiagnosticEmitter& { return context().emitter(); } private: // The type-checking context in which we're performing evaluation. diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 5cd024570f325..aec86c4058b93 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -25,8 +25,7 @@ namespace Carbon::Check { // Adds the location of the associated function to a diagnostic. -static auto NoteAssociatedFunction(Context& context, - Context::DiagnosticBuilder& builder, +static auto NoteAssociatedFunction(Context& context, DiagnosticBuilder& builder, SemIR::FunctionId function_id) -> void { CARBON_DIAGNOSTIC(AssociatedFunctionHere, Note, "associated function {0} declared here", SemIR::NameId); diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index d62925630086d..fc1afe6f78fff 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -184,8 +184,7 @@ static auto AccessMemberOfImplWitness(Context& context, SemIR::LocId loc_id, static auto PerformImplLookup( Context& context, SemIR::LocId loc_id, SemIR::ConstantId type_const_id, SemIR::AssociatedEntityType assoc_type, SemIR::InstId member_id, - Context::BuildDiagnosticFn missing_impl_diagnoser = nullptr) - -> SemIR::InstId { + MakeDiagnosticBuilderFn missing_impl_diagnoser = nullptr) -> SemIR::InstId { auto interface_type = GetInterfaceFromFacetType(context, assoc_type.interface_type_id); if (!interface_type) { @@ -525,10 +524,11 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, return member_id; } -auto PerformCompoundMemberAccess( - Context& context, SemIR::LocId loc_id, SemIR::InstId base_id, - SemIR::InstId member_expr_id, - Context::BuildDiagnosticFn missing_impl_diagnoser) -> SemIR::InstId { +auto PerformCompoundMemberAccess(Context& context, SemIR::LocId loc_id, + SemIR::InstId base_id, + SemIR::InstId member_expr_id, + MakeDiagnosticBuilderFn missing_impl_diagnoser) + -> SemIR::InstId { auto base_type_id = context.insts().Get(base_id).type_id(); auto base_type_const_id = context.types().GetConstantId(base_type_id); diff --git a/toolchain/check/member_access.h b/toolchain/check/member_access.h index 87862e1c48e9d..7ab9a73d13466 100644 --- a/toolchain/check/member_access.h +++ b/toolchain/check/member_access.h @@ -23,8 +23,7 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, auto PerformCompoundMemberAccess( Context& context, SemIR::LocId loc_id, SemIR::InstId base_id, SemIR::InstId member_expr_id, - Context::BuildDiagnosticFn missing_impl_diagnoser = nullptr) - -> SemIR::InstId; + MakeDiagnosticBuilderFn missing_impl_diagnoser = nullptr) -> SemIR::InstId; // Creates SemIR to perform a tuple index with base expression `tuple_inst_id` // and index expression `index_inst_id`. Returns the result of the access. diff --git a/toolchain/check/operator.cpp b/toolchain/check/operator.cpp index ab6690b83cbbf..fb15f5f2eeb2e 100644 --- a/toolchain/check/operator.cpp +++ b/toolchain/check/operator.cpp @@ -32,7 +32,7 @@ static auto GetOperatorOpFunction(Context& context, SemIR::LocId loc_id, auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op, SemIR::InstId operand_id, - Context::BuildDiagnosticFn missing_impl_diagnoser) + MakeDiagnosticBuilderFn missing_impl_diagnoser) -> SemIR::InstId { // Look up the operator function. auto op_fn = GetOperatorOpFunction(context, loc_id.ToImplicit(), op); @@ -50,7 +50,7 @@ auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op, auto BuildBinaryOperator(Context& context, SemIR::LocId loc_id, Operator op, SemIR::InstId lhs_id, SemIR::InstId rhs_id, - Context::BuildDiagnosticFn missing_impl_diagnoser) + MakeDiagnosticBuilderFn missing_impl_diagnoser) -> SemIR::InstId { // Look up the operator function. auto op_fn = GetOperatorOpFunction(context, loc_id.ToImplicit(), op); diff --git a/toolchain/check/operator.h b/toolchain/check/operator.h index a243e3bb14e74..5b3a7fb9aa5ad 100644 --- a/toolchain/check/operator.h +++ b/toolchain/check/operator.h @@ -21,19 +21,19 @@ struct Operator { // `*operand` or `operand*`. If specified, `missing_impl_diagnoser` is used to // build a custom error diagnostic for the case where impl lookup for the // operator fails. -auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op, - SemIR::InstId operand_id, - Context::BuildDiagnosticFn missing_impl_diagnoser = - nullptr) -> SemIR::InstId; +auto BuildUnaryOperator( + Context& context, SemIR::LocId loc_id, Operator op, + SemIR::InstId operand_id, + MakeDiagnosticBuilderFn missing_impl_diagnoser = nullptr) -> SemIR::InstId; // Checks and builds SemIR for a binary operator expression. For example, // `lhs_id * rhs_id`. If specified, `missing_impl_diagnoser` is used to build a // custom error diagnostic for the case where impl lookup for the operator // fails. -auto BuildBinaryOperator(Context& context, SemIR::LocId loc_id, Operator op, - SemIR::InstId lhs_id, SemIR::InstId rhs_id, - Context::BuildDiagnosticFn missing_impl_diagnoser = - nullptr) -> SemIR::InstId; +auto BuildBinaryOperator( + Context& context, SemIR::LocId loc_id, Operator op, SemIR::InstId lhs_id, + SemIR::InstId rhs_id, + MakeDiagnosticBuilderFn missing_impl_diagnoser = nullptr) -> SemIR::InstId; } // namespace Carbon::Check diff --git a/toolchain/check/return.cpp b/toolchain/check/return.cpp index 2ab0d1de133e7..f96e5a150f1c0 100644 --- a/toolchain/check/return.cpp +++ b/toolchain/check/return.cpp @@ -39,7 +39,7 @@ static auto GetCurrentReturnedVar(Context& context) -> SemIR::InstId { } // Produces a note that the given function has no explicit return type. -static auto NoteNoReturnTypeProvided(Context::DiagnosticBuilder& diag, +static auto NoteNoReturnTypeProvided(DiagnosticBuilder& diag, const SemIR::Function& function) { CARBON_DIAGNOSTIC(ReturnTypeOmittedNote, Note, "there was no return type provided"); @@ -48,7 +48,7 @@ static auto NoteNoReturnTypeProvided(Context::DiagnosticBuilder& diag, // Produces a note describing the return type of the given function, which // must be a function whose definition is currently being checked. -static auto NoteReturnType(Context& context, Context::DiagnosticBuilder& diag, +static auto NoteReturnType(Context& context, DiagnosticBuilder& diag, const SemIR::Function& function) { auto out_param_pattern = context.insts().GetAs( function.return_slot_pattern_id); @@ -63,7 +63,7 @@ static auto NoteReturnType(Context& context, Context::DiagnosticBuilder& diag, } // Produces a note pointing at the currently in scope `returned var`. -static auto NoteReturnedVar(Context::DiagnosticBuilder& diag, +static auto NoteReturnedVar(DiagnosticBuilder& diag, SemIR::InstId returned_var_id) { CARBON_DIAGNOSTIC(ReturnedVarHere, Note, "`returned var` was declared here"); diag.Note(returned_var_id, ReturnedVarHere); diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 4935907f7b9a7..0cc7697cf76a9 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -29,7 +29,7 @@ namespace { class TypeCompleter { public: TypeCompleter(Context& context, SemIRLoc loc, - Context::BuildDiagnosticFn diagnoser) + MakeDiagnosticBuilderFn diagnoser) : context_(context), loc_(loc), diagnoser_(diagnoser) {} // Attempts to complete the given type. Returns true if it is now complete, @@ -160,7 +160,7 @@ class TypeCompleter { Context& context_; llvm::SmallVector work_list_; SemIRLoc loc_; - Context::BuildDiagnosticFn diagnoser_; + MakeDiagnosticBuilderFn diagnoser_; }; } // namespace @@ -535,7 +535,7 @@ auto TypeCompleter::BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const } auto TryToCompleteType(Context& context, SemIR::TypeId type_id, SemIRLoc loc, - Context::BuildDiagnosticFn diagnoser) -> bool { + MakeDiagnosticBuilderFn diagnoser) -> bool { return TypeCompleter(context, loc, diagnoser).Complete(type_id); } @@ -547,8 +547,8 @@ auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void { } auto RequireCompleteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, - Context::BuildDiagnosticFn diagnoser) -> bool { + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser) + -> bool { CARBON_CHECK(diagnoser); if (!TypeCompleter(context, loc_id, diagnoser).Complete(type_id)) { @@ -573,8 +573,8 @@ auto RequireCompleteType(Context& context, SemIR::TypeId type_id, // Adds a note to a diagnostic explaining that a class is abstract. static auto NoteAbstractClass(Context& context, SemIR::ClassId class_id, - bool direct_use, - Context::DiagnosticBuilder& builder) -> void { + bool direct_use, DiagnosticBuilder& builder) + -> void { const auto& class_info = context.classes().Get(class_id); CARBON_CHECK( class_info.inheritance_kind == SemIR::Class::InheritanceKind::Abstract, @@ -588,10 +588,8 @@ static auto NoteAbstractClass(Context& context, SemIR::ClassId class_id, } auto RequireConcreteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, - Context::BuildDiagnosticFn diagnoser, - Context::BuildDiagnosticFn abstract_diagnoser) - -> bool { + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser, + MakeDiagnosticBuilderFn abstract_diagnoser) -> bool { // TODO: For symbolic types, should add a RequireConcreteType instruction, // like RequireCompleteType. CARBON_CHECK(abstract_diagnoser); @@ -623,7 +621,7 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, SemIR::LocId loc_id, const SemIR::FacetType& facet_type, - Context::BuildDiagnosticFn diagnoser) + MakeDiagnosticBuilderFn diagnoser) -> SemIR::CompleteFacetTypeId { if (!RequireCompleteType(context, type_id, loc_id, diagnoser)) { return SemIR::CompleteFacetTypeId::None; @@ -633,7 +631,7 @@ auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, } auto AsCompleteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, Context::BuildDiagnosticFn diagnoser) + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser) -> SemIR::TypeId { return RequireCompleteType(context, type_id, loc_id, diagnoser) ? type_id @@ -644,8 +642,8 @@ auto AsCompleteType(Context& context, SemIR::TypeId type_id, // incomplete or abstract type error and returns an error type. This is a // convenience wrapper around `RequireConcreteType`. auto AsConcreteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, Context::BuildDiagnosticFn diagnoser, - Context::BuildDiagnosticFn abstract_diagnoser) + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser, + MakeDiagnosticBuilderFn abstract_diagnoser) -> SemIR::TypeId { return RequireConcreteType(context, type_id, loc_id, diagnoser, abstract_diagnoser) @@ -654,7 +652,7 @@ auto AsConcreteType(Context& context, SemIR::TypeId type_id, } auto NoteIncompleteClass(Context& context, SemIR::ClassId class_id, - Context::DiagnosticBuilder& builder) -> void { + DiagnosticBuilder& builder) -> void { const auto& class_info = context.classes().Get(class_id); CARBON_CHECK(!class_info.is_defined(), "Class is not incomplete"); if (class_info.has_definition_started()) { @@ -669,7 +667,7 @@ auto NoteIncompleteClass(Context& context, SemIR::ClassId class_id, } auto NoteUndefinedInterface(Context& context, SemIR::InterfaceId interface_id, - Context::DiagnosticBuilder& builder) -> void { + DiagnosticBuilder& builder) -> void { const auto& interface_info = context.interfaces().Get(interface_id); CARBON_CHECK(!interface_info.is_defined(), "Interface is not incomplete"); if (interface_info.is_being_defined()) { diff --git a/toolchain/check/type_completion.h b/toolchain/check/type_completion.h index 3c743c054525b..a169479e39bb2 100644 --- a/toolchain/check/type_completion.h +++ b/toolchain/check/type_completion.h @@ -21,7 +21,7 @@ namespace Carbon::Check { // don't want to trigger a request for more monomorphization. // TODO: Remove the other call to this function. auto TryToCompleteType(Context& context, SemIR::TypeId type_id, SemIRLoc loc, - Context::BuildDiagnosticFn diagnoser = nullptr) -> bool; + MakeDiagnosticBuilderFn diagnoser = nullptr) -> bool; // Completes the type `type_id`. CHECK-fails if it can't be completed. auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void; @@ -37,47 +37,46 @@ auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void; // the completeness of the type will be enforced during monomorphization, and // `loc_id` is used as the location for a diagnostic produced at that time. auto RequireCompleteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, - Context::BuildDiagnosticFn diagnoser) -> bool; + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser) + -> bool; // Like `RequireCompleteType`, but also require the type to not be an abstract // class type. If it is, `abstract_diagnoser` is used to diagnose the problem, // and this function returns false. auto RequireConcreteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, - Context::BuildDiagnosticFn diagnoser, - Context::BuildDiagnosticFn abstract_diagnoser) -> bool; + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser, + MakeDiagnosticBuilderFn abstract_diagnoser) -> bool; // Like `RequireCompleteType`, but only for facet types. If it uses some // incomplete interface, diagnoses the problem and returns `None`. auto RequireCompleteFacetType(Context& context, SemIR::TypeId type_id, SemIR::LocId loc_id, const SemIR::FacetType& facet_type, - Context::BuildDiagnosticFn diagnoser) + MakeDiagnosticBuilderFn diagnoser) -> SemIR::CompleteFacetTypeId; // Returns the type `type_id` if it is a complete type, or produces an // incomplete type error and returns an error type. This is a convenience // wrapper around `RequireCompleteType`. auto AsCompleteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, Context::BuildDiagnosticFn diagnoser) + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser) -> SemIR::TypeId; // Returns the type `type_id` if it is a concrete type, or produces an // incomplete or abstract type error and returns an error type. This is a // convenience wrapper around `RequireConcreteType`. auto AsConcreteType(Context& context, SemIR::TypeId type_id, - SemIR::LocId loc_id, Context::BuildDiagnosticFn diagnoser, - Context::BuildDiagnosticFn abstract_diagnoser) + SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser, + MakeDiagnosticBuilderFn abstract_diagnoser) -> SemIR::TypeId; // Adds a note to a diagnostic explaining that a class is incomplete. auto NoteIncompleteClass(Context& context, SemIR::ClassId class_id, - Context::DiagnosticBuilder& builder) -> void; + DiagnosticBuilder& builder) -> void; // Adds a note to a diagnostic explaining that an interface is not defined. auto NoteUndefinedInterface(Context& context, SemIR::InterfaceId interface_id, - Context::DiagnosticBuilder& builder) -> void; + DiagnosticBuilder& builder) -> void; } // namespace Carbon::Check From 7a9af69595cf9324bf9b45e0f7034febcfdd795a Mon Sep 17 00:00:00 2001 From: Alina Sbirlea Date: Wed, 26 Feb 2025 12:03:34 -0800 Subject: [PATCH 25/56] Refactor function definition lowering. (#5014) Some refactoring to start adding lowering of function definition generics. --- toolchain/lower/file_context.cpp | 18 +++++++++++++++--- toolchain/lower/file_context.h | 13 +++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 13562312fc6e4..a7cb36cc37140 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -4,6 +4,7 @@ #include "toolchain/lower/file_context.h" +#include "common/check.h" #include "common/vlog.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" @@ -184,6 +185,8 @@ auto FileContext::GetOrCreateFunction(SemIR::FunctionId function_id, // TODO: Add this function to a list of specific functions whose definitions // we need to emit. specific_functions_[specific_id.index] = result; + // TODO: Should this be a pair of ? + specific_function_definitions_.push_back(specific_id); return result; } @@ -315,13 +318,22 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) return; } + BuildFunctionBody(function_id, function, llvm_function); +} + +auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id, + const SemIR::Function& function, + llvm::Function* llvm_function, + SemIR::SpecificId specific_id) -> void { + const auto& body_block_ids = function.body_block_ids; + CARBON_DCHECK(llvm_function, "LLVM Function not found when lowering body."); + CARBON_DCHECK(!body_block_ids.empty(), + "No function body blocks found during lowering."); + FunctionContext function_lowering(*this, llvm_function, BuildDISubprogram(function, llvm_function), vlog_stream_); - // TODO: Pass in a specific ID for generic functions. - const auto specific_id = SemIR::SpecificId::None; - // Add parameters to locals. // TODO: This duplicates the mapping between sem_ir instructions and LLVM // function parameters that was already computed in BuildFunctionDecl. diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 5cd68da6917f5..305baf40195fc 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -11,6 +11,7 @@ #include "llvm/IR/Module.h" #include "toolchain/check/sem_ir_loc_diagnostic_emitter.h" #include "toolchain/sem_ir/file.h" +#include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst_namer.h" namespace Carbon::Lower { @@ -105,6 +106,12 @@ class FileContext { // declaration with no definition, does nothing. auto BuildFunctionDefinition(SemIR::FunctionId function_id) -> void; + // Builds a functions body. Common functionality for all functions. + auto BuildFunctionBody( + SemIR::FunctionId function_id, const SemIR::Function& function, + llvm::Function* llvm_function, + SemIR::SpecificId specific_id = SemIR::SpecificId::None) -> void; + // Build the DISubprogram metadata for the given function. auto BuildDISubprogram(const SemIR::Function& function, const llvm::Function* llvm_function) @@ -152,6 +159,12 @@ class FileContext { // `SpecificId` indexes. We resize this directly to the correct size. llvm::SmallVector specific_functions_; + // Maps which specific functions are generics that need to have their + // definitions lowered after the lowering of other definitions. + // This list may grow while lowering generic definitions from this list. + // The list uses the `SpecificId` to index into specific_functions_. + llvm::SmallVector specific_function_definitions_; + // Provides lowered versions of types. // Vector indexes correspond to `TypeId` indexes for non-symbolic types. We // resize this directly to the (often large) correct size. From 9fc40f86f99ac7b9095105e459453011e6fe315f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 14:03:58 -0800 Subject: [PATCH 26/56] Rename 'long term' to 'long term issue' (#5023) We were discussing this, `long term` only applies to issues and not PRs (per past discussion, we don't really expect PRs should be inactive for months). Renaming to `long term issue` to be more specific and hopefully reduce confusion. --- .github/workflows/triage_inactive.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/triage_inactive.yaml b/.github/workflows/triage_inactive.yaml index 02da7be2d7d79..154836af89d58 100644 --- a/.github/workflows/triage_inactive.yaml +++ b/.github/workflows/triage_inactive.yaml @@ -29,8 +29,8 @@ jobs: stale-issue-message: > We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active - again, please comment or remove the `inactive` label. The `long - term` label can also be added for issues which are expected to take + again, please comment or remove the `inactive` label. The `long term + issue` label can also be added for issues which are expected to take time. @@ -56,7 +56,8 @@ jobs: stale-issue-label: 'inactive' stale-pr-label: 'inactive' exempt-issue-labels: - 'long term,design idea,design update,good first issue,leads question' + 'long term issue,design idea,design update,good first issue,leads + question' days-before-stale: 90 days-before-close: 14 days-before-issue-close: -1 From e5feced8843abd8d60e152a9b9509dbecae8261f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 26 Feb 2025 17:39:11 -0500 Subject: [PATCH 27/56] Avoid crash when deduce fails for imported generic (#5001) An imported generic has bindings which are of type ImportRefLoaded, and if they come from another package, they have no entity name attached to them. Since a binding name is always a constant-time value, we can get the constant value instruction for the imported instruction to get a canonical non-imported instruction. And that one will have a local `NameId`. --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/deduce.cpp | 25 +- .../fail_deduce_imported_function.carbon | 234 ++++++++++++++++++ 2 files changed, 254 insertions(+), 5 deletions(-) create mode 100644 toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index 98341f2b0fb15..e2cca8db8d5fa 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -506,6 +506,25 @@ auto DeductionContext::Deduce() -> bool { return true; } +// Gets the entity name of a generic binding. The generic binding may be an +// imported instruction. +static auto GetEntityNameForGenericBinding(Context& context, + SemIR::InstId binding_id) + -> SemIR::NameId { + // If `binding_id` is imported, it may not have an entity name. Get a + // canonical local instruction from its constant value which does. + if (context.insts().Is(binding_id)) { + binding_id = context.constant_values().GetConstantInstId(binding_id); + } + + if (auto bind_name = + context.insts().TryGetAs(binding_id)) { + return context.entity_names().Get(bind_name->entity_name_id).name_id; + } else { + CARBON_FATAL("Instruction without entity name in generic binding position"); + } +} + auto DeductionContext::CheckDeductionIsComplete() -> bool { // Check we deduced an argument value for every parameter, and convert each // argument to match the final parameter type after substituting any deduced @@ -518,16 +537,12 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool { context().generics().Get(generic_id_).bindings_id)[binding_index]; if (!deduced_arg_id.has_value()) { if (diagnose_) { - auto entity_name_id = context() - .insts() - .GetAs(binding_id) - .entity_name_id; CARBON_DIAGNOSTIC(DeductionIncomplete, Error, "cannot deduce value for generic parameter `{0}`", SemIR::NameId); auto diag = context().emitter().Build( loc_id_, DeductionIncomplete, - context().entity_names().Get(entity_name_id).name_id); + GetEntityNameForGenericBinding(context(), binding_id)); NoteGenericHere(context(), generic_id_, diag); diag.Emit(); } diff --git a/toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon b/toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon new file mode 100644 index 0000000000000..de008ec2ca4f8 --- /dev/null +++ b/toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon @@ -0,0 +1,234 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/no_prelude/fail_deduce_imported_function.carbon + +// --- lib.carbon +package Lib; + +interface Z {} +fn A[T:! Z](x: {.a: T}) {} + +// --- fail_deduce_imported_function.carbon + +import Lib; + +fn A[T:! Lib.Z](x: {.a: T}) {} + +fn B() { + // CHECK:STDERR: fail_deduce_imported_function.carbon:[[@LINE+7]]:3: error: cannot deduce value for generic parameter `T` [DeductionIncomplete] + // CHECK:STDERR: A({.b = {}}); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_deduce_imported_function.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn A[T:! Lib.Z](x: {.a: T}) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + A({.b = {}}); + + // CHECK:STDERR: fail_deduce_imported_function.carbon:[[@LINE+8]]:3: error: cannot deduce value for generic parameter `T` [DeductionIncomplete] + // CHECK:STDERR: Lib.A({.b = {}}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_deduce_imported_function.carbon:[[@LINE-17]]:1: in import [InImport] + // CHECK:STDERR: lib.carbon:4:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn A[T:! Z](x: {.a: T}) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + Lib.A({.b = {}}); +} + +// CHECK:STDOUT: --- lib.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] +// CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %T: %Z.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: %Z.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %T.as_type} [symbolic] +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete: = require_complete_type %struct_type.a [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Z = %Z.decl +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Z.decl: type = interface_decl @Z [concrete = constants.%Z.type] {} {} +// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { +// CHECK:STDOUT: %T.patt.loc4_6.1: %Z.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: %Z.type = value_param_pattern %T.patt.loc4_6.1, runtime_param [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %x.patt: @A.%struct_type.a.loc4_22.2 (%struct_type.a) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @A.%struct_type.a.loc4_22.2 (%struct_type.a) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %Z.type = value_param runtime_param +// CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] +// CHECK:STDOUT: %T.loc4_6.1: %Z.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %x.param: @A.%struct_type.a.loc4_22.2 (%struct_type.a) = value_param runtime_param0 +// CHECK:STDOUT: %.loc4_22: type = splice_block %struct_type.a.loc4_22.1 [symbolic = %struct_type.a.loc4_22.2 (constants.%struct_type.a)] { +// CHECK:STDOUT: %T.ref: %Z.type = name_ref T, %T.loc4_6.1 [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc4_21.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc4_21.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc4_21: type = converted %T.ref, %T.as_type.loc4_21.1 [symbolic = %T.as_type.loc4_21.2 (constants.%T.as_type)] +// CHECK:STDOUT: %struct_type.a.loc4_22.1: type = struct_type {.a: %T.as_type} [symbolic = %struct_type.a.loc4_22.2 (constants.%struct_type.a)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @A.%struct_type.a.loc4_22.2 (%struct_type.a) = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Z { +// CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A(%T.loc4_6.1: %Z.type) { +// CHECK:STDOUT: %T.loc4_6.2: %Z.type = bind_symbolic_name T, 0 [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_6.2: %Z.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.as_type.loc4_21.2: type = facet_access_type %T.loc4_6.2 [symbolic = %T.as_type.loc4_21.2 (constants.%T.as_type)] +// CHECK:STDOUT: %struct_type.a.loc4_22.2: type = struct_type {.a: @A.%T.as_type.loc4_21.2 (%T.as_type)} [symbolic = %struct_type.a.loc4_22.2 (constants.%struct_type.a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.%struct_type.a.loc4_22.2 (%struct_type.a) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %Z.type](%x.param_patt: @A.%struct_type.a.loc4_22.2 (%struct_type.a)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A(constants.%T) { +// CHECK:STDOUT: %T.loc4_6.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_6.2 => constants.%T +// CHECK:STDOUT: %T.as_type.loc4_21.2 => constants.%T.as_type +// CHECK:STDOUT: %struct_type.a.loc4_22.2 => constants.%struct_type.a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_deduce_imported_function.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] +// CHECK:STDOUT: %T: %Z.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: %Z.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %T.as_type} [symbolic] +// CHECK:STDOUT: %A.type.00d: type = fn_type @A.1 [concrete] +// CHECK:STDOUT: %A.1db: %A.type.00d = struct_value () [concrete] +// CHECK:STDOUT: %require_complete: = require_complete_type %struct_type.a [symbolic] +// CHECK:STDOUT: %B.type: type = fn_type @B [concrete] +// CHECK:STDOUT: %B: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %empty_struct_type} [concrete] +// CHECK:STDOUT: %A.type.fad: type = fn_type @A.2 [concrete] +// CHECK:STDOUT: %A.7a0: %A.type.fad = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Lib: = namespace file.%Lib.import, [concrete] { +// CHECK:STDOUT: .Z = %Lib.Z +// CHECK:STDOUT: .A = %Lib.A +// CHECK:STDOUT: import Lib//default +// CHECK:STDOUT: } +// CHECK:STDOUT: %Lib.Z: type = import_ref Lib//default, Z, loaded [concrete = constants.%Z.type] +// CHECK:STDOUT: %Lib.import_ref.f88 = import_ref Lib//default, inst15 [no loc], unloaded +// CHECK:STDOUT: %Lib.A: %A.type.fad = import_ref Lib//default, A, loaded [concrete = constants.%A.7a0] +// CHECK:STDOUT: %Lib.import_ref.9c1: %Z.type = import_ref Lib//default, loc4_6, loaded [symbolic = @A.2.%T (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Lib = imports.%Lib +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Lib.import = import Lib +// CHECK:STDOUT: %A.decl: %A.type.00d = fn_decl @A.1 [concrete = constants.%A.1db] { +// CHECK:STDOUT: %T.patt.loc4_6.1: %Z.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: %Z.type = value_param_pattern %T.patt.loc4_6.1, runtime_param [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %x.patt: @A.1.%struct_type.a.loc4_26.2 (%struct_type.a) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @A.1.%struct_type.a.loc4_26.2 (%struct_type.a) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %Z.type = value_param runtime_param +// CHECK:STDOUT: %.loc4_13: type = splice_block %Z.ref [concrete = constants.%Z.type] { +// CHECK:STDOUT: %Lib.ref: = name_ref Lib, imports.%Lib [concrete = imports.%Lib] +// CHECK:STDOUT: %Z.ref: type = name_ref Z, imports.%Lib.Z [concrete = constants.%Z.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc4_6.1: %Z.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %x.param: @A.1.%struct_type.a.loc4_26.2 (%struct_type.a) = value_param runtime_param0 +// CHECK:STDOUT: %.loc4_26: type = splice_block %struct_type.a.loc4_26.1 [symbolic = %struct_type.a.loc4_26.2 (constants.%struct_type.a)] { +// CHECK:STDOUT: %T.ref: %Z.type = name_ref T, %T.loc4_6.1 [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc4_25.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc4_25.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc4_25: type = converted %T.ref, %T.as_type.loc4_25.1 [symbolic = %T.as_type.loc4_25.2 (constants.%T.as_type)] +// CHECK:STDOUT: %struct_type.a.loc4_26.1: type = struct_type {.a: %T.as_type} [symbolic = %struct_type.a.loc4_26.2 (constants.%struct_type.a)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @A.1.%struct_type.a.loc4_26.2 (%struct_type.a) = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Z [from "lib.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Lib.import_ref.f88 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.1(%T.loc4_6.1: %Z.type) { +// CHECK:STDOUT: %T.loc4_6.2: %Z.type = bind_symbolic_name T, 0 [symbolic = %T.loc4_6.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_6.2: %Z.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.as_type.loc4_25.2: type = facet_access_type %T.loc4_6.2 [symbolic = %T.as_type.loc4_25.2 (constants.%T.as_type)] +// CHECK:STDOUT: %struct_type.a.loc4_26.2: type = struct_type {.a: @A.1.%T.as_type.loc4_25.2 (%T.as_type)} [symbolic = %struct_type.a.loc4_26.2 (constants.%struct_type.a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.1.%struct_type.a.loc4_26.2 (%struct_type.a) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %Z.type](%x.param_patt: @A.1.%struct_type.a.loc4_26.2 (%struct_type.a)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %A.ref.loc14: %A.type.00d = name_ref A, file.%A.decl [concrete = constants.%A.1db] +// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc14_13: %struct_type.b = struct_literal (%.loc14_12) +// CHECK:STDOUT: %Lib.ref: = name_ref Lib, imports.%Lib [concrete = imports.%Lib] +// CHECK:STDOUT: %A.ref.loc24: %A.type.fad = name_ref A, imports.%Lib.A [concrete = constants.%A.7a0] +// CHECK:STDOUT: %.loc24_16: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc24_17: %struct_type.b = struct_literal (%.loc24_16) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.2(imports.%Lib.import_ref.9c1: %Z.type) [from "lib.carbon"] { +// CHECK:STDOUT: %T: %Z.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T.patt: %Z.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic = %T.as_type (constants.%T.as_type)] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: @A.2.%T.as_type (%T.as_type)} [symbolic = %struct_type.a (constants.%struct_type.a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.2.%struct_type.a (%struct_type.a) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %Z.type](%x.param_patt: @A.2.%struct_type.a (%struct_type.a)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.1(constants.%T) { +// CHECK:STDOUT: %T.loc4_6.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_6.2 => constants.%T +// CHECK:STDOUT: %T.as_type.loc4_25.2 => constants.%T.as_type +// CHECK:STDOUT: %struct_type.a.loc4_26.2 => constants.%struct_type.a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.2(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: %T.as_type => constants.%T.as_type +// CHECK:STDOUT: %struct_type.a => constants.%struct_type.a +// CHECK:STDOUT: } +// CHECK:STDOUT: From 0beda27192ccee6dfa67033bac7b554129a2c901 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 26 Feb 2025 17:47:57 -0500 Subject: [PATCH 28/56] Fingerprint `impl` blocks in semir (#5021) This avoids the suffix changing when adding new impls to the prelude, or in user code. --- .../testdata/array/array_vs_tuple.carbon | 4 +- .../testdata/array/assign_return_value.carbon | 4 +- .../check/testdata/array/assign_var.carbon | 4 +- toolchain/check/testdata/array/base.carbon | 4 +- .../testdata/array/canonicalize_index.carbon | 12 +- .../testdata/array/fail_bound_negative.carbon | 8 +- .../fail_out_of_bound_non_literal.carbon | 4 +- .../testdata/array/fail_type_mismatch.carbon | 4 +- .../testdata/array/function_param.carbon | 4 +- .../testdata/array/index_not_literal.carbon | 4 +- .../array/init_dependent_bound.carbon | 12 +- .../check/testdata/array/nine_elements.carbon | 4 +- .../testdata/as/adapter_conversion.carbon | 16 +- toolchain/check/testdata/as/basic.carbon | 4 +- toolchain/check/testdata/as/overloaded.carbon | 20 +- .../testdata/basics/builtin_types.carbon | 4 +- .../fail_numeric_literal_overflow.carbon | 4 +- .../testdata/basics/numeric_literals.carbon | 4 +- toolchain/check/testdata/basics/parens.carbon | 4 +- .../check/testdata/basics/run_i32.carbon | 4 +- .../convert_facet_value_to_facet_value.carbon | 8 +- ..._value_to_generic_facet_value_value.carbon | 38 +-- ...t_value_shouldnt_know_concrete_type.carbon | 8 +- .../value_with_type_through_access.carbon | 4 +- .../testdata/builtins/float/make_type.carbon | 8 +- .../check/testdata/builtins/print/char.carbon | 4 +- .../check/testdata/builtins/print/int.carbon | 4 +- toolchain/check/testdata/choice/basic.carbon | 4 +- .../testdata/choice/fail_todo_params.carbon | 4 +- .../testdata/class/access_modifers.carbon | 16 +- .../testdata/class/adapter/init_adapt.carbon | 8 +- toolchain/check/testdata/class/base.carbon | 4 +- .../check/testdata/class/base_method.carbon | 4 +- toolchain/check/testdata/class/basic.carbon | 4 +- .../testdata/class/derived_to_base.carbon | 4 +- .../class/fail_field_modifiers.carbon | 4 +- .../check/testdata/class/fail_init.carbon | 4 +- .../class/fail_init_as_inplace.carbon | 4 +- .../check/testdata/class/fail_scope.carbon | 4 +- .../check/testdata/class/field_access.carbon | 4 +- .../class/field_access_in_value.carbon | 4 +- .../check/testdata/class/generic/call.carbon | 4 +- .../generic/complete_in_conversion.carbon | 6 +- .../testdata/class/generic/import.carbon | 8 +- .../testdata/class/generic/stringify.carbon | 8 +- toolchain/check/testdata/class/import.carbon | 4 +- .../check/testdata/class/import_base.carbon | 4 +- .../testdata/class/inheritance_access.carbon | 8 +- toolchain/check/testdata/class/init_as.carbon | 4 +- toolchain/check/testdata/class/local.carbon | 4 +- toolchain/check/testdata/class/method.carbon | 4 +- toolchain/check/testdata/class/reorder.carbon | 4 +- .../testdata/class/reorder_qualified.carbon | 4 +- toolchain/check/testdata/class/scope.carbon | 4 +- .../testdata/class/self_conversion.carbon | 4 +- .../class/syntactic_merge_literal.carbon | 8 +- .../testdata/class/virtual_modifiers.carbon | 4 +- toolchain/check/testdata/deduce/array.carbon | 20 +- .../check/testdata/deduce/generic_type.carbon | 4 +- toolchain/check/testdata/deduce/tuple.carbon | 4 +- .../check/testdata/eval/aggregate.carbon | 4 +- .../check/testdata/eval/fail_aggregate.carbon | 4 +- toolchain/check/testdata/eval/symbolic.carbon | 4 +- .../testdata/function/builtin/call.carbon | 8 +- .../testdata/function/builtin/method.carbon | 20 +- .../no_prelude/call_from_operator.carbon | 52 +-- .../check/testdata/function/call/i32.carbon | 4 +- .../function/call/more_param_ir.carbon | 4 +- .../testdata/function/call/params_one.carbon | 4 +- .../function/call/params_one_comma.carbon | 4 +- .../testdata/function/call/params_two.carbon | 4 +- .../function/call/params_two_comma.carbon | 4 +- .../call/prefer_unqualified_lookup.carbon | 4 +- .../function/declaration/import.carbon | 20 +- .../function/definition/import.carbon | 4 +- .../call_method_on_generic_facet.carbon | 16 +- .../testdata/function/generic/deduce.carbon | 8 +- .../function/generic/param_in_type.carbon | 4 +- .../function/generic/undefined.carbon | 12 +- toolchain/check/testdata/generic/local.carbon | 4 +- .../check/testdata/global/simple_init.carbon | 4 +- .../testdata/global/simple_with_fun.carbon | 4 +- .../if/fail_reachable_fallthrough.carbon | 4 +- toolchain/check/testdata/if/fail_scope.carbon | 4 +- .../if/unreachable_fallthrough.carbon | 4 +- toolchain/check/testdata/if_expr/basic.carbon | 4 +- .../if_expr/constant_condition.carbon | 4 +- .../testdata/if_expr/control_flow.carbon | 4 +- .../check/testdata/if_expr/nested.carbon | 4 +- .../check/testdata/if_expr/struct.carbon | 4 +- .../testdata/impl/assoc_const_self.carbon | 28 +- toolchain/check/testdata/impl/compound.carbon | 8 +- .../testdata/impl/extend_impl_generic.carbon | 14 +- .../testdata/impl/fail_call_invalid.carbon | 4 +- .../impl/fail_extend_impl_type_as.carbon | 16 +- .../impl/fail_impl_bad_assoc_fn.carbon | 60 ++-- .../testdata/impl/fail_redefinition.carbon | 8 +- .../impl/fail_todo_use_assoc_const.carbon | 22 +- .../lookup/fail_todo_undefined_impl.carbon | 14 +- .../impl/lookup/no_prelude/import.carbon | 46 +-- .../testdata/impl/multiple_extend.carbon | 60 ++-- .../impl/no_prelude/fail_alias.carbon | 8 +- .../no_prelude/fail_extend_impl_scope.carbon | 26 +- .../impl/no_prelude/fail_impl_as_scope.carbon | 36 +-- .../no_prelude/generic_redeclaration.carbon | 174 +++++----- .../impl/no_prelude/impl_assoc_const.carbon | 32 +- .../impl/no_prelude/import_generic.carbon | 306 +++++++++--------- .../import_interface_assoc_const.carbon | 32 +- .../no_definition_in_impl_file.carbon | 16 +- .../impl/no_prelude/self_in_signature.carbon | 42 +-- .../index/array_element_access.carbon | 4 +- .../check/testdata/index/expr_category.carbon | 4 +- .../index/fail_array_large_index.carbon | 4 +- .../index/fail_array_non_int_indexing.carbon | 4 +- .../fail_array_out_of_bound_access.carbon | 4 +- .../testdata/index/fail_expr_category.carbon | 4 +- .../index/fail_negative_indexing.carbon | 4 +- .../fail_todo_assoc_const_default.carbon | 4 +- .../interface/no_prelude/generic.carbon | 12 +- .../no_prelude/generic_vs_params.carbon | 20 +- .../interface/todo_define_not_default.carbon | 4 +- .../ir/duplicate_name_same_line.carbon | 4 +- .../testdata/let/compile_time_bindings.carbon | 16 +- toolchain/check/testdata/let/convert.carbon | 4 +- .../testdata/let/fail_duplicate_decl.carbon | 4 +- .../check/testdata/let/fail_modifiers.carbon | 4 +- toolchain/check/testdata/let/global.carbon | 4 +- .../check/testdata/let/shadowed_decl.carbon | 4 +- .../testdata/namespace/add_to_import.carbon | 4 +- .../check/testdata/namespace/alias.carbon | 4 +- .../namespace/fail_decl_in_alias.carbon | 4 +- .../check/testdata/namespace/shadow.carbon | 4 +- .../operators/builtin/assignment.carbon | 4 +- .../fail_assignment_to_non_assignable.carbon | 4 +- .../fail_redundant_compound_access.carbon | 4 +- .../fail_type_mismatch_assignment.carbon | 4 +- .../testdata/operators/overloaded/add.carbon | 16 +- .../operators/overloaded/bit_and.carbon | 16 +- .../overloaded/bit_complement.carbon | 8 +- .../operators/overloaded/bit_or.carbon | 16 +- .../operators/overloaded/bit_xor.carbon | 16 +- .../testdata/operators/overloaded/dec.carbon | 8 +- .../testdata/operators/overloaded/div.carbon | 16 +- .../testdata/operators/overloaded/eq.carbon | 16 +- .../overloaded/fail_assign_non_ref.carbon | 16 +- .../overloaded/fail_error_recovery.carbon | 4 +- .../overloaded/fail_no_impl_for_arg.carbon | 16 +- .../operators/overloaded/implicit_as.carbon | 16 +- .../testdata/operators/overloaded/inc.carbon | 8 +- .../operators/overloaded/index.carbon | 14 +- .../operators/overloaded/left_shift.carbon | 16 +- .../testdata/operators/overloaded/mod.carbon | 16 +- .../testdata/operators/overloaded/mul.carbon | 16 +- .../operators/overloaded/negate.carbon | 8 +- .../operators/overloaded/ordered.carbon | 8 +- .../operators/overloaded/right_shift.carbon | 16 +- .../testdata/operators/overloaded/sub.carbon | 16 +- .../check/testdata/package_expr/syntax.carbon | 8 +- .../packages/implicit_imports_prelude.carbon | 4 +- .../check/testdata/packages/raw_core.carbon | 4 +- .../testdata/pointer/address_of_deref.carbon | 4 +- .../testdata/pointer/address_of_lvalue.carbon | 4 +- toolchain/check/testdata/pointer/basic.carbon | 4 +- .../check/testdata/pointer/import.carbon | 4 +- .../return/code_after_return_value.carbon | 4 +- .../fail_return_with_returned_var.carbon | 4 +- .../return/fail_returned_var_shadow.carbon | 4 +- .../no_prelude/import_convert_function.carbon | 100 +++--- .../check/testdata/return/returned_var.carbon | 4 +- .../testdata/return/returned_var_scope.carbon | 4 +- toolchain/check/testdata/return/struct.carbon | 4 +- toolchain/check/testdata/return/tuple.carbon | 4 +- toolchain/check/testdata/return/value.carbon | 4 +- .../struct/fail_non_member_access.carbon | 4 +- toolchain/check/testdata/struct/import.carbon | 12 +- .../testdata/struct/member_access.carbon | 4 +- .../check/testdata/struct/one_entry.carbon | 4 +- .../testdata/struct/partially_const.carbon | 4 +- .../testdata/struct/tuple_as_element.carbon | 4 +- .../check/testdata/struct/two_entries.carbon | 4 +- .../tuple/access/element_access.carbon | 4 +- .../tuple/access/fail_access_error.carbon | 4 +- .../tuple/access/fail_large_index.carbon | 4 +- .../access/fail_negative_indexing.carbon | 4 +- .../access/fail_non_deterministic_type.carbon | 4 +- .../tuple/access/fail_non_int_indexing.carbon | 4 +- .../tuple/access/fail_non_tuple_access.carbon | 4 +- .../access/fail_out_of_bound_access.carbon | 4 +- .../fail_out_of_bound_not_literal.carbon | 4 +- .../tuple/access/index_not_literal.carbon | 12 +- .../tuple/access/return_value_access.carbon | 4 +- .../tuple/fail_element_type_mismatch.carbon | 4 +- toolchain/check/testdata/tuple/import.carbon | 12 +- .../check/testdata/tuple/nested_tuple.carbon | 4 +- .../tuple/nested_tuple_in_place.carbon | 4 +- .../check/testdata/tuple/one_element.carbon | 4 +- .../check/testdata/tuple/two_elements.carbon | 4 +- toolchain/sem_ir/inst_fingerprinter.cpp | 41 ++- toolchain/sem_ir/inst_fingerprinter.h | 3 + toolchain/sem_ir/inst_namer.cpp | 22 +- toolchain/sem_ir/inst_namer.h | 3 +- 201 files changed, 1178 insertions(+), 1161 deletions(-) diff --git a/toolchain/check/testdata/array/array_vs_tuple.carbon b/toolchain/check/testdata/array/array_vs_tuple.carbon index 1708659da78ff..bbaab0be051f4 100644 --- a/toolchain/check/testdata/array/array_vs_tuple.carbon +++ b/toolchain/check/testdata/array/array_vs_tuple.carbon @@ -29,8 +29,8 @@ fn G() { // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/assign_return_value.carbon b/toolchain/check/testdata/array/assign_return_value.carbon index 7a7f6723d6ded..d82e37c0eb71a 100644 --- a/toolchain/check/testdata/array/assign_return_value.carbon +++ b/toolchain/check/testdata/array/assign_return_value.carbon @@ -27,8 +27,8 @@ fn Run() { // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/assign_var.carbon b/toolchain/check/testdata/array/assign_var.carbon index 6d255d0f94440..518c701a2efe0 100644 --- a/toolchain/check/testdata/array/assign_var.carbon +++ b/toolchain/check/testdata/array/assign_var.carbon @@ -24,8 +24,8 @@ var b: array(i32, 3) = a; // CHECK:STDOUT: %tuple.type.37f: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/base.carbon b/toolchain/check/testdata/array/base.carbon index edc9fa2ce27b6..a3ba80fd15c60 100644 --- a/toolchain/check/testdata/array/base.carbon +++ b/toolchain/check/testdata/array/base.carbon @@ -24,8 +24,8 @@ var c: array((), 5) = ((), (), (), (), (),); // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/canonicalize_index.carbon b/toolchain/check/testdata/array/canonicalize_index.carbon index 38a9fb7cc2f3e..06d058e31b842 100644 --- a/toolchain/check/testdata/array/canonicalize_index.carbon +++ b/toolchain/check/testdata/array/canonicalize_index.carbon @@ -31,8 +31,8 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] @@ -43,8 +43,8 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %Convert.specific_fn.787: = specific_function %Convert.bound.ef9, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] @@ -59,8 +59,8 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %Convert.specific_fn.b42: = specific_function %Convert.bound.b30, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %array: %array_type = tuple_value (%int_1.5d2, %int_2.ef8, %int_3.822) [concrete] // CHECK:STDOUT: %int_3.d14: %u32 = int_value 3 [concrete] -// CHECK:STDOUT: %impl_witness.8da2: = impl_witness (imports.%Core.import_ref.823), @impl.45(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e06: type = fn_type @Convert.9, @impl.45(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.8da2: = impl_witness (imports.%Core.import_ref.823), @impl.750(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e06: type = fn_type @Convert.9, @impl.750(%int_32) [concrete] // CHECK:STDOUT: %Convert.47f: %Convert.type.e06 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.84b: %ImplicitAs.type.2fd = facet_value %u32, %impl_witness.8da2 [concrete] // CHECK:STDOUT: %.88a: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.84b [concrete] diff --git a/toolchain/check/testdata/array/fail_bound_negative.carbon b/toolchain/check/testdata/array/fail_bound_negative.carbon index 456d8df51da85..579066cb95689 100644 --- a/toolchain/check/testdata/array/fail_bound_negative.carbon +++ b/toolchain/check/testdata/array/fail_bound_negative.carbon @@ -28,8 +28,8 @@ var a: array(i32, Negate(1)); // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] @@ -37,8 +37,8 @@ var a: array(i32, Negate(1)); // CHECK:STDOUT: %Convert.specific_fn.70c: = specific_function %Convert.bound.ab5, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %int_-1.251: %i32 = int_value -1 [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] diff --git a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon index 43954fdef4a4c..62331a2fe71eb 100644 --- a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon +++ b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon @@ -28,8 +28,8 @@ var b: i32 = a[{.index = 3}.index]; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/fail_type_mismatch.carbon b/toolchain/check/testdata/array/fail_type_mismatch.carbon index a556a25cdc4f2..7f0c6399e1c24 100644 --- a/toolchain/check/testdata/array/fail_type_mismatch.carbon +++ b/toolchain/check/testdata/array/fail_type_mismatch.carbon @@ -54,8 +54,8 @@ var d: array(i32, 3) = t2; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/function_param.carbon b/toolchain/check/testdata/array/function_param.carbon index caad8bcef9e21..c74c05e00ed00 100644 --- a/toolchain/check/testdata/array/function_param.carbon +++ b/toolchain/check/testdata/array/function_param.carbon @@ -33,8 +33,8 @@ fn G() -> i32 { // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/index_not_literal.carbon b/toolchain/check/testdata/array/index_not_literal.carbon index 0e3c910d4b02d..437889ffa3031 100644 --- a/toolchain/check/testdata/array/index_not_literal.carbon +++ b/toolchain/check/testdata/array/index_not_literal.carbon @@ -24,8 +24,8 @@ var b: i32 = a[{.index = 2}.index]; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/array/init_dependent_bound.carbon b/toolchain/check/testdata/array/init_dependent_bound.carbon index 07ca418653f32..df23527f1c927 100644 --- a/toolchain/check/testdata/array/init_dependent_bound.carbon +++ b/toolchain/check/testdata/array/init_dependent_bound.carbon @@ -46,8 +46,8 @@ fn H() { G(3); } // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet [concrete] @@ -147,8 +147,8 @@ fn H() { G(3); } // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] @@ -165,8 +165,8 @@ fn H() { G(3); } // CHECK:STDOUT: %H: %H.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] diff --git a/toolchain/check/testdata/array/nine_elements.carbon b/toolchain/check/testdata/array/nine_elements.carbon index c6ae0fa7781e1..5b5e6e2de1ded 100644 --- a/toolchain/check/testdata/array/nine_elements.carbon +++ b/toolchain/check/testdata/array/nine_elements.carbon @@ -29,8 +29,8 @@ var a: array(i32, 9) = (1, 2, 3, 4, 5, 6, 7, 8, 9); // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon index 6973b6ab118b5..74d08e1ccfdc0 100644 --- a/toolchain/check/testdata/as/adapter_conversion.carbon +++ b/toolchain/check/testdata/as/adapter_conversion.carbon @@ -179,8 +179,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %struct_type.x.y.4cf: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -371,8 +371,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] @@ -558,8 +558,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %struct_type.x.y.4cf: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -674,8 +674,8 @@ var b: B = {.x = 1} as B; // CHECK:STDOUT: %struct_type.x.y.4cf: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/as/basic.carbon b/toolchain/check/testdata/as/basic.carbon index 2c0ad18e9bffe..717a381be8718 100644 --- a/toolchain/check/testdata/as/basic.carbon +++ b/toolchain/check/testdata/as/basic.carbon @@ -22,8 +22,8 @@ fn Main() -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] diff --git a/toolchain/check/testdata/as/overloaded.carbon b/toolchain/check/testdata/as/overloaded.carbon index b19d12245c133..d5af9217cb29e 100644 --- a/toolchain/check/testdata/as/overloaded.carbon +++ b/toolchain/check/testdata/as/overloaded.carbon @@ -35,19 +35,19 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: %As.generic: %As.type.90f = struct_value () [concrete] // CHECK:STDOUT: %As.type.602: type = facet_type <@As, @As(%X)> [concrete] // CHECK:STDOUT: %Convert.type.35b: type = fn_type @Convert.1, @As(%X) [concrete] -// CHECK:STDOUT: %impl_witness.491: = impl_witness (@impl.1.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.491: = impl_witness (@impl.d8c.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.0e3: type = fn_type @Convert.2 [concrete] // CHECK:STDOUT: %Convert.311: %Convert.type.0e3 = struct_value () [concrete] // CHECK:STDOUT: %As.facet.e45: %As.type.602 = facet_value %i32, %impl_witness.491 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.662: = impl_witness (@impl.2.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.662: = impl_witness (@impl.18a.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.c23: type = fn_type @Convert.3 [concrete] // CHECK:STDOUT: %Convert.8bb: %Convert.type.c23 = struct_value () [concrete] // CHECK:STDOUT: %As.facet.831: %As.type.fd4 = facet_value %X, %impl_witness.662 [concrete] // CHECK:STDOUT: %int_4.0c1: Core.IntLiteral = int_value 4 [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.5(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.7, @impl.5(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.7, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet.5e2: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet.5e2 [concrete] @@ -77,7 +77,7 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %X.decl: type = class_decl @X [concrete = constants.%X] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.d8c [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] @@ -85,8 +85,8 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %As.type: type = facet_type <@As, @As(constants.%X)> [concrete = constants.%As.type.602] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.1.%Convert.decl) [concrete = constants.%impl_witness.491] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.d8c.%Convert.decl) [concrete = constants.%impl_witness.491] +// CHECK:STDOUT: impl_decl @impl.18a [concrete] {} { // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %As.ref: %As.type.90f = name_ref As, imports.%Core.As [concrete = constants.%As.generic] @@ -94,7 +94,7 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %As.type: type = facet_type <@As, @As(constants.%i32)> [concrete = constants.%As.type.fd4] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.2.%Convert.decl) [concrete = constants.%impl_witness.662] +// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.18a.%Convert.decl) [concrete = constants.%impl_witness.662] // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %n.patt: %i32 = binding_pattern n // CHECK:STDOUT: } @@ -105,7 +105,7 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: %n: %i32 = bind_name n, @__global_init.%.loc23_32.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %As.type { +// CHECK:STDOUT: impl @impl.d8c: %i32 as %As.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.0e3 = fn_decl @Convert.2 [concrete = constants.%Convert.311] { // CHECK:STDOUT: %self.patt: %i32 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %i32 = value_param_pattern %self.patt, runtime_param0 @@ -129,7 +129,7 @@ let n: i32 = ((4 as i32) as X) as i32; // CHECK:STDOUT: witness = file.%impl_witness.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %X.ref as %As.type { +// CHECK:STDOUT: impl @impl.18a: %X.ref as %As.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.c23 = fn_decl @Convert.3 [concrete = constants.%Convert.8bb] { // CHECK:STDOUT: %self.patt: %X = binding_pattern self // CHECK:STDOUT: %self.param_patt: %X = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/basics/builtin_types.carbon b/toolchain/check/testdata/basics/builtin_types.carbon index cf0ff447a7011..f705be2358ef8 100644 --- a/toolchain/check/testdata/basics/builtin_types.carbon +++ b/toolchain/check/testdata/basics/builtin_types.carbon @@ -21,8 +21,8 @@ var test_type: type = i32; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon b/toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon index 9f86c548fd031..ac7290fac8fa5 100644 --- a/toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon +++ b/toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon @@ -46,8 +46,8 @@ let e: f64 = 5.0e39999999999999999993; // CHECK:STDOUT: %int_39999999999999999993.af6: Core.IntLiteral = int_value 39999999999999999993 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/basics/numeric_literals.carbon b/toolchain/check/testdata/basics/numeric_literals.carbon index adbe4bf535684..f8f449f43a6af 100644 --- a/toolchain/check/testdata/basics/numeric_literals.carbon +++ b/toolchain/check/testdata/basics/numeric_literals.carbon @@ -45,8 +45,8 @@ fn F() { // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/basics/parens.carbon b/toolchain/check/testdata/basics/parens.carbon index f96d3c9c2164f..86ae9ca498168 100644 --- a/toolchain/check/testdata/basics/parens.carbon +++ b/toolchain/check/testdata/basics/parens.carbon @@ -19,8 +19,8 @@ var b: i32 = ((2)); // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/basics/run_i32.carbon b/toolchain/check/testdata/basics/run_i32.carbon index 7a264f14f315b..21633667ba884 100644 --- a/toolchain/check/testdata/basics/run_i32.carbon +++ b/toolchain/check/testdata/basics/run_i32.carbon @@ -20,8 +20,8 @@ fn Run() -> i32 { return 0; } // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_to_facet_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_to_facet_value.carbon index d7d5c31ed99b7..3485ed34eed71 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_to_facet_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_to_facet_value.carbon @@ -175,7 +175,7 @@ fn F() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Eats.decl: type = interface_decl @Eats [concrete = constants.%Eats.type] {} {} // CHECK:STDOUT: %Animal.decl: type = interface_decl @Animal [concrete = constants.%Animal.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.d75 [concrete] {} { // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] // CHECK:STDOUT: } @@ -189,7 +189,7 @@ fn F() { // CHECK:STDOUT: %e.loc13_9.1: %Eats.type = bind_symbolic_name e, 0, %e.param [symbolic = %e.loc13_9.2 (constants.%e)] // CHECK:STDOUT: } // CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.27e [concrete] {} { // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: } @@ -213,12 +213,12 @@ fn F() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Animal.ref as %Eats.ref { +// CHECK:STDOUT: impl @impl.d75: %Animal.ref as %Eats.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc11 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Goat.ref as %Animal.ref { +// CHECK:STDOUT: impl @impl.27e: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc16 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon index 11df252a80d8f..3d60c479749cd 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon @@ -167,7 +167,7 @@ fn F() { // CHECK:STDOUT: %U.as_type: type = facet_access_type %U [symbolic] // CHECK:STDOUT: %Eats.type.f54c3d.1: type = facet_type <@Eats, @Eats(%U.as_type)> [symbolic] // CHECK:STDOUT: %require_complete.42532a.1: = require_complete_type %Eats.type.f54c3d.1 [symbolic] -// CHECK:STDOUT: %impl_witness.c7c36b.1: = impl_witness (), @impl.2(%T.fd4, %U) [symbolic] +// CHECK:STDOUT: %impl_witness.c7c36b.1: = impl_witness (), @impl.009(%T.fd4, %U) [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] // CHECK:STDOUT: %Food.9af: %Edible.type = bind_symbolic_name Food, 0 [symbolic] // CHECK:STDOUT: %Food.patt.0b7: %Edible.type = symbolic_binding_pattern Food, 0 [symbolic] @@ -189,7 +189,7 @@ fn F() { // CHECK:STDOUT: %require_complete.444: = require_complete_type %Food.as_type.fae [symbolic] // CHECK:STDOUT: %Eats.type.f54c3d.2: type = facet_type <@Eats, @Eats(%Food.as_type.fae)> [symbolic] // CHECK:STDOUT: %require_complete.42532a.2: = require_complete_type %Eats.type.f54c3d.2 [symbolic] -// CHECK:STDOUT: %impl_witness.c7c36b.2: = impl_witness (), @impl.2(%T.fd4, %Food.5fe) [symbolic] +// CHECK:STDOUT: %impl_witness.c7c36b.2: = impl_witness (), @impl.009(%T.fd4, %Food.5fe) [symbolic] // CHECK:STDOUT: %Eats.facet.b56: %Eats.type.f54c3d.2 = facet_value %T.as_type.2ad, %impl_witness.c7c36b.2 [symbolic] // CHECK:STDOUT: %Feed.specific_fn.f4b: = specific_function %Feed, @Feed(%Food.5fe, %Eats.facet.b56) [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -201,7 +201,7 @@ fn F() { // CHECK:STDOUT: %HandleAnimal.specific_fn: = specific_function %HandleAnimal, @HandleAnimal(%Animal.facet, %Edible.facet) [concrete] // CHECK:STDOUT: %Eats.type.1ae: type = facet_type <@Eats, @Eats(%Grass)> [concrete] // CHECK:STDOUT: %complete_type.004: = complete_type_witness %Eats.type.1ae [concrete] -// CHECK:STDOUT: %impl_witness.15d: = impl_witness (), @impl.2(%Animal.facet, %Edible.facet) [concrete] +// CHECK:STDOUT: %impl_witness.15d: = impl_witness (), @impl.009(%Animal.facet, %Edible.facet) [concrete] // CHECK:STDOUT: %Eats.facet.c76: %Eats.type.1ae = facet_value %Goat, %impl_witness.15d [concrete] // CHECK:STDOUT: %Feed.specific_fn.e8d: = specific_function %Feed, @Feed(%Edible.facet, %Eats.facet.c76) [concrete] // CHECK:STDOUT: } @@ -227,7 +227,7 @@ fn F() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Edible.decl: type = interface_decl @Edible [concrete = constants.%Edible.type] {} {} // CHECK:STDOUT: %Grass.decl: type = class_decl @Grass [concrete = constants.%Grass] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.592 [concrete] {} { // CHECK:STDOUT: %Grass.ref: type = name_ref Grass, file.%Grass.decl [concrete = constants.%Grass] // CHECK:STDOUT: %Edible.ref: type = name_ref Edible, file.%Edible.decl [concrete = constants.%Edible.type] // CHECK:STDOUT: } @@ -240,7 +240,7 @@ fn F() { // CHECK:STDOUT: %Food.param: type = value_param runtime_param // CHECK:STDOUT: %Food.loc12_16.1: type = bind_symbolic_name Food, 0, %Food.param [symbolic = %Food.loc12_16.2 (constants.%Food.8b3)] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: impl_decl @impl.009 [concrete] { // CHECK:STDOUT: %T.patt.loc17_14.1: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] // CHECK:STDOUT: %T.param_patt: %Animal.type = value_param_pattern %T.patt.loc17_14.1, runtime_param [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] // CHECK:STDOUT: %U.patt.loc17_26.1: %Edible.type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_26.2 (constants.%U.patt)] @@ -261,9 +261,9 @@ fn F() { // CHECK:STDOUT: %Edible.ref: type = name_ref Edible, file.%Edible.decl [concrete = constants.%Edible.type] // CHECK:STDOUT: %U.loc17_26.1: %Edible.type = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc17_26.2 (constants.%U)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (), @impl.2(constants.%T.fd4, constants.%U) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.c7c36b.1)] +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (), @impl.009(constants.%T.fd4, constants.%U) [symbolic = @impl.009.%impl_witness (constants.%impl_witness.c7c36b.1)] // CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.27e [concrete] {} { // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: } @@ -372,12 +372,12 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Grass.ref as %Edible.ref { +// CHECK:STDOUT: impl @impl.592: %Grass.ref as %Edible.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc17_14.1: %Animal.type, %U.loc17_26.1: %Edible.type) { +// CHECK:STDOUT: generic impl @impl.009(%T.loc17_14.1: %Animal.type, %U.loc17_26.1: %Edible.type) { // CHECK:STDOUT: %T.loc17_14.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc17_14.2 (constants.%T.fd4)] // CHECK:STDOUT: %T.patt.loc17_14.2: %Animal.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt.a9c)] // CHECK:STDOUT: %U.loc17_26.2: %Edible.type = bind_symbolic_name U, 1 [symbolic = %U.loc17_26.2 (constants.%U)] @@ -385,8 +385,8 @@ fn F() { // CHECK:STDOUT: %T.as_type.loc17_38.2: type = facet_access_type %T.loc17_14.2 [symbolic = %T.as_type.loc17_38.2 (constants.%T.as_type.2ad)] // CHECK:STDOUT: %U.as_type.loc17_49.2: type = facet_access_type %U.loc17_26.2 [symbolic = %U.as_type.loc17_49.2 (constants.%U.as_type)] // CHECK:STDOUT: %Eats.type.loc17_49.2: type = facet_type <@Eats, @Eats(%U.as_type.loc17_49.2)> [symbolic = %Eats.type.loc17_49.2 (constants.%Eats.type.f54c3d.1)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%Eats.type.loc17_49.2 (%Eats.type.f54c3d.1) [symbolic = %require_complete (constants.%require_complete.42532a.1)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc17_14.2, %U.loc17_26.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.009.%Eats.type.loc17_49.2 (%Eats.type.f54c3d.1) [symbolic = %require_complete (constants.%require_complete.42532a.1)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.009(%T.loc17_14.2, %U.loc17_26.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -396,7 +396,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %Goat.ref as %Animal.ref { +// CHECK:STDOUT: impl @impl.27e: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc20 // CHECK:STDOUT: } @@ -449,7 +449,7 @@ fn F() { // CHECK:STDOUT: %require_complete.loc23_54: = require_complete_type @HandleAnimal.%Food.as_type.loc23_56.2 (%Food.as_type.fae) [symbolic = %require_complete.loc23_54 (constants.%require_complete.444)] // CHECK:STDOUT: %Eats.type: type = facet_type <@Eats, @Eats(%Food.as_type.loc23_56.2)> [symbolic = %Eats.type (constants.%Eats.type.f54c3d.2)] // CHECK:STDOUT: %require_complete.loc23_76: = require_complete_type @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) [symbolic = %require_complete.loc23_76 (constants.%require_complete.42532a.2)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc23_17.2, %Food.loc23_29.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.2)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.009(%T.loc23_17.2, %Food.loc23_29.2) [symbolic = %impl_witness (constants.%impl_witness.c7c36b.2)] // CHECK:STDOUT: %Eats.facet.loc23_76.2: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value %T.as_type.loc23_47.2, %impl_witness [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.b56)] // CHECK:STDOUT: %Feed.specific_fn.loc23_64.2: = specific_function constants.%Feed, @Feed(%Food.loc23_29.2, %Eats.facet.loc23_76.2) [symbolic = %Feed.specific_fn.loc23_64.2 (constants.%Feed.specific_fn.f4b)] // CHECK:STDOUT: @@ -520,7 +520,7 @@ fn F() { // CHECK:STDOUT: %Self.2 => constants.%Self.4eb // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T.fd4, constants.%U) { +// CHECK:STDOUT: specific @impl.009(constants.%T.fd4, constants.%U) { // CHECK:STDOUT: %T.loc17_14.2 => constants.%T.fd4 // CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%T.fd4 // CHECK:STDOUT: %U.loc17_26.2 => constants.%U @@ -532,9 +532,9 @@ fn F() { // CHECK:STDOUT: %impl_witness => constants.%impl_witness.c7c36b.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Eats(@impl.2.%U.as_type.loc17_49.2) {} +// CHECK:STDOUT: specific @Eats(@impl.009.%U.as_type.loc17_49.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc17_14.2, %U.loc17_26.2) {} +// CHECK:STDOUT: specific @impl.009(%T.loc17_14.2, %U.loc17_26.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Eats(constants.%Food.as_type.952) { // CHECK:STDOUT: %Food.loc12_16.2 => constants.%Food.as_type.952 @@ -571,7 +571,7 @@ fn F() { // CHECK:STDOUT: %Self.2 => constants.%Self.4eb // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T.fd4, constants.%Food.5fe) { +// CHECK:STDOUT: specific @impl.009(constants.%T.fd4, constants.%Food.5fe) { // CHECK:STDOUT: %T.loc17_14.2 => constants.%T.fd4 // CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%T.fd4 // CHECK:STDOUT: %U.loc17_26.2 => constants.%Food.5fe @@ -611,7 +611,7 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: specific @Eats(@HandleAnimal.%Food.as_type.loc23_56.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(@HandleAnimal.%T.loc23_17.2, @HandleAnimal.%Food.loc23_29.2) {} +// CHECK:STDOUT: specific @impl.009(@HandleAnimal.%T.loc23_17.2, @HandleAnimal.%Food.loc23_29.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Feed(@HandleAnimal.%Food.loc23_29.2, @HandleAnimal.%Eats.facet.loc23_76.2) {} // CHECK:STDOUT: @@ -642,7 +642,7 @@ fn F() { // CHECK:STDOUT: %Self.2 => constants.%Self.4eb // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%Animal.facet, constants.%Edible.facet) { +// CHECK:STDOUT: specific @impl.009(constants.%Animal.facet, constants.%Edible.facet) { // CHECK:STDOUT: %T.loc17_14.2 => constants.%Animal.facet // CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%Animal.facet // CHECK:STDOUT: %U.loc17_26.2 => constants.%Edible.facet diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_facet_value_shouldnt_know_concrete_type.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_facet_value_shouldnt_know_concrete_type.carbon index c993f8617761a..609485d5b6854 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_facet_value_shouldnt_know_concrete_type.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_convert_facet_value_shouldnt_know_concrete_type.carbon @@ -291,12 +291,12 @@ fn F() { // CHECK:STDOUT: %Eats.decl: type = interface_decl @Eats [concrete = constants.%Eats.type] {} {} // CHECK:STDOUT: %Animal.decl: type = interface_decl @Animal [concrete = constants.%Animal.type] {} {} // CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.27e [concrete] {} { // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc10: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.b88 [concrete] {} { // CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] // CHECK:STDOUT: } @@ -348,12 +348,12 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Goat.ref as %Animal.ref { +// CHECK:STDOUT: impl @impl.27e: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Goat.ref as %Eats.ref { +// CHECK:STDOUT: impl @impl.b88: %Goat.ref as %Eats.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc11 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon index 6a5cee487233c..98e2c218939dc 100644 --- a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon @@ -670,8 +670,8 @@ fn G() { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/builtins/float/make_type.carbon b/toolchain/check/testdata/builtins/float/make_type.carbon index 2c4346c337e40..722807c0de5ed 100644 --- a/toolchain/check/testdata/builtins/float/make_type.carbon +++ b/toolchain/check/testdata/builtins/float/make_type.carbon @@ -97,8 +97,8 @@ var dyn: Float(dyn_size); // CHECK:STDOUT: %int_64.fab: Core.IntLiteral = int_value 64 [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.c81(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.c81(%int_32) [concrete] // CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] // CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] @@ -193,8 +193,8 @@ var dyn: Float(dyn_size); // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32.be0) [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32.be0) [concrete] -// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32.be0) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.c81(%int_32.be0) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.c81(%int_32.be0) [concrete] // CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] // CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/builtins/print/char.carbon b/toolchain/check/testdata/builtins/print/char.carbon index 9d5f6631a341f..f2acd36e7dab2 100644 --- a/toolchain/check/testdata/builtins/print/char.carbon +++ b/toolchain/check/testdata/builtins/print/char.carbon @@ -29,8 +29,8 @@ fn Main() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/builtins/print/int.carbon b/toolchain/check/testdata/builtins/print/int.carbon index 6f62d318e763e..4a34e6aac6066 100644 --- a/toolchain/check/testdata/builtins/print/int.carbon +++ b/toolchain/check/testdata/builtins/print/int.carbon @@ -31,8 +31,8 @@ fn Main() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/choice/basic.carbon b/toolchain/check/testdata/choice/basic.carbon index 28d9c7d469799..d9c18c9bcf5e2 100644 --- a/toolchain/check/testdata/choice/basic.carbon +++ b/toolchain/check/testdata/choice/basic.carbon @@ -165,8 +165,8 @@ fn G() { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.54b: type = facet_type <@ImplicitAs, @ImplicitAs(%u2)> [concrete] // CHECK:STDOUT: %Convert.type.f0e: type = fn_type @Convert.1, @ImplicitAs(%u2) [concrete] -// CHECK:STDOUT: %impl_witness.f5e: = impl_witness (imports.%Core.import_ref.c3d), @impl.1(%int_2.ecc) [concrete] -// CHECK:STDOUT: %Convert.type.70b: type = fn_type @Convert.2, @impl.1(%int_2.ecc) [concrete] +// CHECK:STDOUT: %impl_witness.f5e: = impl_witness (imports.%Core.import_ref.c3d), @impl.86e(%int_2.ecc) [concrete] +// CHECK:STDOUT: %Convert.type.70b: type = fn_type @Convert.2, @impl.86e(%int_2.ecc) [concrete] // CHECK:STDOUT: %Convert.474: %Convert.type.70b = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.54b = facet_value Core.IntLiteral, %impl_witness.f5e [concrete] // CHECK:STDOUT: %.89d: type = fn_type_with_self_type %Convert.type.f0e, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/choice/fail_todo_params.carbon b/toolchain/check/testdata/choice/fail_todo_params.carbon index ec40572bf5fda..d9bc7359f6358 100644 --- a/toolchain/check/testdata/choice/fail_todo_params.carbon +++ b/toolchain/check/testdata/choice/fail_todo_params.carbon @@ -58,8 +58,8 @@ choice C { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.766: type = facet_type <@ImplicitAs, @ImplicitAs(%u1)> [concrete] // CHECK:STDOUT: %Convert.type.5a2: type = fn_type @Convert.1, @ImplicitAs(%u1) [concrete] -// CHECK:STDOUT: %impl_witness.514: = impl_witness (imports.%Core.import_ref.c3d), @impl.1(%int_1.5b8) [concrete] -// CHECK:STDOUT: %Convert.type.f9b: type = fn_type @Convert.2, @impl.1(%int_1.5b8) [concrete] +// CHECK:STDOUT: %impl_witness.514: = impl_witness (imports.%Core.import_ref.c3d), @impl.86e(%int_1.5b8) [concrete] +// CHECK:STDOUT: %Convert.type.f9b: type = fn_type @Convert.2, @impl.86e(%int_1.5b8) [concrete] // CHECK:STDOUT: %Convert.84e: %Convert.type.f9b = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.766 = facet_value Core.IntLiteral, %impl_witness.514 [concrete] // CHECK:STDOUT: %.996: type = fn_type_with_self_type %Convert.type.5a2, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/access_modifers.carbon b/toolchain/check/testdata/class/access_modifers.carbon index b2aaea7657b40..397a72a00b968 100644 --- a/toolchain/check/testdata/class/access_modifers.carbon +++ b/toolchain/check/testdata/class/access_modifers.carbon @@ -156,8 +156,8 @@ class A { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -389,8 +389,8 @@ class A { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -511,8 +511,8 @@ class A { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -590,8 +590,8 @@ class A { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/adapter/init_adapt.carbon b/toolchain/check/testdata/class/adapter/init_adapt.carbon index 28d35cf8a7b1d..b4de25dab27b7 100644 --- a/toolchain/check/testdata/class/adapter/init_adapt.carbon +++ b/toolchain/check/testdata/class/adapter/init_adapt.carbon @@ -107,8 +107,8 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -295,8 +295,8 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/base.carbon b/toolchain/check/testdata/class/base.carbon index 87ff6211577fa..03f674875b171 100644 --- a/toolchain/check/testdata/class/base.carbon +++ b/toolchain/check/testdata/class/base.carbon @@ -67,8 +67,8 @@ class Derived { // CHECK:STDOUT: %struct_type.base.d.a20: type = struct_type {.base: %struct_type.b.a15, .d: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon index 871a4b3c84940..5de2378f7a823 100644 --- a/toolchain/check/testdata/class/base_method.carbon +++ b/toolchain/check/testdata/class/base_method.carbon @@ -42,8 +42,8 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/basic.carbon b/toolchain/check/testdata/class/basic.carbon index 44422475d2f8d..a44dd8f8767af 100644 --- a/toolchain/check/testdata/class/basic.carbon +++ b/toolchain/check/testdata/class/basic.carbon @@ -44,8 +44,8 @@ fn Run() -> i32 { // CHECK:STDOUT: %int_4.0c1: Core.IntLiteral = int_value 4 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/derived_to_base.carbon b/toolchain/check/testdata/class/derived_to_base.carbon index a4568913e90bd..ebbaa46764c50 100644 --- a/toolchain/check/testdata/class/derived_to_base.carbon +++ b/toolchain/check/testdata/class/derived_to_base.carbon @@ -80,8 +80,8 @@ fn ConvertInit() { // CHECK:STDOUT: %struct_type.base.c.136: type = struct_type {.base: %struct_type.base.b.bf0, .c: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/fail_field_modifiers.carbon b/toolchain/check/testdata/class/fail_field_modifiers.carbon index b9818ecda0642..ffa067a8682aa 100644 --- a/toolchain/check/testdata/class/fail_field_modifiers.carbon +++ b/toolchain/check/testdata/class/fail_field_modifiers.carbon @@ -45,8 +45,8 @@ class Class { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/fail_init.carbon b/toolchain/check/testdata/class/fail_init.carbon index 7286595376ba0..3db86a91287ed 100644 --- a/toolchain/check/testdata/class/fail_init.carbon +++ b/toolchain/check/testdata/class/fail_init.carbon @@ -48,8 +48,8 @@ fn F() { // CHECK:STDOUT: %struct_type.a.c: type = struct_type {.a: Core.IntLiteral, .c: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/fail_init_as_inplace.carbon b/toolchain/check/testdata/class/fail_init_as_inplace.carbon index 6164e12b64fd7..90a85a9f943ae 100644 --- a/toolchain/check/testdata/class/fail_init_as_inplace.carbon +++ b/toolchain/check/testdata/class/fail_init_as_inplace.carbon @@ -47,8 +47,8 @@ fn F() { // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/fail_scope.carbon b/toolchain/check/testdata/class/fail_scope.carbon index 9bb78681bb5a8..d22033058dcab 100644 --- a/toolchain/check/testdata/class/fail_scope.carbon +++ b/toolchain/check/testdata/class/fail_scope.carbon @@ -35,8 +35,8 @@ fn G() -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/field_access.carbon b/toolchain/check/testdata/class/field_access.carbon index ad14dd2103c95..4bf5b9a2dfa78 100644 --- a/toolchain/check/testdata/class/field_access.carbon +++ b/toolchain/check/testdata/class/field_access.carbon @@ -35,8 +35,8 @@ fn Run() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/field_access_in_value.carbon b/toolchain/check/testdata/class/field_access_in_value.carbon index 990baf5f096d9..0b3faa350a272 100644 --- a/toolchain/check/testdata/class/field_access_in_value.carbon +++ b/toolchain/check/testdata/class/field_access_in_value.carbon @@ -36,8 +36,8 @@ fn Test() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/generic/call.carbon b/toolchain/check/testdata/class/generic/call.carbon index cbdebed1606af..194ded4d6df4d 100644 --- a/toolchain/check/testdata/class/generic/call.carbon +++ b/toolchain/check/testdata/class/generic/call.carbon @@ -105,8 +105,8 @@ class Outer(T:! type) { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/generic/complete_in_conversion.carbon b/toolchain/check/testdata/class/generic/complete_in_conversion.carbon index f9b57ccc5f8d5..b0b9932b11be8 100644 --- a/toolchain/check/testdata/class/generic/complete_in_conversion.carbon +++ b/toolchain/check/testdata/class/generic/complete_in_conversion.carbon @@ -49,7 +49,7 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %A.generic: %A.type = struct_value () [concrete] // CHECK:STDOUT: %A.dd3: type = class_type @A, @A(%N.51e) [symbolic] // CHECK:STDOUT: %A.elem.500: type = unbound_element_type %A.dd3, %B [symbolic] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %Convert.bound.588: = bound_method %N.51e, %Convert.960 [symbolic] // CHECK:STDOUT: %Convert.specific_fn.18b: = specific_function %Convert.bound.588, @Convert.3(%int_32) [symbolic] @@ -62,8 +62,8 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] diff --git a/toolchain/check/testdata/class/generic/import.carbon b/toolchain/check/testdata/class/generic/import.carbon index 8ac0d19bcb27b..48371f3249f52 100644 --- a/toolchain/check/testdata/class/generic/import.carbon +++ b/toolchain/check/testdata/class/generic/import.carbon @@ -105,8 +105,8 @@ class Class(U:! type) { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -279,8 +279,8 @@ class Class(U:! type) { // CHECK:STDOUT: %struct_type.n.44a: type = struct_type {.n: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.b9e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.ea0: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Main.import_ref.773), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Main.import_ref.773), @impl.a8d(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.a8d(%int_32) [concrete] // CHECK:STDOUT: %Convert.4cb: %Convert.type.e14 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.b9e = facet_value Core.IntLiteral, %impl_witness.847 [concrete] // CHECK:STDOUT: %.088: type = fn_type_with_self_type %Convert.type.ea0, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/generic/stringify.carbon b/toolchain/check/testdata/class/generic/stringify.carbon index 113156bc8604e..d2336ac2d4a75 100644 --- a/toolchain/check/testdata/class/generic/stringify.carbon +++ b/toolchain/check/testdata/class/generic/stringify.carbon @@ -338,8 +338,8 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %int_123.fff: Core.IntLiteral = int_value 123 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -451,8 +451,8 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index 48033d6fc31f1..86673494ea2ba 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -171,8 +171,8 @@ fn Run() { // CHECK:STDOUT: %struct_type.x.c96: type = struct_type {.x: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.c81(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.c81(%int_32) [concrete] // CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] // CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/import_base.carbon b/toolchain/check/testdata/class/import_base.carbon index a6cc24e7a39bf..678d4ee640aea 100644 --- a/toolchain/check/testdata/class/import_base.carbon +++ b/toolchain/check/testdata/class/import_base.carbon @@ -149,8 +149,8 @@ fn Run() { // CHECK:STDOUT: %struct_type.base.6c7: type = struct_type {.base: %struct_type.x.unused.c45} [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.c81(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.c81(%int_32) [concrete] // CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] // CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/inheritance_access.carbon b/toolchain/check/testdata/class/inheritance_access.carbon index 62ac2382c6b9f..e4ec6c955266c 100644 --- a/toolchain/check/testdata/class/inheritance_access.carbon +++ b/toolchain/check/testdata/class/inheritance_access.carbon @@ -477,8 +477,8 @@ class B { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -965,8 +965,8 @@ class B { // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/init_as.carbon b/toolchain/check/testdata/class/init_as.carbon index da461102b8f81..9d9da8ba0b9d8 100644 --- a/toolchain/check/testdata/class/init_as.carbon +++ b/toolchain/check/testdata/class/init_as.carbon @@ -33,8 +33,8 @@ fn F() -> i32 { // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/local.carbon b/toolchain/check/testdata/class/local.carbon index 5468afdd80585..f7b2b8daab438 100644 --- a/toolchain/check/testdata/class/local.carbon +++ b/toolchain/check/testdata/class/local.carbon @@ -43,8 +43,8 @@ class A { // CHECK:STDOUT: %struct_type.n.44a: type = struct_type {.n: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/method.carbon b/toolchain/check/testdata/class/method.carbon index a9f0d75cfdbe7..368d75979f60e 100644 --- a/toolchain/check/testdata/class/method.carbon +++ b/toolchain/check/testdata/class/method.carbon @@ -82,8 +82,8 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %struct_type.k.240: type = struct_type {.k: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/reorder.carbon b/toolchain/check/testdata/class/reorder.carbon index c3cf47d2f7b66..b79a800662112 100644 --- a/toolchain/check/testdata/class/reorder.carbon +++ b/toolchain/check/testdata/class/reorder.carbon @@ -33,8 +33,8 @@ class Class { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/reorder_qualified.carbon b/toolchain/check/testdata/class/reorder_qualified.carbon index b18877408ae6c..654b680aca0c2 100644 --- a/toolchain/check/testdata/class/reorder_qualified.carbon +++ b/toolchain/check/testdata/class/reorder_qualified.carbon @@ -82,8 +82,8 @@ class A { // CHECK:STDOUT: %struct_type.a.a6c: type = struct_type {.a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/scope.carbon b/toolchain/check/testdata/class/scope.carbon index 0c6b327c21d70..56ee16a6aa2bb 100644 --- a/toolchain/check/testdata/class/scope.carbon +++ b/toolchain/check/testdata/class/scope.carbon @@ -42,8 +42,8 @@ fn Run() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/self_conversion.carbon b/toolchain/check/testdata/class/self_conversion.carbon index e43c5f3e86db3..5890ac4b866e1 100644 --- a/toolchain/check/testdata/class/self_conversion.carbon +++ b/toolchain/check/testdata/class/self_conversion.carbon @@ -54,8 +54,8 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/syntactic_merge_literal.carbon b/toolchain/check/testdata/class/syntactic_merge_literal.carbon index 6ca79978a0338..1cccbf24094a6 100644 --- a/toolchain/check/testdata/class/syntactic_merge_literal.carbon +++ b/toolchain/check/testdata/class/syntactic_merge_literal.carbon @@ -46,8 +46,8 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %int_1000.ff9: Core.IntLiteral = int_value 1000 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -187,8 +187,8 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %int_1000.ff9: Core.IntLiteral = int_value 1000 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index dcbb624bb3ece..a5183db06bf14 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -739,8 +739,8 @@ class Derived { // CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/deduce/array.carbon b/toolchain/check/testdata/deduce/array.carbon index ac8e2785d6380..fe45cbe4f96f9 100644 --- a/toolchain/check/testdata/deduce/array.carbon +++ b/toolchain/check/testdata/deduce/array.carbon @@ -140,8 +140,8 @@ fn G() -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -320,8 +320,8 @@ fn G() -> i32 { // CHECK:STDOUT: %require_complete.d82: = require_complete_type %array_type.6a2 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -678,8 +678,8 @@ fn G() -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -860,8 +860,8 @@ fn G() -> i32 { // CHECK:STDOUT: %require_complete.d82: = require_complete_type %array_type.6a2 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -1060,8 +1060,8 @@ fn G() -> i32 { // CHECK:STDOUT: %N.patt.8e2: %i32 = symbolic_binding_pattern N, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/deduce/generic_type.carbon b/toolchain/check/testdata/deduce/generic_type.carbon index 4f0bdac7b52b0..d8cbdb5300ecb 100644 --- a/toolchain/check/testdata/deduce/generic_type.carbon +++ b/toolchain/check/testdata/deduce/generic_type.carbon @@ -751,8 +751,8 @@ fn G() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/deduce/tuple.carbon b/toolchain/check/testdata/deduce/tuple.carbon index fc2129aeb1479..48e4eb75268d3 100644 --- a/toolchain/check/testdata/deduce/tuple.carbon +++ b/toolchain/check/testdata/deduce/tuple.carbon @@ -248,8 +248,8 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/eval/aggregate.carbon b/toolchain/check/testdata/eval/aggregate.carbon index bfda06f3a8866..ce64ccdd9e3aa 100644 --- a/toolchain/check/testdata/eval/aggregate.carbon +++ b/toolchain/check/testdata/eval/aggregate.carbon @@ -28,8 +28,8 @@ var struct_access: array(i32, 1) = (0,) as array(i32, {.a = 3, .b = 1}.b); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/eval/fail_aggregate.carbon b/toolchain/check/testdata/eval/fail_aggregate.carbon index 19e118429f9c4..14ac8a867eda8 100644 --- a/toolchain/check/testdata/eval/fail_aggregate.carbon +++ b/toolchain/check/testdata/eval/fail_aggregate.carbon @@ -33,8 +33,8 @@ var array_index: array(i32, 1) = (0,) as array(i32, ((5, 7, 1, 9) as array(i32, // CHECK:STDOUT: %array_type.f32: type = array_type %int_4, %i32 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/eval/symbolic.carbon b/toolchain/check/testdata/eval/symbolic.carbon index 38eb9e6b065df..c9c4e8ca37390 100644 --- a/toolchain/check/testdata/eval/symbolic.carbon +++ b/toolchain/check/testdata/eval/symbolic.carbon @@ -44,8 +44,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/builtin/call.carbon b/toolchain/check/testdata/function/builtin/call.carbon index 5a7e368a2c503..0f1f3e1d207ae 100644 --- a/toolchain/check/testdata/function/builtin/call.carbon +++ b/toolchain/check/testdata/function/builtin/call.carbon @@ -29,8 +29,8 @@ fn RuntimeCall(a: i32, b: i32) -> i32 { // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] @@ -41,8 +41,8 @@ fn RuntimeCall(a: i32, b: i32) -> i32 { // CHECK:STDOUT: %Convert.specific_fn.787: = specific_function %Convert.bound.ef9, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] diff --git a/toolchain/check/testdata/function/builtin/method.carbon b/toolchain/check/testdata/function/builtin/method.carbon index 40505171ab0a7..7c0376c4da58a 100644 --- a/toolchain/check/testdata/function/builtin/method.carbon +++ b/toolchain/check/testdata/function/builtin/method.carbon @@ -30,7 +30,7 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: %assoc0.a5e: %I.assoc_type = assoc_entity element0, @I.%F.decl [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %impl_witness.da7: = impl_witness (@impl.1.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.da7: = impl_witness (@impl.a9a.%F.decl) [concrete] // CHECK:STDOUT: %F.type.066: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.9ec: %F.type.066 = struct_value () [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %i32, %impl_witness.da7 [concrete] @@ -39,8 +39,8 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.2, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.4(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.4(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] @@ -52,8 +52,8 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.2, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.3, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] @@ -61,8 +61,8 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: %Convert.specific_fn.787: = specific_function %Convert.bound.ef9, @Convert.3(%int_32) [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.4, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.4, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] @@ -90,12 +90,12 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.a9a [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%F.decl) [concrete = constants.%impl_witness.da7] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.a9a.%F.decl) [concrete = constants.%impl_witness.da7] // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %arr.patt: %array_type = binding_pattern arr // CHECK:STDOUT: %.loc19_1: %array_type = var_pattern %arr.patt @@ -176,7 +176,7 @@ var arr: array(i32, (1 as i32).(I.F)(2)); // CHECK:STDOUT: witness = (%F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %I.ref { +// CHECK:STDOUT: impl @impl.a9a: %i32 as %I.ref { // CHECK:STDOUT: %F.decl: %F.type.066 = fn_decl @F.2 [concrete = constants.%F.9ec] { // CHECK:STDOUT: %self.patt: %i32 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %i32 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon b/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon index dacbe3f1669fc..11426e6b8630f 100644 --- a/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon +++ b/toolchain/check/testdata/function/builtin/no_prelude/call_from_operator.carbon @@ -85,7 +85,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %assoc0.a50: %ImplicitAs.assoc_type.94e = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] -// CHECK:STDOUT: %impl_witness.8b6: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.8b6: = impl_witness (@impl.c45.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.c2a: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.4e3: %Op.type.c2a = struct_value () [concrete] // CHECK:STDOUT: %Add.facet: %Add.type = facet_value %i32.builtin, %impl_witness.8b6 [concrete] @@ -94,7 +94,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %Convert.713: %Convert.type.c0d = struct_value () [concrete] // CHECK:STDOUT: %As.assoc_type.567: type = assoc_entity_type %As.type.a09 [concrete] // CHECK:STDOUT: %assoc0.3bd: %As.assoc_type.567 = assoc_entity element0, @As.%Convert.decl [concrete] -// CHECK:STDOUT: %impl_witness.213: = impl_witness (@impl.2.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.213: = impl_witness (@impl.028.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.fc9: type = fn_type @Convert.3 [concrete] // CHECK:STDOUT: %Convert.33c: %Convert.type.fc9 = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.a09 = facet_value Core.IntLiteral, %impl_witness.213 [concrete] @@ -103,7 +103,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %Convert.fcc: %Convert.type.752 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.assoc_type.dd3: type = assoc_entity_type %ImplicitAs.type.11a [concrete] // CHECK:STDOUT: %assoc0.7cc: %ImplicitAs.assoc_type.dd3 = assoc_entity element0, @ImplicitAs.%Convert.decl [concrete] -// CHECK:STDOUT: %impl_witness.48c: = impl_witness (@impl.3.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.48c: = impl_witness (@impl.e13.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.c2a: type = fn_type @Convert.4 [concrete] // CHECK:STDOUT: %Convert.40d: %Convert.type.c2a = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.1ff: %ImplicitAs.type.11a = facet_value Core.IntLiteral, %impl_witness.48c [concrete] @@ -112,7 +112,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %Convert.c73: %Convert.type.60e = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.assoc_type.81c: type = assoc_entity_type %ImplicitAs.type.9fc [concrete] // CHECK:STDOUT: %assoc0.80e: %ImplicitAs.assoc_type.81c = assoc_entity element0, @ImplicitAs.%Convert.decl [concrete] -// CHECK:STDOUT: %impl_witness.caf: = impl_witness (@impl.4.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.caf: = impl_witness (@impl.3df.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.295: type = fn_type @Convert.5 [concrete] // CHECK:STDOUT: %Convert.2bf: %Convert.type.295 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.72d: %ImplicitAs.type.9fc = facet_value %i32.builtin, %impl_witness.caf [concrete] @@ -165,15 +165,15 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc15_22.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc15_22.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c45 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%int_32) [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc19_6.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc19_6.2: type = converted %int.make_type_signed, %.loc19_6.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %Add.ref: type = name_ref Add, file.%Add.decl [concrete = constants.%Add.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.8b6] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.c45.%Op.decl) [concrete = constants.%impl_witness.8b6] +// CHECK:STDOUT: impl_decl @impl.028 [concrete] {} { // CHECK:STDOUT: %IntLiteral.ref: %IntLiteral.type = name_ref IntLiteral, file.%IntLiteral.decl [concrete = constants.%IntLiteral] // CHECK:STDOUT: %int_literal.make_type: init type = call %IntLiteral.ref() [concrete = Core.IntLiteral] // CHECK:STDOUT: %.loc23_17.1: type = value_of_initializer %int_literal.make_type [concrete = Core.IntLiteral] @@ -185,8 +185,8 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc23_28.2: type = converted %int.make_type_signed, %.loc23_28.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %As.type: type = facet_type <@As, @As(constants.%i32.builtin)> [concrete = constants.%As.type.a09] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.2.%Convert.decl) [concrete = constants.%impl_witness.213] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.028.%Convert.decl) [concrete = constants.%impl_witness.213] +// CHECK:STDOUT: impl_decl @impl.e13 [concrete] {} { // CHECK:STDOUT: %IntLiteral.ref: %IntLiteral.type = name_ref IntLiteral, file.%IntLiteral.decl [concrete = constants.%IntLiteral] // CHECK:STDOUT: %int_literal.make_type: init type = call %IntLiteral.ref() [concrete = Core.IntLiteral] // CHECK:STDOUT: %.loc27_17.1: type = value_of_initializer %int_literal.make_type [concrete = Core.IntLiteral] @@ -198,8 +198,8 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc27_36.2: type = converted %int.make_type_signed, %.loc27_36.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%i32.builtin)> [concrete = constants.%ImplicitAs.type.11a] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc27: = impl_witness (@impl.3.%Convert.decl) [concrete = constants.%impl_witness.48c] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc27: = impl_witness (@impl.e13.%Convert.decl) [concrete = constants.%impl_witness.48c] +// CHECK:STDOUT: impl_decl @impl.3df [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %int.make_type_signed: init type = call constants.%Int(%int_32) [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc31_6.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] @@ -211,7 +211,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc31_36.2: type = converted %int_literal.make_type, %.loc31_36.1 [concrete = Core.IntLiteral] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete = constants.%ImplicitAs.type.9fc] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc31: = impl_witness (@impl.4.%Convert.decl) [concrete = constants.%impl_witness.caf] +// CHECK:STDOUT: %impl_witness.loc31: = impl_witness (@impl.3df.%Convert.decl) [concrete = constants.%impl_witness.caf] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Add { @@ -336,7 +336,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc19_6.2 as %Add.ref { +// CHECK:STDOUT: impl @impl.c45: %.loc19_6.2 as %Add.ref { // CHECK:STDOUT: %Op.decl: %Op.type.c2a = fn_decl @Op.2 [concrete = constants.%Op.4e3] { // CHECK:STDOUT: %self.patt: %i32.builtin = binding_pattern self // CHECK:STDOUT: %self.param_patt: %i32.builtin = value_param_pattern %self.patt, runtime_param0 @@ -345,12 +345,12 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %return.patt: %i32.builtin = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %i32.builtin = out_param_pattern %return.patt, runtime_param2 // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.ref.loc20_37: type = name_ref Self, @impl.1.%.loc19_6.2 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %Self.ref.loc20_37: type = name_ref Self, @impl.c45.%.loc19_6.2 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %self.param: %i32.builtin = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref.loc20_15: type = name_ref Self, @impl.1.%.loc19_6.2 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %Self.ref.loc20_15: type = name_ref Self, @impl.c45.%.loc19_6.2 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %self: %i32.builtin = bind_name self, %self.param // CHECK:STDOUT: %other.param: %i32.builtin = value_param runtime_param1 -// CHECK:STDOUT: %Self.ref.loc20_28: type = name_ref Self, @impl.1.%.loc19_6.2 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %Self.ref.loc20_28: type = name_ref Self, @impl.c45.%.loc19_6.2 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %other: %i32.builtin = bind_name other, %other.param // CHECK:STDOUT: %return.param: ref %i32.builtin = out_param runtime_param2 // CHECK:STDOUT: %return: ref %i32.builtin = return_slot %return.param @@ -361,7 +361,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: witness = file.%impl_witness.loc19 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc23_17.2 as %As.type { +// CHECK:STDOUT: impl @impl.028: %.loc23_17.2 as %As.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.fc9 = fn_decl @Convert.3 [concrete = constants.%Convert.33c] { // CHECK:STDOUT: %self.patt: Core.IntLiteral = binding_pattern self // CHECK:STDOUT: %self.param_patt: Core.IntLiteral = value_param_pattern %self.patt, runtime_param0 @@ -373,7 +373,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc24_31.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc24_31.2: type = converted %int.make_type_signed, %.loc24_31.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %self.param: Core.IntLiteral = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.2.%.loc23_17.2 [concrete = Core.IntLiteral] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.028.%.loc23_17.2 [concrete = Core.IntLiteral] // CHECK:STDOUT: %self: Core.IntLiteral = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %i32.builtin = out_param runtime_param1 // CHECK:STDOUT: %return: ref %i32.builtin = return_slot %return.param @@ -384,7 +384,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: witness = file.%impl_witness.loc23 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %.loc27_17.2 as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.e13: %.loc27_17.2 as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.c2a = fn_decl @Convert.4 [concrete = constants.%Convert.40d] { // CHECK:STDOUT: %self.patt: Core.IntLiteral = binding_pattern self // CHECK:STDOUT: %self.param_patt: Core.IntLiteral = value_param_pattern %self.patt, runtime_param0 @@ -396,7 +396,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc28_31.1: type = value_of_initializer %int.make_type_signed [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc28_31.2: type = converted %int.make_type_signed, %.loc28_31.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %self.param: Core.IntLiteral = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.3.%.loc27_17.2 [concrete = Core.IntLiteral] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.e13.%.loc27_17.2 [concrete = Core.IntLiteral] // CHECK:STDOUT: %self: Core.IntLiteral = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %i32.builtin = out_param runtime_param1 // CHECK:STDOUT: %return: ref %i32.builtin = return_slot %return.param @@ -407,7 +407,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: witness = file.%impl_witness.loc27 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: %.loc31_6.2 as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.3df: %.loc31_6.2 as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.295 = fn_decl @Convert.5 [concrete = constants.%Convert.2bf] { // CHECK:STDOUT: %self.patt: %i32.builtin = binding_pattern self // CHECK:STDOUT: %self.param_patt: %i32.builtin = value_param_pattern %self.patt, runtime_param0 @@ -419,7 +419,7 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: %.loc32_42.1: type = value_of_initializer %int_literal.make_type [concrete = Core.IntLiteral] // CHECK:STDOUT: %.loc32_42.2: type = converted %int_literal.make_type, %.loc32_42.1 [concrete = Core.IntLiteral] // CHECK:STDOUT: %self.param: %i32.builtin = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.4.%.loc31_6.2 [concrete = constants.%i32.builtin] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.3df.%.loc31_6.2 [concrete = constants.%i32.builtin] // CHECK:STDOUT: %self: %i32.builtin = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref Core.IntLiteral = out_param runtime_param1 // CHECK:STDOUT: %return: ref Core.IntLiteral = return_slot %return.param @@ -798,22 +798,22 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32)); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%Core.import_ref.c8c7cd.1 as imports.%Core.import_ref.bf0 [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.a1d: imports.%Core.import_ref.c8c7cd.1 as imports.%Core.import_ref.bf0 [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.595 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: imports.%Core.import_ref.8721d7.1 as imports.%Core.import_ref.1e5 [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.2cc: imports.%Core.import_ref.8721d7.1 as imports.%Core.import_ref.1e5 [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.8aa // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: imports.%Core.import_ref.8721d7.2 as imports.%Core.import_ref.4d9 [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.68b: imports.%Core.import_ref.8721d7.2 as imports.%Core.import_ref.4d9 [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.de9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: imports.%Core.import_ref.c8c7cd.2 as imports.%Core.import_ref.efb [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.ddc: imports.%Core.import_ref.c8c7cd.2 as imports.%Core.import_ref.efb [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.3b6 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/call/i32.carbon b/toolchain/check/testdata/function/call/i32.carbon index 08746d3e2dc4a..ed4a4b801aaae 100644 --- a/toolchain/check/testdata/function/call/i32.carbon +++ b/toolchain/check/testdata/function/call/i32.carbon @@ -28,8 +28,8 @@ fn Main() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/more_param_ir.carbon b/toolchain/check/testdata/function/call/more_param_ir.carbon index df71cc07437dd..38ef4e26692f8 100644 --- a/toolchain/check/testdata/function/call/more_param_ir.carbon +++ b/toolchain/check/testdata/function/call/more_param_ir.carbon @@ -32,8 +32,8 @@ fn Main() { // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/params_one.carbon b/toolchain/check/testdata/function/call/params_one.carbon index 077df54672ffc..fb9059fa75d29 100644 --- a/toolchain/check/testdata/function/call/params_one.carbon +++ b/toolchain/check/testdata/function/call/params_one.carbon @@ -27,8 +27,8 @@ fn Main() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/params_one_comma.carbon b/toolchain/check/testdata/function/call/params_one_comma.carbon index c27c15b48a846..be602e999c957 100644 --- a/toolchain/check/testdata/function/call/params_one_comma.carbon +++ b/toolchain/check/testdata/function/call/params_one_comma.carbon @@ -28,8 +28,8 @@ fn Main() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/params_two.carbon b/toolchain/check/testdata/function/call/params_two.carbon index ac41e29711178..c186da1d7b0fc 100644 --- a/toolchain/check/testdata/function/call/params_two.carbon +++ b/toolchain/check/testdata/function/call/params_two.carbon @@ -28,8 +28,8 @@ fn Main() { // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/params_two_comma.carbon b/toolchain/check/testdata/function/call/params_two_comma.carbon index 3d2e9541a534c..6d36bdf32433c 100644 --- a/toolchain/check/testdata/function/call/params_two_comma.carbon +++ b/toolchain/check/testdata/function/call/params_two_comma.carbon @@ -29,8 +29,8 @@ fn Main() { // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon b/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon index a3bb3ee94913b..6db3a2a0e9d02 100644 --- a/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon +++ b/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon @@ -44,8 +44,8 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/declaration/import.carbon b/toolchain/check/testdata/function/declaration/import.carbon index 567548cbad1ba..d66a007bdfc7d 100644 --- a/toolchain/check/testdata/function/declaration/import.carbon +++ b/toolchain/check/testdata/function/declaration/import.carbon @@ -455,8 +455,8 @@ import library "extern_api"; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -632,8 +632,8 @@ import library "extern_api"; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -826,8 +826,8 @@ import library "extern_api"; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.6da: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.b97: = impl_witness (imports.%Core.import_ref.a86), @impl.c81(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.ed5: type = fn_type @Convert.2, @impl.c81(%int_32) [concrete] // CHECK:STDOUT: %Convert.16d: %Convert.type.ed5 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9ba = facet_value Core.IntLiteral, %impl_witness.b97 [concrete] // CHECK:STDOUT: %.39b: type = fn_type_with_self_type %Convert.type.6da, %ImplicitAs.facet [concrete] @@ -1011,8 +1011,8 @@ import library "extern_api"; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -1179,8 +1179,8 @@ import library "extern_api"; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/definition/import.carbon b/toolchain/check/testdata/function/definition/import.carbon index 4a5e9a97fecd0..c12385f3b7906 100644 --- a/toolchain/check/testdata/function/definition/import.carbon +++ b/toolchain/check/testdata/function/definition/import.carbon @@ -249,8 +249,8 @@ fn D() {} // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon index 2a079f7bd8d93..f6eeb8b7909d9 100644 --- a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon +++ b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon @@ -57,7 +57,7 @@ fn G() { // CHECK:STDOUT: %F.118: %F.type.4cf = struct_value () [concrete] // CHECK:STDOUT: %Generic.assoc_type.9f1: type = assoc_entity_type %Generic.type.769 [concrete] // CHECK:STDOUT: %assoc0.9b7: %Generic.assoc_type.9f1 = assoc_entity element0, @Generic.%F.decl [concrete] -// CHECK:STDOUT: %impl_witness.b42: = impl_witness (@impl.1.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.b42: = impl_witness (@impl.046.%F.decl) [concrete] // CHECK:STDOUT: %F.type.17b: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.a56: %F.type.17b = struct_value () [concrete] // CHECK:STDOUT: %Generic.facet.b0a: %Generic.type.769 = facet_value %ImplsGeneric, %impl_witness.b42 [concrete] @@ -67,7 +67,7 @@ fn G() { // CHECK:STDOUT: %G.17f: %G.type.0c6 = struct_value () [concrete] // CHECK:STDOUT: %Other.assoc_type: type = assoc_entity_type %Other.type [concrete] // CHECK:STDOUT: %assoc0.5ce: %Other.assoc_type = assoc_entity element0, @Other.%G.decl [concrete] -// CHECK:STDOUT: %impl_witness.51c: = impl_witness (@impl.2.%G.decl) [concrete] +// CHECK:STDOUT: %impl_witness.51c: = impl_witness (@impl.728.%G.decl) [concrete] // CHECK:STDOUT: %G.type.58d: type = fn_type @G.2 [concrete] // CHECK:STDOUT: %G.b67: %G.type.58d = struct_value () [concrete] // CHECK:STDOUT: %Other.facet: %Other.type = facet_value %ImplsGeneric, %impl_witness.51c [concrete] @@ -124,19 +124,19 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: %GenericParam.decl: type = class_decl @GenericParam [concrete = constants.%GenericParam] {} {} // CHECK:STDOUT: %ImplsGeneric.decl: type = class_decl @ImplsGeneric [concrete = constants.%ImplsGeneric] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.046 [concrete] {} { // CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric] // CHECK:STDOUT: %Generic.ref: %Generic.type.c21 = name_ref Generic, file.%Generic.decl [concrete = constants.%Generic.generic] // CHECK:STDOUT: %GenericParam.ref: type = name_ref GenericParam, file.%GenericParam.decl [concrete = constants.%GenericParam] // CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.1.%F.decl) [concrete = constants.%impl_witness.b42] +// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.046.%F.decl) [concrete = constants.%impl_witness.b42] // CHECK:STDOUT: %Other.decl: type = interface_decl @Other [concrete = constants.%Other.type] {} {} -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.728 [concrete] {} { // CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric] // CHECK:STDOUT: %Other.ref: type = name_ref Other, file.%Other.decl [concrete = constants.%Other.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc25: = impl_witness (@impl.2.%G.decl) [concrete = constants.%impl_witness.51c] +// CHECK:STDOUT: %impl_witness.loc25: = impl_witness (@impl.728.%G.decl) [concrete = constants.%impl_witness.51c] // CHECK:STDOUT: %CallGenericMethod.decl: %CallGenericMethod.type = fn_decl @CallGenericMethod [concrete = constants.%CallGenericMethod] { // CHECK:STDOUT: %T.patt.loc29_22.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc29_22.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc29_22.1, runtime_param [symbolic = %T.patt.loc29_22.2 (constants.%T.patt)] @@ -191,7 +191,7 @@ fn G() { // CHECK:STDOUT: witness = (%G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %ImplsGeneric.ref as %Generic.type { +// CHECK:STDOUT: impl @impl.046: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %F.decl: %F.type.17b = fn_decl @F.2 [concrete = constants.%F.a56] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -199,7 +199,7 @@ fn G() { // CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %ImplsGeneric.ref as %Other.ref { +// CHECK:STDOUT: impl @impl.728: %ImplsGeneric.ref as %Other.ref { // CHECK:STDOUT: %G.decl: %G.type.58d = fn_decl @G.2 [concrete = constants.%G.b67] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: diff --git a/toolchain/check/testdata/function/generic/deduce.carbon b/toolchain/check/testdata/function/generic/deduce.carbon index f16b888b16735..4d17d4f03144c 100644 --- a/toolchain/check/testdata/function/generic/deduce.carbon +++ b/toolchain/check/testdata/function/generic/deduce.carbon @@ -787,8 +787,8 @@ fn CallImplicitNotDeducible() { // CHECK:STDOUT: %TupleParam.specific_fn: = specific_function %TupleParam, @TupleParam(Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -905,8 +905,8 @@ fn CallImplicitNotDeducible() { // CHECK:STDOUT: %StructParam.specific_fn: = specific_function %StructParam, @StructParam(Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/generic/param_in_type.carbon b/toolchain/check/testdata/function/generic/param_in_type.carbon index 8900f918571dc..a77ac2180f798 100644 --- a/toolchain/check/testdata/function/generic/param_in_type.carbon +++ b/toolchain/check/testdata/function/generic/param_in_type.carbon @@ -19,8 +19,8 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %N.patt.8e2: %i32 = symbolic_binding_pattern N, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/function/generic/undefined.carbon b/toolchain/check/testdata/function/generic/undefined.carbon index c19e1a4dec85d..224ebcb007a5b 100644 --- a/toolchain/check/testdata/function/generic/undefined.carbon +++ b/toolchain/check/testdata/function/generic/undefined.carbon @@ -68,8 +68,8 @@ fn CallUndefined() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] @@ -185,8 +185,8 @@ fn CallUndefined() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] @@ -318,8 +318,8 @@ fn CallUndefined() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] diff --git a/toolchain/check/testdata/generic/local.carbon b/toolchain/check/testdata/generic/local.carbon index 641f175f41a29..d144188ce666e 100644 --- a/toolchain/check/testdata/generic/local.carbon +++ b/toolchain/check/testdata/generic/local.carbon @@ -69,8 +69,8 @@ class C(C:! type) { // CHECK:STDOUT: %struct_type.x.c96: type = struct_type {.x: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/global/simple_init.carbon b/toolchain/check/testdata/global/simple_init.carbon index 9d9549460e6d5..c8f2e78737c67 100644 --- a/toolchain/check/testdata/global/simple_init.carbon +++ b/toolchain/check/testdata/global/simple_init.carbon @@ -17,8 +17,8 @@ var a: i32 = 0; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/global/simple_with_fun.carbon b/toolchain/check/testdata/global/simple_with_fun.carbon index 00eebeb2857d4..ebf6ac70c199a 100644 --- a/toolchain/check/testdata/global/simple_with_fun.carbon +++ b/toolchain/check/testdata/global/simple_with_fun.carbon @@ -24,8 +24,8 @@ var a: i32 = test_a(); // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if/fail_reachable_fallthrough.carbon b/toolchain/check/testdata/if/fail_reachable_fallthrough.carbon index 1174cc009cddb..905eff3a7d2d7 100644 --- a/toolchain/check/testdata/if/fail_reachable_fallthrough.carbon +++ b/toolchain/check/testdata/if/fail_reachable_fallthrough.carbon @@ -52,8 +52,8 @@ fn If3(b: bool) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if/fail_scope.carbon b/toolchain/check/testdata/if/fail_scope.carbon index c1b8500456e05..f086365377463 100644 --- a/toolchain/check/testdata/if/fail_scope.carbon +++ b/toolchain/check/testdata/if/fail_scope.carbon @@ -32,8 +32,8 @@ fn VarScope(b: bool) -> i32 { // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if/unreachable_fallthrough.carbon b/toolchain/check/testdata/if/unreachable_fallthrough.carbon index 02144a95149a0..8131a8502f6d8 100644 --- a/toolchain/check/testdata/if/unreachable_fallthrough.carbon +++ b/toolchain/check/testdata/if/unreachable_fallthrough.carbon @@ -29,8 +29,8 @@ fn If(b: bool) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if_expr/basic.carbon b/toolchain/check/testdata/if_expr/basic.carbon index 734a1e68ac92e..35faf791a72b1 100644 --- a/toolchain/check/testdata/if_expr/basic.carbon +++ b/toolchain/check/testdata/if_expr/basic.carbon @@ -28,8 +28,8 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: %tuple.type: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if_expr/constant_condition.carbon b/toolchain/check/testdata/if_expr/constant_condition.carbon index e6f6935c48934..b3eab8029d0ea 100644 --- a/toolchain/check/testdata/if_expr/constant_condition.carbon +++ b/toolchain/check/testdata/if_expr/constant_condition.carbon @@ -41,8 +41,8 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if_expr/control_flow.carbon b/toolchain/check/testdata/if_expr/control_flow.carbon index 748df781e195e..99711eb01180b 100644 --- a/toolchain/check/testdata/if_expr/control_flow.carbon +++ b/toolchain/check/testdata/if_expr/control_flow.carbon @@ -25,8 +25,8 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if_expr/nested.carbon b/toolchain/check/testdata/if_expr/nested.carbon index 437753d6fb5fc..5cccc5bd74bbd 100644 --- a/toolchain/check/testdata/if_expr/nested.carbon +++ b/toolchain/check/testdata/if_expr/nested.carbon @@ -24,8 +24,8 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/if_expr/struct.carbon b/toolchain/check/testdata/if_expr/struct.carbon index c885ee1671189..61b149e35b1c7 100644 --- a/toolchain/check/testdata/if_expr/struct.carbon +++ b/toolchain/check/testdata/if_expr/struct.carbon @@ -33,8 +33,8 @@ fn F(cond: bool) { // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index ed69f1d5d6e7f..0a8d37ec5fcb8 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -130,8 +130,8 @@ fn CallF() { // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -156,7 +156,7 @@ fn CallF() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.f17 [concrete] {} { // CHECK:STDOUT: %.loc8_7.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -175,7 +175,7 @@ fn CallF() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc8: = impl_witness (constants.%empty_struct) [concrete = constants.%impl_witness.a4f] -// CHECK:STDOUT: impl_decl @impl.45 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.ffd [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -220,12 +220,12 @@ fn CallF() { // CHECK:STDOUT: assoc_const V:! @V.%Self.as_type (%Self.as_type.b70); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc8_7.2 as %.loc8_14 { +// CHECK:STDOUT: impl @impl.f17: %.loc8_7.2 as %.loc8_14 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.45: %i32 as %.loc10_15 { +// CHECK:STDOUT: impl @impl.ffd: %i32 as %.loc10_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } @@ -372,7 +372,7 @@ fn CallF() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.15e: type = facet_type <@ImplicitAs, @ImplicitAs(%C)> [concrete] // CHECK:STDOUT: %Convert.type.56d: type = fn_type @Convert.1, @ImplicitAs(%C) [concrete] -// CHECK:STDOUT: %impl_witness.3db: = impl_witness (@impl.1.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.3db: = impl_witness (@impl.e86.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.721: type = fn_type @Convert.2 [concrete] // CHECK:STDOUT: %Convert.155: %Convert.type.721 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.15e = facet_value %empty_tuple.type, %impl_witness.3db [concrete] @@ -409,7 +409,7 @@ fn CallF() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.e86 [concrete] {} { // CHECK:STDOUT: %.loc10_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] @@ -417,8 +417,8 @@ fn CallF() { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%C)> [concrete = constants.%ImplicitAs.type.15e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (@impl.1.%Convert.decl) [concrete = constants.%impl_witness.3db] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (@impl.e86.%Convert.decl) [concrete = constants.%impl_witness.3db] +// CHECK:STDOUT: impl_decl @impl.979 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -465,7 +465,7 @@ fn CallF() { // CHECK:STDOUT: assoc_const V:! @V.%Self.as_type (%Self.as_type.b70); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc10_7.2 as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.e86: %.loc10_7.2 as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.721 = fn_decl @Convert.2 [concrete = constants.%Convert.155] { // CHECK:STDOUT: %self.patt: %empty_tuple.type = binding_pattern self // CHECK:STDOUT: %self.param_patt: %empty_tuple.type = value_param_pattern %self.patt, runtime_param0 @@ -489,7 +489,7 @@ fn CallF() { // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %.loc18_13 { +// CHECK:STDOUT: impl @impl.979: %C.ref as %.loc18_13 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } @@ -596,7 +596,7 @@ fn CallF() { // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc4_13.1: Core.IntLiteral = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc4_13.2 (constants.%N)] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.7 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.19e [concrete] {} { // CHECK:STDOUT: %.loc15_7.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] @@ -657,7 +657,7 @@ fn CallF() { // CHECK:STDOUT: assoc_const V:! @V.%array_type (%array_type); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.7: %.loc15_7.2 as %.loc15_18 { +// CHECK:STDOUT: impl @impl.19e: %.loc15_7.2 as %.loc15_18 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/compound.carbon b/toolchain/check/testdata/impl/compound.carbon index 2836b02c51eab..8981aad232583 100644 --- a/toolchain/check/testdata/impl/compound.carbon +++ b/toolchain/check/testdata/impl/compound.carbon @@ -50,7 +50,7 @@ fn InstanceCallIndirect(p: i32*) { // CHECK:STDOUT: %assoc1: %Simple.assoc_type = assoc_entity element1, @Simple.%G.decl [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %impl_witness.5b2: = impl_witness (@impl.1.%F.decl, @impl.1.%G.decl) [concrete] +// CHECK:STDOUT: %impl_witness.5b2: = impl_witness (@impl.006.%F.decl, @impl.006.%G.decl) [concrete] // CHECK:STDOUT: %F.type.758: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.df1: %F.type.758 = struct_value () [concrete] // CHECK:STDOUT: %G.type.c98: type = fn_type @G.2 [concrete] @@ -88,12 +88,12 @@ fn InstanceCallIndirect(p: i32*) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Simple.decl: type = interface_decl @Simple [concrete = constants.%Simple.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.006 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Simple.ref: type = name_ref Simple, file.%Simple.decl [concrete = constants.%Simple.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%F.decl, @impl.1.%G.decl) [concrete = constants.%impl_witness.5b2] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.006.%F.decl, @impl.006.%G.decl) [concrete = constants.%impl_witness.5b2] // CHECK:STDOUT: %NonInstanceCall.decl: %NonInstanceCall.type = fn_decl @NonInstanceCall [concrete = constants.%NonInstanceCall] { // CHECK:STDOUT: %n.patt: %i32 = binding_pattern n // CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0 @@ -167,7 +167,7 @@ fn InstanceCallIndirect(p: i32*) { // CHECK:STDOUT: witness = (%F.decl, %G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %Simple.ref { +// CHECK:STDOUT: impl @impl.006: %i32 as %Simple.ref { // CHECK:STDOUT: %F.decl: %F.type.758 = fn_decl @F.2 [concrete = constants.%F.df1] {} {} // CHECK:STDOUT: %G.decl: %G.type.c98 = fn_decl @G.2 [concrete = constants.%G.e73] { // CHECK:STDOUT: %self.patt: %i32 = binding_pattern self diff --git a/toolchain/check/testdata/impl/extend_impl_generic.carbon b/toolchain/check/testdata/impl/extend_impl_generic.carbon index 3f8457a749eda..00003fa7e897c 100644 --- a/toolchain/check/testdata/impl/extend_impl_generic.carbon +++ b/toolchain/check/testdata/impl/extend_impl_generic.carbon @@ -72,7 +72,7 @@ class X(U:! type) { // CHECK:STDOUT: %F.eff: %F.type.7f1 = struct_value () [concrete] // CHECK:STDOUT: %HasF.assoc_type.dc4: type = assoc_entity_type %HasF.type.b18 [concrete] // CHECK:STDOUT: %assoc0.a6b: %HasF.assoc_type.dc4 = assoc_entity element0, @HasF.%F.decl [concrete] -// CHECK:STDOUT: %impl_witness.9bf: = impl_witness (@impl.1.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.9bf: = impl_witness (@impl.3b1.%F.decl) [concrete] // CHECK:STDOUT: %F.type.94c: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.901: %F.type.94c = struct_value () [concrete] // CHECK:STDOUT: %HasF.facet: %HasF.type.b18 = facet_value %C, %impl_witness.9bf [concrete] @@ -82,8 +82,8 @@ class X(U:! type) { // CHECK:STDOUT: %struct_type.x.c96: type = struct_type {.x: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -166,7 +166,7 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %HasF.type { +// CHECK:STDOUT: impl @impl.3b1: %Self.ref as %HasF.type { // CHECK:STDOUT: %F.decl: %F.type.94c = fn_decl @F.2 [concrete = constants.%F.901] { // CHECK:STDOUT: %return.patt: %Param = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %Param = out_param_pattern %return.patt, runtime_param0 @@ -197,13 +197,13 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.3b1 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %HasF.ref: %HasF.type.fe3 = name_ref HasF, file.%HasF.decl [concrete = constants.%HasF.generic] // CHECK:STDOUT: %Param.ref: type = name_ref Param, file.%Param.decl [concrete = constants.%Param] // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF, @HasF(constants.%Param)> [concrete = constants.%HasF.type.b18] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%F.decl) [concrete = constants.%impl_witness.9bf] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.3b1.%F.decl) [concrete = constants.%impl_witness.9bf] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -212,7 +212,7 @@ class X(U:! type) { // CHECK:STDOUT: .HasF = // CHECK:STDOUT: .Param = // CHECK:STDOUT: .F = -// CHECK:STDOUT: extend @impl.1.%HasF.type +// CHECK:STDOUT: extend @impl.3b1.%HasF.type // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F.1(@HasF.%T.loc4_16.1: type, @HasF.%Self.1: @HasF.%HasF.type (%HasF.type.901)) { diff --git a/toolchain/check/testdata/impl/fail_call_invalid.carbon b/toolchain/check/testdata/impl/fail_call_invalid.carbon index 640482b37b563..8686608e0eaa0 100644 --- a/toolchain/check/testdata/impl/fail_call_invalid.carbon +++ b/toolchain/check/testdata/impl/fail_call_invalid.carbon @@ -62,7 +62,7 @@ fn InstanceCall(n: i32) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Simple.decl: type = interface_decl @Simple [concrete = constants.%Simple.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.006 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Simple.ref: type = name_ref Simple, file.%Simple.decl [concrete = constants.%Simple.type] @@ -103,7 +103,7 @@ fn InstanceCall(n: i32) { // CHECK:STDOUT: witness = (%G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %Simple.ref { +// CHECK:STDOUT: impl @impl.006: %i32 as %Simple.ref { // CHECK:STDOUT: %G.decl: %G.type.c98 = fn_decl @G.2 [concrete = constants.%G.e73] { // CHECK:STDOUT: %self.patt: = binding_pattern self // CHECK:STDOUT: %self.param_patt: = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon b/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon index f666e96303506..65e87c93b8600 100644 --- a/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon +++ b/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon @@ -90,20 +90,20 @@ class E { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %I.ref { +// CHECK:STDOUT: impl @impl.154: %i32 as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %D.ref as %I.ref; +// CHECK:STDOUT: impl @impl.ca7: %D.ref as %I.ref; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.c98: %Self.ref as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = @E.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.154 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -119,7 +119,7 @@ class E { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.ca7 [concrete] {} { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -131,11 +131,11 @@ class E { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: .D = // CHECK:STDOUT: .I = -// CHECK:STDOUT: extend @impl.2.%I.ref +// CHECK:STDOUT: extend @impl.ca7.%I.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @E { -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c98 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -146,6 +146,6 @@ class E { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%E // CHECK:STDOUT: .I = -// CHECK:STDOUT: extend @impl.3.%I.ref +// CHECK:STDOUT: extend @impl.c98.%I.ref // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon index 4f7df849a7641..67b409536b9d4 100644 --- a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon +++ b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon @@ -472,13 +472,13 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = (%F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.0c9: %Self.ref as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: .F = // CHECK:STDOUT: witness = @NoF.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.b55: %Self.ref as %I.ref { // CHECK:STDOUT: %F.decl: type = class_decl @F.16 [concrete = constants.%F.70c] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -486,7 +486,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FNotFunction.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.199: %Self.ref as %I.ref { // CHECK:STDOUT: %PossiblyF.ref: %PossiblyF.type = name_ref PossiblyF, file.%PossiblyF.decl [concrete = constants.%PossiblyF] // CHECK:STDOUT: %F: %PossiblyF.type = bind_alias F, file.%PossiblyF.decl [concrete = constants.%PossiblyF] // CHECK:STDOUT: @@ -496,7 +496,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FAlias.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.ddd: %Self.ref as %I.ref { // CHECK:STDOUT: %F.decl: %F.type.44e = fn_decl @F.2 [concrete = constants.%F.424] { // CHECK:STDOUT: %b.patt: bool = binding_pattern b // CHECK:STDOUT: %b.param_patt: bool = value_param_pattern %b.patt, runtime_param0 @@ -515,7 +515,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraParam.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.5: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.698: %Self.ref as %I.ref { // CHECK:STDOUT: %F.decl: %F.type.e1a = fn_decl @F.3 [concrete = constants.%F.6ff] { // CHECK:STDOUT: %self.patt: %FExtraImplicitParam = binding_pattern self // CHECK:STDOUT: %self.param_patt: %FExtraImplicitParam = value_param_pattern %self.patt, runtime_param0 @@ -530,7 +530,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraImplicitParam.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.6: %Self.ref as %I.ref { +// CHECK:STDOUT: impl @impl.77b: %Self.ref as %I.ref { // CHECK:STDOUT: %F.decl: %F.type.387 = fn_decl @F.4 [concrete = constants.%F.df5] { // CHECK:STDOUT: %return.patt: bool = return_slot_pattern // CHECK:STDOUT: %return.param_patt: bool = out_param_pattern %return.patt, runtime_param0 @@ -547,7 +547,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraReturnType.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.7: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.5cf: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.695 = fn_decl @F.6 [concrete = constants.%F.738] { // CHECK:STDOUT: %self.patt: bool = binding_pattern self // CHECK:STDOUT: %self.param_patt: bool = value_param_pattern %self.patt, runtime_param0 @@ -573,7 +573,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingParam.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.8: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.bac: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.d97 = fn_decl @F.7 [concrete = constants.%F.01d] { // CHECK:STDOUT: %b.patt: bool = binding_pattern b // CHECK:STDOUT: %b.param_patt: bool = value_param_pattern %b.patt, runtime_param0 @@ -599,7 +599,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingImplicitParam.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.9: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.1a7: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.123 = fn_decl @F.8 [concrete = constants.%F.c7d] { // CHECK:STDOUT: %self.patt: bool = binding_pattern self // CHECK:STDOUT: %self.param_patt: bool = value_param_pattern %self.patt, runtime_param0 @@ -627,7 +627,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingReturnType.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.10: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.f2b: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.6b5 = fn_decl @F.9 [concrete = constants.%F.043] { // CHECK:STDOUT: %self.patt: bool = binding_pattern self // CHECK:STDOUT: %self.param_patt: bool = value_param_pattern %self.patt, runtime_param0 @@ -658,7 +658,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentParamType.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.11: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.db4: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.d62 = fn_decl @F.10 [concrete = constants.%F.886] { // CHECK:STDOUT: %self.patt: %FDifferentImplicitParamType = binding_pattern self // CHECK:STDOUT: %self.param_patt: %FDifferentImplicitParamType = value_param_pattern %self.patt, runtime_param0 @@ -689,7 +689,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentImplicitParamType.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.12: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.fcc: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.d3b = fn_decl @F.11 [concrete = constants.%F.be8] { // CHECK:STDOUT: %self.patt: bool = binding_pattern self // CHECK:STDOUT: %self.param_patt: bool = value_param_pattern %self.patt, runtime_param0 @@ -722,7 +722,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentReturnType.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.13: %Self.ref as %J.ref { +// CHECK:STDOUT: impl @impl.c5d: %Self.ref as %J.ref { // CHECK:STDOUT: %F.decl: %F.type.d19 = fn_decl @F.12 [concrete = constants.%F.669] { // CHECK:STDOUT: %self.patt: bool = binding_pattern self // CHECK:STDOUT: %self.param_patt: bool = value_param_pattern %self.patt, runtime_param0 @@ -757,7 +757,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentParamName.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.14: %Self.ref as %SelfNested.ref { +// CHECK:STDOUT: impl @impl.6a5: %Self.ref as %SelfNested.ref { // CHECK:STDOUT: %F.decl: %F.type.f90 = fn_decl @F.14 [concrete = constants.%F.fa8] { // CHECK:STDOUT: %x.patt: %tuple.type.a7d = binding_pattern x // CHECK:STDOUT: %x.param_patt: %tuple.type.a7d = value_param_pattern %x.patt, runtime_param0 @@ -790,7 +790,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @SelfNestedBadParam.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.15: %Self.ref as %SelfNested.ref { +// CHECK:STDOUT: impl @impl.bfc: %Self.ref as %SelfNested.ref { // CHECK:STDOUT: %F.decl: %F.type.0e7 = fn_decl @F.15 [concrete = constants.%F.0bc] { // CHECK:STDOUT: %x.patt: %tuple.type.eb9 = binding_pattern x // CHECK:STDOUT: %x.param_patt: %tuple.type.eb9 = value_param_pattern %x.patt, runtime_param0 @@ -824,7 +824,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @NoF { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.0c9 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoF [concrete = constants.%NoF] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -838,7 +838,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FNotFunction { -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.b55 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FNotFunction [concrete = constants.%FNotFunction] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -854,7 +854,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: class @F.16; // CHECK:STDOUT: // CHECK:STDOUT: class @FAlias { -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.199 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FAlias [concrete = constants.%FAlias] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -869,7 +869,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FExtraParam { -// CHECK:STDOUT: impl_decl @impl.4 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.ddd [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraParam [concrete = constants.%FExtraParam] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -883,7 +883,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FExtraImplicitParam { -// CHECK:STDOUT: impl_decl @impl.5 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.698 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraImplicitParam [concrete = constants.%FExtraImplicitParam] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -897,7 +897,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FExtraReturnType { -// CHECK:STDOUT: impl_decl @impl.6 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.77b [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraReturnType [concrete = constants.%FExtraReturnType] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -911,7 +911,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FMissingParam { -// CHECK:STDOUT: impl_decl @impl.7 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.5cf [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingParam [concrete = constants.%FMissingParam] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -925,7 +925,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FMissingImplicitParam { -// CHECK:STDOUT: impl_decl @impl.8 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.bac [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingImplicitParam [concrete = constants.%FMissingImplicitParam] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -939,7 +939,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FMissingReturnType { -// CHECK:STDOUT: impl_decl @impl.9 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.1a7 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingReturnType [concrete = constants.%FMissingReturnType] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -953,7 +953,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FDifferentParamType { -// CHECK:STDOUT: impl_decl @impl.10 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.f2b [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentParamType [concrete = constants.%FDifferentParamType] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -967,7 +967,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FDifferentImplicitParamType { -// CHECK:STDOUT: impl_decl @impl.11 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.db4 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentImplicitParamType [concrete = constants.%FDifferentImplicitParamType] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -981,7 +981,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FDifferentReturnType { -// CHECK:STDOUT: impl_decl @impl.12 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.fcc [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentReturnType [concrete = constants.%FDifferentReturnType] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -995,7 +995,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @FDifferentParamName { -// CHECK:STDOUT: impl_decl @impl.13 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c5d [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentParamName [concrete = constants.%FDifferentParamName] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: } @@ -1009,7 +1009,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @SelfNestedBadParam { -// CHECK:STDOUT: impl_decl @impl.14 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.6a5 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadParam [concrete = constants.%SelfNestedBadParam] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } @@ -1024,7 +1024,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @SelfNestedBadReturnType { -// CHECK:STDOUT: impl_decl @impl.15 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.bfc [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadReturnType [concrete = constants.%SelfNestedBadReturnType] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/fail_redefinition.carbon b/toolchain/check/testdata/impl/fail_redefinition.carbon index d66852e8ed841..e76425ed0d40b 100644 --- a/toolchain/check/testdata/impl/fail_redefinition.carbon +++ b/toolchain/check/testdata/impl/fail_redefinition.carbon @@ -46,13 +46,13 @@ impl i32 as I {} // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.a9ac64.1 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc13: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.a9ac64.2 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -68,12 +68,12 @@ impl i32 as I {} // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %I.ref { +// CHECK:STDOUT: impl @impl.a9ac64.1: %i32 as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %i32 as %I.ref { +// CHECK:STDOUT: impl @impl.a9ac64.2: %i32 as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc22 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon index 1e63545e1f43a..cb1f72386fb8d 100644 --- a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon @@ -131,7 +131,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.2d9 [concrete] {} { // CHECK:STDOUT: %.loc22_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc22_7.2: type = converted %.loc22_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] @@ -150,7 +150,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc22: = impl_witness (constants.%empty_struct_type, ) [concrete = constants.%impl_witness.f71] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.fb4 [concrete] {} { // CHECK:STDOUT: %C.ref.loc31_6: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -212,7 +212,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc22_7.2 as %.loc22_14 { +// CHECK:STDOUT: impl @impl.2d9: %.loc22_7.2 as %.loc22_14 { // CHECK:STDOUT: %F.decl: %F.type.159 = fn_decl @F.2 [concrete = constants.%F.59d] { // CHECK:STDOUT: %self.patt: %empty_tuple.type = binding_pattern self // CHECK:STDOUT: %self.param_patt: %empty_tuple.type = value_param_pattern %self.patt, runtime_param0 @@ -224,7 +224,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %.loc23_31.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc23_31.2: type = converted %.loc23_31.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %self.param: %empty_tuple.type = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.1.%.loc22_7.2 [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.2d9.%.loc22_7.2 [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %self: %empty_tuple.type = bind_name self, %self.param // CHECK:STDOUT: %u.param: %empty_struct_type = value_param runtime_param1 // CHECK:STDOUT: %.loc23_24.1: type = splice_block %.loc23_24.3 [concrete = constants.%empty_struct_type] { @@ -241,7 +241,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: witness = file.%impl_witness.loc22 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref.loc31_6 as %.loc31_13 { +// CHECK:STDOUT: impl @impl.fb4: %C.ref.loc31_6 as %.loc31_13 { // CHECK:STDOUT: %F.decl: %F.type.01a = fn_decl @F.3 [concrete = constants.%F.686] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -252,7 +252,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } { // CHECK:STDOUT: %C.ref.loc32_29: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %self.param: %C = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.2.%C.ref.loc31_6 [concrete = constants.%C] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.fb4.%C.ref.loc31_6 [concrete = constants.%C] // CHECK:STDOUT: %self: %C = bind_name self, %self.param // CHECK:STDOUT: %u.param: %C = value_param runtime_param1 // CHECK:STDOUT: %C.ref.loc32_23: type = name_ref C, file.%C.decl [concrete = constants.%C] @@ -472,8 +472,8 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -511,7 +511,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.44 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.581 [concrete] {} { // CHECK:STDOUT: %.loc15_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -576,7 +576,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: assoc_const N:! %i32; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.44: %.loc15_7.2 as %.loc15_14 { +// CHECK:STDOUT: impl @impl.581: %.loc15_7.2 as %.loc15_14 { // CHECK:STDOUT: %F.decl: %F.type.9f6 = fn_decl @F.2 [concrete = constants.%F.572] { // CHECK:STDOUT: %self.patt: %empty_tuple.type = binding_pattern self // CHECK:STDOUT: %self.param_patt: %empty_tuple.type = value_param_pattern %self.patt, runtime_param0 @@ -589,7 +589,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %.loc16_31.2: type = converted %bool.make_type, %.loc16_31.1 [concrete = bool] // CHECK:STDOUT: %array_type: type = array_type %int_2, bool [concrete = constants.%array_type] // CHECK:STDOUT: %self.param: %empty_tuple.type = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.44.%.loc15_7.2 [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.581.%.loc15_7.2 [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %self: %empty_tuple.type = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %array_type = out_param runtime_param1 // CHECK:STDOUT: %return: ref %array_type = return_slot %return.param diff --git a/toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon b/toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon index 7321a51a1fd19..a6e9025f159ab 100644 --- a/toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon +++ b/toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon @@ -55,7 +55,7 @@ impl C as I { // CHECK:STDOUT: %F.c41: %F.type.b25 = struct_value () [concrete] // CHECK:STDOUT: %I.facet.b45: %I.type = facet_value %C, %impl_witness.85b [concrete] // CHECK:STDOUT: %.575: type = fn_type_with_self_type %F.type.cf0, %I.facet.b45 [concrete] -// CHECK:STDOUT: %impl_witness.054: = impl_witness (@impl.2.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.054: = impl_witness (@impl.770.%F.decl) [concrete] // CHECK:STDOUT: %F.type.5d6: type = fn_type @F.3 [concrete] // CHECK:STDOUT: %F.a2e: %F.type.5d6 = struct_value () [concrete] // CHECK:STDOUT: %I.facet.4ac: %I.type = facet_value %C, %impl_witness.054 [concrete] @@ -88,11 +88,11 @@ impl C as I { // CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.770 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.2.%F.decl) [concrete = constants.%impl_witness.054] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.770.%F.decl) [concrete = constants.%impl_witness.054] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { @@ -106,9 +106,9 @@ impl C as I { // CHECK:STDOUT: witness = (%F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %I.ref; +// CHECK:STDOUT: impl @impl.a21: %Self.ref as %I.ref; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %I.ref { +// CHECK:STDOUT: impl @impl.770: %C.ref as %I.ref { // CHECK:STDOUT: %F.decl: %F.type.5d6 = fn_decl @F.3 [concrete = constants.%F.a2e] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -117,7 +117,7 @@ impl C as I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.a21 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -129,7 +129,7 @@ impl C as I { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: .I = // CHECK:STDOUT: .F = -// CHECK:STDOUT: extend @impl.1.%I.ref +// CHECK:STDOUT: extend @impl.a21.%I.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F.1(@I.%Self: %I.type) { diff --git a/toolchain/check/testdata/impl/lookup/no_prelude/import.carbon b/toolchain/check/testdata/impl/lookup/no_prelude/import.carbon index 637433eec4be8..ea6196e5b8a19 100644 --- a/toolchain/check/testdata/impl/lookup/no_prelude/import.carbon +++ b/toolchain/check/testdata/impl/lookup/no_prelude/import.carbon @@ -275,7 +275,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %impl_witness.722: = impl_witness (@impl.1.%G.decl) [concrete] +// CHECK:STDOUT: %impl_witness.722: = impl_witness (@impl.e95.%G.decl) [concrete] // CHECK:STDOUT: %G.type.05c: type = fn_type @G.2 [concrete] // CHECK:STDOUT: %G.486: %G.type.05c = struct_value () [concrete] // CHECK:STDOUT: %HasG.facet.085: %HasG.type = facet_value %C, %impl_witness.722 [concrete] @@ -283,11 +283,11 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %Self.cf3: %HasF.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %F.type.dbc: type = fn_type @F.1 [concrete] // CHECK:STDOUT: %F.a2b: %F.type.dbc = struct_value () [concrete] -// CHECK:STDOUT: %impl_witness.a36: = impl_witness (@impl.2.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.a36: = impl_witness (@impl.8af.%F.decl) [concrete] // CHECK:STDOUT: %F.type.bab: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.46f: %F.type.bab = struct_value () [concrete] // CHECK:STDOUT: %HasF.facet: %HasF.type = facet_value %D, %impl_witness.a36 [concrete] -// CHECK:STDOUT: %impl_witness.9ed: = impl_witness (@impl.3.%G.decl) [concrete] +// CHECK:STDOUT: %impl_witness.9ed: = impl_witness (@impl.da9.%G.decl) [concrete] // CHECK:STDOUT: %G.type.c1d: type = fn_type @G.3 [concrete] // CHECK:STDOUT: %G.294: %G.type.c1d = struct_value () [concrete] // CHECK:STDOUT: %HasG.facet.6fc: %HasG.type = facet_value %D, %impl_witness.9ed [concrete] @@ -318,23 +318,23 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %PackageA.import = import PackageA // CHECK:STDOUT: %HasG.decl: type = interface_decl @HasG [concrete = constants.%HasG.type] {} {} // CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.e95 [concrete] {} { // CHECK:STDOUT: %PackageA.ref: = name_ref PackageA, imports.%PackageA [concrete = imports.%PackageA] // CHECK:STDOUT: %C.ref: type = name_ref C, imports.%PackageA.C [concrete = constants.%C] // CHECK:STDOUT: %HasG.ref: type = name_ref HasG, file.%HasG.decl [concrete = constants.%HasG.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.1.%G.decl) [concrete = constants.%impl_witness.722] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.e95.%G.decl) [concrete = constants.%impl_witness.722] +// CHECK:STDOUT: impl_decl @impl.8af [concrete] {} { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %PackageA.ref: = name_ref PackageA, imports.%PackageA [concrete = imports.%PackageA] // CHECK:STDOUT: %HasF.ref: type = name_ref HasF, imports.%PackageA.HasF [concrete = constants.%HasF.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.2.%F.decl) [concrete = constants.%impl_witness.a36] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.8af.%F.decl) [concrete = constants.%impl_witness.a36] +// CHECK:STDOUT: impl_decl @impl.da9 [concrete] {} { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %HasG.ref: type = name_ref HasG, file.%HasG.decl [concrete = constants.%HasG.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.3.%G.decl) [concrete = constants.%impl_witness.9ed] +// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.da9.%G.decl) [concrete = constants.%impl_witness.9ed] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @HasG { @@ -355,7 +355,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageA.F) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %HasG.ref { +// CHECK:STDOUT: impl @impl.e95: %C.ref as %HasG.ref { // CHECK:STDOUT: %G.decl: %G.type.05c = fn_decl @G.2 [concrete = constants.%G.486] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -363,7 +363,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = file.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %D.ref as %HasF.ref { +// CHECK:STDOUT: impl @impl.8af: %D.ref as %HasF.ref { // CHECK:STDOUT: %F.decl: %F.type.bab = fn_decl @F.2 [concrete = constants.%F.46f] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -371,7 +371,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %D.ref as %HasG.ref { +// CHECK:STDOUT: impl @impl.da9: %D.ref as %HasG.ref { // CHECK:STDOUT: %G.decl: %G.type.c1d = fn_decl @G.3 [concrete = constants.%G.294] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -618,22 +618,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageB.G) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { +// CHECK:STDOUT: impl @impl.4b2: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageA.import_ref.0e8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.922: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.fa0 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.52b: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.f2f // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.47e: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.231 // CHECK:STDOUT: } @@ -765,22 +765,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageA.F) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { +// CHECK:STDOUT: impl @impl.4b2: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageA.import_ref.0e8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.922: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.5d9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.52b: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.7db // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.47e: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.231 // CHECK:STDOUT: } @@ -904,17 +904,17 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageB.F) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.162: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.fa0 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.5f1: imports.%PackageB.import_ref.aa9f8a.1 as imports.%PackageB.import_ref.831 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.7db // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { +// CHECK:STDOUT: impl @impl.47e: imports.%PackageB.import_ref.aa9f8a.2 as imports.%PackageB.import_ref.cee586.2 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.240 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/multiple_extend.carbon b/toolchain/check/testdata/impl/multiple_extend.carbon index 724f8c9287ce9..97e94501272d4 100644 --- a/toolchain/check/testdata/impl/multiple_extend.carbon +++ b/toolchain/check/testdata/impl/multiple_extend.carbon @@ -177,11 +177,11 @@ fn P(o: O) { // CHECK:STDOUT: %HasG.assoc_type: type = assoc_entity_type %HasG.type [concrete] // CHECK:STDOUT: %assoc0.58a: %HasG.assoc_type = assoc_entity element0, @HasG.%G.decl [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %impl_witness.329: = impl_witness (@impl.1.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.329: = impl_witness (@impl.670.%F.decl) [concrete] // CHECK:STDOUT: %F.type.a65: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.ad8: %F.type.a65 = struct_value () [concrete] // CHECK:STDOUT: %HasF.facet: %HasF.type = facet_value %C, %impl_witness.329 [concrete] -// CHECK:STDOUT: %impl_witness.42a: = impl_witness (@impl.2.%G.decl) [concrete] +// CHECK:STDOUT: %impl_witness.42a: = impl_witness (@impl.096.%G.decl) [concrete] // CHECK:STDOUT: %G.type.cf6: type = fn_type @G.2 [concrete] // CHECK:STDOUT: %G.957: %G.type.cf6 = struct_value () [concrete] // CHECK:STDOUT: %HasG.facet: %HasG.type = facet_value %C, %impl_witness.42a [concrete] @@ -247,7 +247,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = (%G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %HasF.ref { +// CHECK:STDOUT: impl @impl.670: %Self.ref as %HasF.ref { // CHECK:STDOUT: %F.decl: %F.type.a65 = fn_decl @F.2 [concrete = constants.%F.ad8] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -255,7 +255,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = @C.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %HasG.ref { +// CHECK:STDOUT: impl @impl.096: %Self.ref as %HasG.ref { // CHECK:STDOUT: %G.decl: %G.type.cf6 = fn_decl @G.2 [concrete = constants.%G.957] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -264,16 +264,16 @@ fn P(o: O) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.670 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %HasF.ref: type = name_ref HasF, file.%HasF.decl [concrete = constants.%HasF.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.1.%F.decl) [concrete = constants.%impl_witness.329] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.670.%F.decl) [concrete = constants.%impl_witness.329] +// CHECK:STDOUT: impl_decl @impl.096 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %HasG.ref: type = name_ref HasG, file.%HasG.decl [concrete = constants.%HasG.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.2.%G.decl) [concrete = constants.%impl_witness.42a] +// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.096.%G.decl) [concrete = constants.%impl_witness.42a] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -283,8 +283,8 @@ fn P(o: O) { // CHECK:STDOUT: .HasG = // CHECK:STDOUT: .F = // CHECK:STDOUT: .G = -// CHECK:STDOUT: extend @impl.1.%HasF.ref -// CHECK:STDOUT: extend @impl.2.%HasG.ref +// CHECK:STDOUT: extend @impl.670.%HasF.ref +// CHECK:STDOUT: extend @impl.096.%HasG.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F.1(@HasF.%Self: %HasF.type) { @@ -350,11 +350,11 @@ fn P(o: O) { // CHECK:STDOUT: %HasA2.assoc_type: type = assoc_entity_type %HasA2.type [concrete] // CHECK:STDOUT: %assoc0.6ed: %HasA2.assoc_type = assoc_entity element0, @HasA2.%A.decl [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] -// CHECK:STDOUT: %impl_witness.73a: = impl_witness (@impl.1.%A.decl) [concrete] +// CHECK:STDOUT: %impl_witness.73a: = impl_witness (@impl.909.%A.decl) [concrete] // CHECK:STDOUT: %A.type.468: type = fn_type @A.3 [concrete] // CHECK:STDOUT: %A.efc: %A.type.468 = struct_value () [concrete] // CHECK:STDOUT: %HasA1.facet: %HasA1.type = facet_value %D, %impl_witness.73a [concrete] -// CHECK:STDOUT: %impl_witness.baf: = impl_witness (@impl.2.%A.decl) [concrete] +// CHECK:STDOUT: %impl_witness.baf: = impl_witness (@impl.390.%A.decl) [concrete] // CHECK:STDOUT: %A.type.938: type = fn_type @A.4 [concrete] // CHECK:STDOUT: %A.890: %A.type.938 = struct_value () [concrete] // CHECK:STDOUT: %HasA2.facet: %HasA2.type = facet_value %D, %impl_witness.baf [concrete] @@ -416,7 +416,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = (%A.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %HasA1.ref { +// CHECK:STDOUT: impl @impl.909: %Self.ref as %HasA1.ref { // CHECK:STDOUT: %A.decl: %A.type.468 = fn_decl @A.3 [concrete = constants.%A.efc] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -424,7 +424,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = @D.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %HasA2.ref { +// CHECK:STDOUT: impl @impl.390: %Self.ref as %HasA2.ref { // CHECK:STDOUT: %A.decl: %A.type.938 = fn_decl @A.4 [concrete = constants.%A.890] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -433,16 +433,16 @@ fn P(o: O) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.909 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] // CHECK:STDOUT: %HasA1.ref: type = name_ref HasA1, file.%HasA1.decl [concrete = constants.%HasA1.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.1.%A.decl) [concrete = constants.%impl_witness.73a] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.909.%A.decl) [concrete = constants.%impl_witness.73a] +// CHECK:STDOUT: impl_decl @impl.390 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] // CHECK:STDOUT: %HasA2.ref: type = name_ref HasA2, file.%HasA2.decl [concrete = constants.%HasA2.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.2.%A.decl) [concrete = constants.%impl_witness.baf] +// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.390.%A.decl) [concrete = constants.%impl_witness.baf] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -451,8 +451,8 @@ fn P(o: O) { // CHECK:STDOUT: .HasA1 = // CHECK:STDOUT: .HasA2 = // CHECK:STDOUT: .A = -// CHECK:STDOUT: extend @impl.1.%HasA1.ref -// CHECK:STDOUT: extend @impl.2.%HasA2.ref +// CHECK:STDOUT: extend @impl.909.%HasA1.ref +// CHECK:STDOUT: extend @impl.390.%HasA2.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @A.1(@HasA1.%Self: %HasA1.type) { @@ -794,11 +794,11 @@ fn P(o: O) { // CHECK:STDOUT: %assoc0.9ae: %HasN2.assoc_type = assoc_entity element0, @HasN2.%N.decl [concrete] // CHECK:STDOUT: %O: type = class_type @O [concrete] // CHECK:STDOUT: %O.elem: type = unbound_element_type %O, %NBase [concrete] -// CHECK:STDOUT: %impl_witness.982: = impl_witness (@impl.1.%N.decl) [concrete] +// CHECK:STDOUT: %impl_witness.982: = impl_witness (@impl.968.%N.decl) [concrete] // CHECK:STDOUT: %N.type.ffc: type = fn_type @N.4 [concrete] // CHECK:STDOUT: %N.4f5: %N.type.ffc = struct_value () [concrete] // CHECK:STDOUT: %HasN1.facet: %HasN1.type = facet_value %O, %impl_witness.982 [concrete] -// CHECK:STDOUT: %impl_witness.599: = impl_witness (@impl.2.%N.decl) [concrete] +// CHECK:STDOUT: %impl_witness.599: = impl_witness (@impl.117.%N.decl) [concrete] // CHECK:STDOUT: %N.type.8af: type = fn_type @N.5 [concrete] // CHECK:STDOUT: %N.308: %N.type.8af = struct_value () [concrete] // CHECK:STDOUT: %HasN2.facet: %HasN2.type = facet_value %O, %impl_witness.599 [concrete] @@ -864,7 +864,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = (%N.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %HasN1.ref { +// CHECK:STDOUT: impl @impl.968: %Self.ref as %HasN1.ref { // CHECK:STDOUT: %N.decl: %N.type.ffc = fn_decl @N.4 [concrete = constants.%N.4f5] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -872,7 +872,7 @@ fn P(o: O) { // CHECK:STDOUT: witness = @O.%impl_witness.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %HasN2.ref { +// CHECK:STDOUT: impl @impl.117: %Self.ref as %HasN2.ref { // CHECK:STDOUT: %N.decl: %N.type.8af = fn_decl @N.5 [concrete = constants.%N.308] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -895,16 +895,16 @@ fn P(o: O) { // CHECK:STDOUT: class @O { // CHECK:STDOUT: %NBase.ref: type = name_ref NBase, file.%NBase.decl [concrete = constants.%NBase] // CHECK:STDOUT: %.loc17: %O.elem = base_decl %NBase.ref, element0 [concrete] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.968 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%O [concrete = constants.%O] // CHECK:STDOUT: %HasN1.ref: type = name_ref HasN1, file.%HasN1.decl [concrete = constants.%HasN1.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.1.%N.decl) [concrete = constants.%impl_witness.982] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.968.%N.decl) [concrete = constants.%impl_witness.982] +// CHECK:STDOUT: impl_decl @impl.117 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%O [concrete = constants.%O] // CHECK:STDOUT: %HasN2.ref: type = name_ref HasN2, file.%HasN2.decl [concrete = constants.%HasN2.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc21: = impl_witness (@impl.2.%N.decl) [concrete = constants.%impl_witness.599] +// CHECK:STDOUT: %impl_witness.loc21: = impl_witness (@impl.117.%N.decl) [concrete = constants.%impl_witness.599] // CHECK:STDOUT: %N.decl: %N.type.8b4 = fn_decl @N.6 [concrete = constants.%N.cc3] {} {} // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.9c6 [concrete = constants.%complete_type.121] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -917,8 +917,8 @@ fn P(o: O) { // CHECK:STDOUT: .HasN2 = // CHECK:STDOUT: .N = %N.decl // CHECK:STDOUT: extend %NBase.ref -// CHECK:STDOUT: extend @impl.1.%HasN1.ref -// CHECK:STDOUT: extend @impl.2.%HasN2.ref +// CHECK:STDOUT: extend @impl.968.%HasN1.ref +// CHECK:STDOUT: extend @impl.117.%HasN2.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @N.1() { diff --git a/toolchain/check/testdata/impl/no_prelude/fail_alias.carbon b/toolchain/check/testdata/impl/no_prelude/fail_alias.carbon index 436f9cd2fa141..3c2216e9903b1 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_alias.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_alias.carbon @@ -49,12 +49,12 @@ impl AC as AI {} // CHECK:STDOUT: %AI: type = bind_alias AI, %I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] // CHECK:STDOUT: %AC: type = bind_alias AC, %C.decl [concrete = constants.%C] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.7704ae.1 [concrete] {} { // CHECK:STDOUT: %AC.ref: type = name_ref AC, file.%AC [concrete = constants.%C] // CHECK:STDOUT: %AI.ref: type = name_ref AI, file.%AI [concrete = constants.%I.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc17: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.7704ae.2 [concrete] {} { // CHECK:STDOUT: %AC.ref: type = name_ref AC, file.%AC [concrete = constants.%C] // CHECK:STDOUT: %AI.ref: type = name_ref AI, file.%AI [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -69,12 +69,12 @@ impl AC as AI {} // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %AC.ref as %AI.ref { +// CHECK:STDOUT: impl @impl.7704ae.1: %AC.ref as %AI.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %AC.ref as %AI.ref { +// CHECK:STDOUT: impl @impl.7704ae.2: %AC.ref as %AI.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc26 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon b/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon index 7518851e8296f..cfcf7951264a4 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_extend_impl_scope.carbon @@ -156,10 +156,10 @@ fn F() { // CHECK:STDOUT: %Zero.d14: %Zero.type.822 = struct_value () [concrete] // CHECK:STDOUT: %Z.assoc_type: type = assoc_entity_type %Z.type [concrete] // CHECK:STDOUT: %assoc0: %Z.assoc_type = assoc_entity element0, @Z.%Zero.decl [concrete] -// CHECK:STDOUT: %Zero.type.db4: type = fn_type @Zero.2, @impl.1(%Self) [symbolic] +// CHECK:STDOUT: %Zero.type.db4: type = fn_type @Zero.2, @impl.6b5(%Self) [symbolic] // CHECK:STDOUT: %Zero.8fb: %Zero.type.db4 = struct_value () [symbolic] // CHECK:STDOUT: %Point: type = class_type @Point [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.2.%Zero.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c94.%Zero.decl) [concrete] // CHECK:STDOUT: %Zero.type.e33: type = fn_type @Zero.3 [concrete] // CHECK:STDOUT: %Zero.dec: %Zero.type.e33 = struct_value () [concrete] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %Point, %impl_witness [concrete] @@ -186,7 +186,7 @@ fn F() { // CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %Zero.decl: %Zero.type.822 = fn_decl @Zero.1 [concrete = constants.%Zero.d14] {} {} // CHECK:STDOUT: %assoc0: %Z.assoc_type = assoc_entity element0, %Zero.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.6b5 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, [concrete = ] // CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] // CHECK:STDOUT: } @@ -198,14 +198,14 @@ fn F() { // CHECK:STDOUT: witness = (%Zero.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(@Z.%Self: %Z.type) { +// CHECK:STDOUT: generic impl @impl.6b5(@Z.%Self: %Z.type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Zero.type: type = fn_type @Zero.2, @impl.1(%Self) [symbolic = %Zero.type (constants.%Zero.type.db4)] -// CHECK:STDOUT: %Zero: @impl.1.%Zero.type (%Zero.type.db4) = struct_value () [symbolic = %Zero (constants.%Zero.8fb)] +// CHECK:STDOUT: %Zero.type: type = fn_type @Zero.2, @impl.6b5(%Self) [symbolic = %Zero.type (constants.%Zero.type.db4)] +// CHECK:STDOUT: %Zero: @impl.6b5.%Zero.type (%Zero.type.db4) = struct_value () [symbolic = %Zero (constants.%Zero.8fb)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %Self.ref as %Z.ref { -// CHECK:STDOUT: %Zero.decl: @impl.1.%Zero.type (%Zero.type.db4) = fn_decl @Zero.2 [symbolic = @impl.1.%Zero (constants.%Zero.8fb)] {} {} +// CHECK:STDOUT: %Zero.decl: @impl.6b5.%Zero.type (%Zero.type.db4) = fn_decl @Zero.2 [symbolic = @impl.6b5.%Zero (constants.%Zero.8fb)] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Zero = %Zero.decl @@ -213,7 +213,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %Z.ref { +// CHECK:STDOUT: impl @impl.c94: %Self.ref as %Z.ref { // CHECK:STDOUT: %Zero.decl: %Zero.type.e33 = fn_decl @Zero.3 [concrete = constants.%Zero.dec] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -222,11 +222,11 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Point { -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c94 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] // CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.2.%Zero.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c94.%Zero.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -234,7 +234,7 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Point // CHECK:STDOUT: .Z = // CHECK:STDOUT: .Zero = -// CHECK:STDOUT: extend @impl.2.%Z.ref +// CHECK:STDOUT: extend @impl.c94.%Z.ref // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @Zero.1(@Z.%Self: %Z.type) { @@ -271,7 +271,7 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.1(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%Self) { +// CHECK:STDOUT: specific @impl.6b5(constants.%Self) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self => constants.%Self // CHECK:STDOUT: %Zero.type => constants.%Zero.type.db4 @@ -280,7 +280,7 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.2(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%Self) {} +// CHECK:STDOUT: specific @impl.6b5(%Self) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.1(constants.%Z.facet) {} // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon b/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon index e79c47b5b3e4f..486158b0f0346 100644 --- a/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon +++ b/toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon @@ -212,10 +212,10 @@ class X { // CHECK:STDOUT: %Zero.d14: %Zero.type.822 = struct_value () [concrete] // CHECK:STDOUT: %Z.assoc_type: type = assoc_entity_type %Z.type [concrete] // CHECK:STDOUT: %assoc0: %Z.assoc_type = assoc_entity element0, @Z.%Zero.decl [concrete] -// CHECK:STDOUT: %Zero.type.db4: type = fn_type @Zero.2, @impl.1(%Self) [symbolic] +// CHECK:STDOUT: %Zero.type.db4: type = fn_type @Zero.2, @impl.6b5(%Self) [symbolic] // CHECK:STDOUT: %Zero.8fb: %Zero.type.db4 = struct_value () [symbolic] // CHECK:STDOUT: %Point: type = class_type @Point [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.2.%Zero.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c94.%Zero.decl) [concrete] // CHECK:STDOUT: %Zero.type.e33: type = fn_type @Zero.3 [concrete] // CHECK:STDOUT: %Zero.dec: %Zero.type.e33 = struct_value () [concrete] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %Point, %impl_witness [concrete] @@ -242,7 +242,7 @@ class X { // CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %Zero.decl: %Zero.type.822 = fn_decl @Zero.1 [concrete = constants.%Zero.d14] {} {} // CHECK:STDOUT: %assoc0: %Z.assoc_type = assoc_entity element0, %Zero.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.6b5 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, [concrete = ] // CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] // CHECK:STDOUT: } @@ -254,14 +254,14 @@ class X { // CHECK:STDOUT: witness = (%Zero.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(@Z.%Self: %Z.type) { +// CHECK:STDOUT: generic impl @impl.6b5(@Z.%Self: %Z.type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Zero.type: type = fn_type @Zero.2, @impl.1(%Self) [symbolic = %Zero.type (constants.%Zero.type.db4)] -// CHECK:STDOUT: %Zero: @impl.1.%Zero.type (%Zero.type.db4) = struct_value () [symbolic = %Zero (constants.%Zero.8fb)] +// CHECK:STDOUT: %Zero.type: type = fn_type @Zero.2, @impl.6b5(%Self) [symbolic = %Zero.type (constants.%Zero.type.db4)] +// CHECK:STDOUT: %Zero: @impl.6b5.%Zero.type (%Zero.type.db4) = struct_value () [symbolic = %Zero (constants.%Zero.8fb)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %Self.ref as %Z.ref { -// CHECK:STDOUT: %Zero.decl: @impl.1.%Zero.type (%Zero.type.db4) = fn_decl @Zero.2 [symbolic = @impl.1.%Zero (constants.%Zero.8fb)] {} {} +// CHECK:STDOUT: %Zero.decl: @impl.6b5.%Zero.type (%Zero.type.db4) = fn_decl @Zero.2 [symbolic = @impl.6b5.%Zero (constants.%Zero.8fb)] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Zero = %Zero.decl @@ -269,7 +269,7 @@ class X { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %Z.ref { +// CHECK:STDOUT: impl @impl.c94: %Self.ref as %Z.ref { // CHECK:STDOUT: %Zero.decl: %Zero.type.e33 = fn_decl @Zero.3 [concrete = constants.%Zero.dec] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -278,11 +278,11 @@ class X { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Point { -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c94 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] // CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.2.%Zero.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c94.%Zero.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -326,7 +326,7 @@ class X { // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.1(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%Self) { +// CHECK:STDOUT: specific @impl.6b5(constants.%Self) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self => constants.%Self // CHECK:STDOUT: %Zero.type => constants.%Zero.type.db4 @@ -335,7 +335,7 @@ class X { // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.2(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%Self) {} +// CHECK:STDOUT: specific @impl.6b5(%Self) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Zero.1(constants.%Z.facet) {} // CHECK:STDOUT: @@ -354,7 +354,7 @@ class X { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %X: type = class_type @X [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%B.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.3b4.%B.decl) [concrete] // CHECK:STDOUT: %B.type.d47: type = fn_type @B.2 [concrete] // CHECK:STDOUT: %B.4af: %B.type.d47 = struct_value () [concrete] // CHECK:STDOUT: %A.facet: %A.type = facet_value %X, %impl_witness [concrete] @@ -394,8 +394,8 @@ class X { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %A.ref { -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl @impl.3b4: %Self.ref as %A.ref { +// CHECK:STDOUT: impl_decl @impl.4cc [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, [concrete = ] // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C.type] // CHECK:STDOUT: } @@ -408,17 +408,17 @@ class X { // CHECK:STDOUT: witness = @X.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %C.ref { +// CHECK:STDOUT: impl @impl.4cc: %Self.ref as %C.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @X { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.3b4 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%B.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.3b4.%B.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon b/toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon index e77db813748ee..a903b836c04c3 100644 --- a/toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon +++ b/toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon @@ -105,19 +105,19 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %T.826: %I.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt.3ad: %I.type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %T.as_type.b70: type = facet_access_type %T.826 [symbolic] -// CHECK:STDOUT: %impl_witness.d14: = impl_witness (), @impl.1(%T.826) [symbolic] +// CHECK:STDOUT: %impl_witness.d14: = impl_witness (), @impl.c3d(%T.826) [symbolic] // CHECK:STDOUT: %T.ccd: %J.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt.371: %J.type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %T.as_type.3df: type = facet_access_type %T.ccd [symbolic] -// CHECK:STDOUT: %impl_witness.d94: = impl_witness (), @impl.2(%T.ccd) [symbolic] +// CHECK:STDOUT: %impl_witness.d94: = impl_witness (), @impl.793(%T.ccd) [symbolic] // CHECK:STDOUT: %T.09f: %K.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt.036: %K.type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %T.as_type.037: type = facet_access_type %T.09f [symbolic] -// CHECK:STDOUT: %impl_witness.8aa: = impl_witness (), @impl.3(%T.09f) [symbolic] +// CHECK:STDOUT: %impl_witness.8aa: = impl_witness (), @impl.c93(%T.09f) [symbolic] // CHECK:STDOUT: %T.1d2: %L.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt.29d: %L.type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %T.as_type.0ed: type = facet_access_type %T.1d2 [symbolic] -// CHECK:STDOUT: %impl_witness.da5: = impl_witness (), @impl.4(%T.1d2) [symbolic] +// CHECK:STDOUT: %impl_witness.da5: = impl_witness (), @impl.9e6(%T.1d2) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -133,7 +133,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} // CHECK:STDOUT: %K.decl: type = interface_decl @K [concrete = constants.%K.type] {} {} // CHECK:STDOUT: %L.decl: type = interface_decl @L [concrete = constants.%L.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: impl_decl @impl.c3d [concrete] { // CHECK:STDOUT: %T.patt.loc11_14.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_14.2 (constants.%T.patt.3ad)] // CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc11_14.1, runtime_param [symbolic = %T.patt.loc11_14.2 (constants.%T.patt.3ad)] // CHECK:STDOUT: } { @@ -145,8 +145,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %I.ref.loc11: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %T.loc11_14.1: %I.type = bind_symbolic_name T, 0, %T.param.loc11 [symbolic = %T.loc11_14.2 (constants.%T.826)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (), @impl.1(constants.%T.826) [symbolic = @impl.1.%impl_witness (constants.%impl_witness.d14)] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (), @impl.c3d(constants.%T.826) [symbolic = @impl.c3d.%impl_witness (constants.%impl_witness.d14)] +// CHECK:STDOUT: impl_decl @impl.793 [concrete] { // CHECK:STDOUT: %T.patt.loc12_14.1: %J.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_14.2 (constants.%T.patt.371)] // CHECK:STDOUT: %T.param_patt: %J.type = value_param_pattern %T.patt.loc12_14.1, runtime_param [symbolic = %T.patt.loc12_14.2 (constants.%T.patt.371)] // CHECK:STDOUT: } { @@ -158,8 +158,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %J.ref.loc12: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: %T.loc12_14.1: %J.type = bind_symbolic_name T, 0, %T.param.loc12 [symbolic = %T.loc12_14.2 (constants.%T.ccd)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (), @impl.2(constants.%T.ccd) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.d94)] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] { +// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (), @impl.793(constants.%T.ccd) [symbolic = @impl.793.%impl_witness (constants.%impl_witness.d94)] +// CHECK:STDOUT: impl_decl @impl.c93 [concrete] { // CHECK:STDOUT: %T.patt.loc13_14.1: %K.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc13_14.2 (constants.%T.patt.036)] // CHECK:STDOUT: %T.param_patt: %K.type = value_param_pattern %T.patt.loc13_14.1, runtime_param [symbolic = %T.patt.loc13_14.2 (constants.%T.patt.036)] // CHECK:STDOUT: } { @@ -171,8 +171,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %K.ref.loc13: type = name_ref K, file.%K.decl [concrete = constants.%K.type] // CHECK:STDOUT: %T.loc13_14.1: %K.type = bind_symbolic_name T, 0, %T.param.loc13 [symbolic = %T.loc13_14.2 (constants.%T.09f)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (), @impl.3(constants.%T.09f) [symbolic = @impl.3.%impl_witness (constants.%impl_witness.8aa)] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] { +// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (), @impl.c93(constants.%T.09f) [symbolic = @impl.c93.%impl_witness (constants.%impl_witness.8aa)] +// CHECK:STDOUT: impl_decl @impl.9e6 [concrete] { // CHECK:STDOUT: %T.patt.loc14_14.1: %L.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt.29d)] // CHECK:STDOUT: %T.param_patt: %L.type = value_param_pattern %T.patt.loc14_14.1, runtime_param [symbolic = %T.patt.loc14_14.2 (constants.%T.patt.29d)] // CHECK:STDOUT: } { @@ -184,8 +184,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %L.ref.loc14: type = name_ref L, file.%L.decl [concrete = constants.%L.type] // CHECK:STDOUT: %T.loc14_14.1: %L.type = bind_symbolic_name T, 0, %T.param.loc14 [symbolic = %T.loc14_14.2 (constants.%T.1d2)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.4(constants.%T.1d2) [symbolic = @impl.4.%impl_witness (constants.%impl_witness.da5)] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.9e6(constants.%T.1d2) [symbolic = @impl.9e6.%impl_witness (constants.%impl_witness.da5)] +// CHECK:STDOUT: impl_decl @impl.c3d [concrete] { // CHECK:STDOUT: %T.patt.loc11_14.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_14.2 (constants.%T.patt.3ad)] // CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc11_14.1, runtime_param [symbolic = %T.patt.loc11_14.2 (constants.%T.patt.3ad)] // CHECK:STDOUT: } { @@ -197,7 +197,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %I.ref.loc18: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %T.loc18: %I.type = bind_symbolic_name T, 0, %T.param.loc18 [symbolic = constants.%T.826] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: impl_decl @impl.793 [concrete] { // CHECK:STDOUT: %T.patt.loc12_14.1: %J.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_14.2 (constants.%T.patt.371)] // CHECK:STDOUT: %T.param_patt: %J.type = value_param_pattern %T.patt.loc12_14.1, runtime_param [symbolic = %T.patt.loc12_14.2 (constants.%T.patt.371)] // CHECK:STDOUT: } { @@ -209,7 +209,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %J.ref.loc19: type = name_ref J, file.%J.decl [concrete = constants.%J.type] // CHECK:STDOUT: %T.loc19: %J.type = bind_symbolic_name T, 0, %T.param.loc19 [symbolic = constants.%T.ccd] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.3 [concrete] { +// CHECK:STDOUT: impl_decl @impl.c93 [concrete] { // CHECK:STDOUT: %T.patt.loc13_14.1: %K.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc13_14.2 (constants.%T.patt.036)] // CHECK:STDOUT: %T.param_patt: %K.type = value_param_pattern %T.patt.loc13_14.1, runtime_param [symbolic = %T.patt.loc13_14.2 (constants.%T.patt.036)] // CHECK:STDOUT: } { @@ -221,7 +221,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %K.ref.loc20: type = name_ref K, file.%K.decl [concrete = constants.%K.type] // CHECK:STDOUT: %T.loc20: %K.type = bind_symbolic_name T, 0, %T.param.loc20 [symbolic = constants.%T.09f] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.4 [concrete] { +// CHECK:STDOUT: impl_decl @impl.9e6 [concrete] { // CHECK:STDOUT: %T.patt.loc14_14.1: %L.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt.29d)] // CHECK:STDOUT: %T.param_patt: %L.type = value_param_pattern %T.patt.loc14_14.1, runtime_param [symbolic = %T.patt.loc14_14.2 (constants.%T.patt.29d)] // CHECK:STDOUT: } { @@ -275,11 +275,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(%T.loc11_14.1: %I.type) { +// CHECK:STDOUT: generic impl @impl.c3d(%T.loc11_14.1: %I.type) { // CHECK:STDOUT: %T.loc11_14.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc11_14.2 (constants.%T.826)] // CHECK:STDOUT: %T.patt.loc11_14.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_14.2 (constants.%T.patt.3ad)] // CHECK:STDOUT: %T.as_type.loc11_21.2: type = facet_access_type %T.loc11_14.2 [symbolic = %T.as_type.loc11_21.2 (constants.%T.as_type.b70)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T.loc11_14.2) [symbolic = %impl_witness (constants.%impl_witness.d14)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.c3d(%T.loc11_14.2) [symbolic = %impl_witness (constants.%impl_witness.d14)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -289,11 +289,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc12_14.1: %J.type) { +// CHECK:STDOUT: generic impl @impl.793(%T.loc12_14.1: %J.type) { // CHECK:STDOUT: %T.loc12_14.2: %J.type = bind_symbolic_name T, 0 [symbolic = %T.loc12_14.2 (constants.%T.ccd)] // CHECK:STDOUT: %T.patt.loc12_14.2: %J.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_14.2 (constants.%T.patt.371)] // CHECK:STDOUT: %T.as_type.loc12_21.2: type = facet_access_type %T.loc12_14.2 [symbolic = %T.as_type.loc12_21.2 (constants.%T.as_type.3df)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc12_14.2) [symbolic = %impl_witness (constants.%impl_witness.d94)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.793(%T.loc12_14.2) [symbolic = %impl_witness (constants.%impl_witness.d94)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -303,11 +303,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.3(%T.loc13_14.1: %K.type) { +// CHECK:STDOUT: generic impl @impl.c93(%T.loc13_14.1: %K.type) { // CHECK:STDOUT: %T.loc13_14.2: %K.type = bind_symbolic_name T, 0 [symbolic = %T.loc13_14.2 (constants.%T.09f)] // CHECK:STDOUT: %T.patt.loc13_14.2: %K.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc13_14.2 (constants.%T.patt.036)] // CHECK:STDOUT: %T.as_type.loc13_21.2: type = facet_access_type %T.loc13_14.2 [symbolic = %T.as_type.loc13_21.2 (constants.%T.as_type.037)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.3(%T.loc13_14.2) [symbolic = %impl_witness (constants.%impl_witness.8aa)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.c93(%T.loc13_14.2) [symbolic = %impl_witness (constants.%impl_witness.8aa)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -317,11 +317,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.4(%T.loc14_14.1: %L.type) { +// CHECK:STDOUT: generic impl @impl.9e6(%T.loc14_14.1: %L.type) { // CHECK:STDOUT: %T.loc14_14.2: %L.type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T.1d2)] // CHECK:STDOUT: %T.patt.loc14_14.2: %L.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt.29d)] // CHECK:STDOUT: %T.as_type.loc14_21.2: type = facet_access_type %T.loc14_14.2 [symbolic = %T.as_type.loc14_21.2 (constants.%T.as_type.0ed)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.4(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.da5)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.9e6(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.da5)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -331,41 +331,41 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T.826) { +// CHECK:STDOUT: specific @impl.c3d(constants.%T.826) { // CHECK:STDOUT: %T.loc11_14.2 => constants.%T.826 // CHECK:STDOUT: %T.patt.loc11_14.2 => constants.%T.826 // CHECK:STDOUT: %T.as_type.loc11_21.2 => constants.%T.as_type.b70 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.d14 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T.loc11_14.2) {} +// CHECK:STDOUT: specific @impl.c3d(%T.loc11_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T.ccd) { +// CHECK:STDOUT: specific @impl.793(constants.%T.ccd) { // CHECK:STDOUT: %T.loc12_14.2 => constants.%T.ccd // CHECK:STDOUT: %T.patt.loc12_14.2 => constants.%T.ccd // CHECK:STDOUT: %T.as_type.loc12_21.2 => constants.%T.as_type.3df // CHECK:STDOUT: %impl_witness => constants.%impl_witness.d94 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc12_14.2) {} +// CHECK:STDOUT: specific @impl.793(%T.loc12_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(constants.%T.09f) { +// CHECK:STDOUT: specific @impl.c93(constants.%T.09f) { // CHECK:STDOUT: %T.loc13_14.2 => constants.%T.09f // CHECK:STDOUT: %T.patt.loc13_14.2 => constants.%T.09f // CHECK:STDOUT: %T.as_type.loc13_21.2 => constants.%T.as_type.037 // CHECK:STDOUT: %impl_witness => constants.%impl_witness.8aa // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(%T.loc13_14.2) {} +// CHECK:STDOUT: specific @impl.c93(%T.loc13_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(constants.%T.1d2) { +// CHECK:STDOUT: specific @impl.9e6(constants.%T.1d2) { // CHECK:STDOUT: %T.loc14_14.2 => constants.%T.1d2 // CHECK:STDOUT: %T.patt.loc14_14.2 => constants.%T.1d2 // CHECK:STDOUT: %T.as_type.loc14_21.2 => constants.%T.as_type.0ed // CHECK:STDOUT: %impl_witness => constants.%impl_witness.da5 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(%T.loc14_14.2) {} +// CHECK:STDOUT: specific @impl.9e6(%T.loc14_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_same_self_and_interface_redefined.carbon // CHECK:STDOUT: @@ -377,8 +377,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %T: %I.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt: %I.type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] -// CHECK:STDOUT: %impl_witness.1896b7.1: = impl_witness (), @impl.1(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.1896b7.2: = impl_witness (), @impl.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.1896b7.1: = impl_witness (), @impl.bfd509.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.1896b7.2: = impl_witness (), @impl.bfd509.2(%T) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -388,7 +388,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: impl_decl @impl.bfd509.1 [concrete] { // CHECK:STDOUT: %T.patt.loc7_14.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc7_14.1, runtime_param [symbolic = %T.patt.loc7_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -400,8 +400,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %T.loc7_14.1: %I.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc7_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc7: = impl_witness (), @impl.1(constants.%T) [symbolic = @impl.1.%impl_witness (constants.%impl_witness.1896b7.1)] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: %impl_witness.loc7: = impl_witness (), @impl.bfd509.1(constants.%T) [symbolic = @impl.bfd509.1.%impl_witness (constants.%impl_witness.1896b7.1)] +// CHECK:STDOUT: impl_decl @impl.bfd509.2 [concrete] { // CHECK:STDOUT: %T.patt.loc15_14.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc15_14.1, runtime_param [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -413,7 +413,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %T.loc15_14.1: %I.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc15_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (), @impl.2(constants.%T) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.1896b7.2)] +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (), @impl.bfd509.2(constants.%T) [symbolic = @impl.bfd509.2.%impl_witness (constants.%impl_witness.1896b7.2)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { @@ -432,11 +432,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(%T.loc7_14.1: %I.type) { +// CHECK:STDOUT: generic impl @impl.bfd509.1(%T.loc7_14.1: %I.type) { // CHECK:STDOUT: %T.loc7_14.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc7_14.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.as_type.loc7_21.2: type = facet_access_type %T.loc7_14.2 [symbolic = %T.as_type.loc7_21.2 (constants.%T.as_type)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T.loc7_14.2) [symbolic = %impl_witness (constants.%impl_witness.1896b7.1)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.bfd509.1(%T.loc7_14.2) [symbolic = %impl_witness (constants.%impl_witness.1896b7.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -446,11 +446,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc15_14.1: %I.type) { +// CHECK:STDOUT: generic impl @impl.bfd509.2(%T.loc15_14.1: %I.type) { // CHECK:STDOUT: %T.loc15_14.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc15_14.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.as_type.loc15_21.2: type = facet_access_type %T.loc15_14.2 [symbolic = %T.as_type.loc15_21.2 (constants.%T.as_type)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc15_14.2) [symbolic = %impl_witness (constants.%impl_witness.1896b7.2)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.bfd509.2(%T.loc15_14.2) [symbolic = %impl_witness (constants.%impl_witness.1896b7.2)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -460,23 +460,23 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.bfd509.1(constants.%T) { // CHECK:STDOUT: %T.loc7_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc7_14.2 => constants.%T // CHECK:STDOUT: %T.as_type.loc7_21.2 => constants.%T.as_type // CHECK:STDOUT: %impl_witness => constants.%impl_witness.1896b7.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T.loc7_14.2) {} +// CHECK:STDOUT: specific @impl.bfd509.1(%T.loc7_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.bfd509.2(constants.%T) { // CHECK:STDOUT: %T.loc15_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc15_14.2 => constants.%T // CHECK:STDOUT: %T.as_type.loc15_21.2 => constants.%T.as_type // CHECK:STDOUT: %impl_witness => constants.%impl_witness.1896b7.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc15_14.2) {} +// CHECK:STDOUT: specific @impl.bfd509.2(%T.loc15_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: --- same_type_different_spelling.carbon // CHECK:STDOUT: @@ -497,12 +497,12 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.7704ae.1 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc13: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.7704ae.2 [concrete] {} { // CHECK:STDOUT: %C.ref.loc14_7: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %C.ref.loc14_10: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %.loc14_11.1: %tuple.type = tuple_literal (%C.ref.loc14_7, %C.ref.loc14_10) @@ -523,12 +523,12 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %I.ref { +// CHECK:STDOUT: impl @impl.7704ae.1: %C.ref as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %tuple.elem0 as %I.ref { +// CHECK:STDOUT: impl @impl.7704ae.2: %tuple.elem0 as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc14 // CHECK:STDOUT: } @@ -543,15 +543,15 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %impl_witness.1f09a1.1: = impl_witness (), @impl.1(%T) [symbolic] -// CHECK:STDOUT: %A.type: type = fn_type @A, @impl.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.1f09a1.1: = impl_witness (), @impl.2caff2.1(%T) [symbolic] +// CHECK:STDOUT: %A.type: type = fn_type @A, @impl.2caff2.1(%T) [symbolic] // CHECK:STDOUT: %A: %A.type = struct_value () [symbolic] -// CHECK:STDOUT: %impl_witness.1f09a1.2: = impl_witness (), @impl.2(%T) [symbolic] -// CHECK:STDOUT: %B.type: type = fn_type @B, @impl.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.1f09a1.2: = impl_witness (), @impl.2caff2.2(%T) [symbolic] +// CHECK:STDOUT: %B.type: type = fn_type @B, @impl.2caff2.2(%T) [symbolic] // CHECK:STDOUT: %B: %B.type = struct_value () [symbolic] -// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2(%T) [symbolic] +// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2caff2.2(%T) [symbolic] // CHECK:STDOUT: %C: %C.type = struct_value () [symbolic] -// CHECK:STDOUT: %D.type: type = fn_type @D, @impl.2(%T) [symbolic] +// CHECK:STDOUT: %D.type: type = fn_type @D, @impl.2caff2.2(%T) [symbolic] // CHECK:STDOUT: %D: %D.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: %C.specific_fn: = specific_function %C, @C(%T) [symbolic] @@ -562,7 +562,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: .I = %I.decl // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: impl_decl @impl.2caff2.1 [concrete] { // CHECK:STDOUT: %T.patt.loc4_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_14.1, runtime_param [symbolic = %T.patt.loc4_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -571,8 +571,8 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc4_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc4: = impl_witness (), @impl.1(constants.%T) [symbolic = @impl.1.%impl_witness (constants.%impl_witness.1f09a1.1)] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: %impl_witness.loc4: = impl_witness (), @impl.2caff2.1(constants.%T) [symbolic = @impl.2caff2.1.%impl_witness (constants.%impl_witness.1f09a1.1)] +// CHECK:STDOUT: impl_decl @impl.2caff2.2 [concrete] { // CHECK:STDOUT: %T.patt.loc15_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc15_14.1, runtime_param [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -581,7 +581,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc15_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc15_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (), @impl.2(constants.%T) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.1f09a1.2)] +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (), @impl.2caff2.2(constants.%T) [symbolic = @impl.2caff2.2.%impl_witness (constants.%impl_witness.1f09a1.2)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { @@ -592,17 +592,17 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(%T.loc4_14.1: type) { +// CHECK:STDOUT: generic impl @impl.2caff2.1(%T.loc4_14.1: type) { // CHECK:STDOUT: %T.loc4_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc4_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T.loc4_14.2) [symbolic = %impl_witness (constants.%impl_witness.1f09a1.1)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2caff2.1(%T.loc4_14.2) [symbolic = %impl_witness (constants.%impl_witness.1f09a1.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %A.type: type = fn_type @A, @impl.1(%T.loc4_14.2) [symbolic = %A.type (constants.%A.type)] -// CHECK:STDOUT: %A: @impl.1.%A.type (%A.type) = struct_value () [symbolic = %A (constants.%A)] +// CHECK:STDOUT: %A.type: type = fn_type @A, @impl.2caff2.1(%T.loc4_14.2) [symbolic = %A.type (constants.%A.type)] +// CHECK:STDOUT: %A: @impl.2caff2.1.%A.type (%A.type) = struct_value () [symbolic = %A (constants.%A)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %T.ref as %I.ref { -// CHECK:STDOUT: %A.decl: @impl.1.%A.type (%A.type) = fn_decl @A [symbolic = @impl.1.%A (constants.%A)] {} {} +// CHECK:STDOUT: %A.decl: @impl.2caff2.1.%A.type (%A.type) = fn_decl @A [symbolic = @impl.2caff2.1.%A (constants.%A)] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .A = %A.decl @@ -610,22 +610,22 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc15_14.1: type) { +// CHECK:STDOUT: generic impl @impl.2caff2.2(%T.loc15_14.1: type) { // CHECK:STDOUT: %T.loc15_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc15_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc15_14.2) [symbolic = %impl_witness (constants.%impl_witness.1f09a1.2)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2caff2.2(%T.loc15_14.2) [symbolic = %impl_witness (constants.%impl_witness.1f09a1.2)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %B.type: type = fn_type @B, @impl.2(%T.loc15_14.2) [symbolic = %B.type (constants.%B.type)] -// CHECK:STDOUT: %B: @impl.2.%B.type (%B.type) = struct_value () [symbolic = %B (constants.%B)] -// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2(%T.loc15_14.2) [symbolic = %C.type (constants.%C.type)] -// CHECK:STDOUT: %C: @impl.2.%C.type (%C.type) = struct_value () [symbolic = %C (constants.%C)] -// CHECK:STDOUT: %D.type: type = fn_type @D, @impl.2(%T.loc15_14.2) [symbolic = %D.type (constants.%D.type)] -// CHECK:STDOUT: %D: @impl.2.%D.type (%D.type) = struct_value () [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %B.type: type = fn_type @B, @impl.2caff2.2(%T.loc15_14.2) [symbolic = %B.type (constants.%B.type)] +// CHECK:STDOUT: %B: @impl.2caff2.2.%B.type (%B.type) = struct_value () [symbolic = %B (constants.%B)] +// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2caff2.2(%T.loc15_14.2) [symbolic = %C.type (constants.%C.type)] +// CHECK:STDOUT: %C: @impl.2caff2.2.%C.type (%C.type) = struct_value () [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %D.type: type = fn_type @D, @impl.2caff2.2(%T.loc15_14.2) [symbolic = %D.type (constants.%D.type)] +// CHECK:STDOUT: %D: @impl.2caff2.2.%D.type (%D.type) = struct_value () [symbolic = %D (constants.%D)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %T.ref as %I.ref { -// CHECK:STDOUT: %B.decl: @impl.2.%B.type (%B.type) = fn_decl @B [symbolic = @impl.2.%B (constants.%B)] {} {} -// CHECK:STDOUT: %C.decl: @impl.2.%C.type (%C.type) = fn_decl @C [symbolic = @impl.2.%C (constants.%C)] { +// CHECK:STDOUT: %B.decl: @impl.2caff2.2.%B.type (%B.type) = fn_decl @B [symbolic = @impl.2caff2.2.%B (constants.%B)] {} {} +// CHECK:STDOUT: %C.decl: @impl.2caff2.2.%C.type (%C.type) = fn_decl @C [symbolic = @impl.2caff2.2.%C (constants.%C)] { // CHECK:STDOUT: %return.patt: %empty_tuple.type = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %empty_tuple.type = out_param_pattern %return.patt, runtime_param0 // CHECK:STDOUT: } { @@ -634,7 +634,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param runtime_param0 // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %D.decl: @impl.2.%D.type (%D.type) = fn_decl @D [symbolic = @impl.2.%D (constants.%D)] { +// CHECK:STDOUT: %D.decl: @impl.2caff2.2.%D.type (%D.type) = fn_decl @D [symbolic = @impl.2caff2.2.%D (constants.%D)] { // CHECK:STDOUT: %return.patt: %empty_tuple.type = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %empty_tuple.type = out_param_pattern %return.patt, runtime_param0 // CHECK:STDOUT: } { @@ -652,7 +652,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @A(@impl.1.%T.loc4_14.1: type) { +// CHECK:STDOUT: generic fn @A(@impl.2caff2.1.%T.loc4_14.1: type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: fn() { @@ -661,7 +661,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @B(@impl.2.%T.loc15_14.1: type) { +// CHECK:STDOUT: generic fn @B(@impl.2caff2.2.%T.loc15_14.1: type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: fn() { @@ -670,7 +670,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @C(@impl.2.%T.loc15_14.1: type) { +// CHECK:STDOUT: generic fn @C(@impl.2caff2.2.%T.loc15_14.1: type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: fn() -> %empty_tuple.type { @@ -682,16 +682,16 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @D(@impl.2.%T.loc15_14.1: type) { +// CHECK:STDOUT: generic fn @D(@impl.2caff2.2.%T.loc15_14.1: type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] -// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2(%T) [symbolic = %C.type (constants.%C.type)] +// CHECK:STDOUT: %C.type: type = fn_type @C, @impl.2caff2.2(%T) [symbolic = %C.type (constants.%C.type)] // CHECK:STDOUT: %C: @D.%C.type (%C.type) = struct_value () [symbolic = %C (constants.%C)] // CHECK:STDOUT: %C.specific_fn.loc21_12.2: = specific_function %C, @C(%T) [symbolic = %C.specific_fn.loc21_12.2 (constants.%C.specific_fn)] // CHECK:STDOUT: // CHECK:STDOUT: fn() -> %empty_tuple.type { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc21_12: @D.%C.type (%C.type) = specific_constant @impl.2.%C.decl, @impl.2(constants.%T) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %.loc21_12: @D.%C.type (%C.type) = specific_constant @impl.2caff2.2.%C.decl, @impl.2caff2.2(constants.%T) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %C.ref: @D.%C.type (%C.type) = name_ref C, %.loc21_12 [symbolic = %C (constants.%C)] // CHECK:STDOUT: %C.specific_fn.loc21_12.1: = specific_function %C.ref, @C(constants.%T) [symbolic = %C.specific_fn.loc21_12.2 (constants.%C.specific_fn)] // CHECK:STDOUT: %C.call: init %empty_tuple.type = call %C.specific_fn.loc21_12.1() @@ -703,7 +703,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.2caff2.1(constants.%T) { // CHECK:STDOUT: %T.loc4_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc4_14.2 => constants.%T // CHECK:STDOUT: %impl_witness => constants.%impl_witness.1f09a1.1 @@ -713,11 +713,11 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %A => constants.%A // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T.loc4_14.2) {} +// CHECK:STDOUT: specific @impl.2caff2.1(%T.loc4_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @A(constants.%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.2caff2.2(constants.%T) { // CHECK:STDOUT: %T.loc15_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc15_14.2 => constants.%T // CHECK:STDOUT: %impl_witness => constants.%impl_witness.1f09a1.2 @@ -731,7 +731,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: %D => constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc15_14.2) {} +// CHECK:STDOUT: specific @impl.2caff2.2(%T.loc15_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @B(constants.%T) {} // CHECK:STDOUT: @@ -741,7 +741,7 @@ impl forall [T:! type] T as I { // CHECK:STDOUT: // CHECK:STDOUT: specific @D(constants.%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(@D.%T) {} +// CHECK:STDOUT: specific @impl.2caff2.2(@D.%T) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @C(@D.%T) {} // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon b/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon index f2234f3a41b92..f954cc04e198f 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon @@ -355,13 +355,13 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: .I3 = %I3.decl // CHECK:STDOUT: } // CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [concrete = constants.%I3.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.b46 [concrete] {} { // CHECK:STDOUT: %.loc9_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc9_7.2: type = converted %.loc9_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %I3.ref: type = name_ref I3, file.%I3.decl [concrete = constants.%I3.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc9: = impl_witness () [concrete = constants.%impl_witness.85b] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.add [concrete] {} { // CHECK:STDOUT: %.loc10_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %I3.ref: type = name_ref I3, file.%I3.decl [concrete = constants.%I3.type] @@ -397,9 +397,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T3:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc9_7.2 as %I3.ref; +// CHECK:STDOUT: impl @impl.b46: %.loc9_7.2 as %I3.ref; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc10_7.2 as %.loc10_15 { +// CHECK:STDOUT: impl @impl.add: %.loc10_7.2 as %.loc10_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } @@ -433,7 +433,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: .J = %J.decl // CHECK:STDOUT: } // CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.2d9 [concrete] {} { // CHECK:STDOUT: %.loc9_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc9_7.2: type = converted %.loc9_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] @@ -451,7 +451,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc9: = impl_witness (constants.%empty_struct_type) [concrete = constants.%impl_witness.6de] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.bd6 [concrete] {} { // CHECK:STDOUT: %.loc10_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] @@ -487,9 +487,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc9_7.2 as %.loc9_14; +// CHECK:STDOUT: impl @impl.2d9: %.loc9_7.2 as %.loc9_14; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc10_7.2 as %.loc10_14 { +// CHECK:STDOUT: impl @impl.bd6: %.loc10_7.2 as %.loc10_14 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } @@ -529,7 +529,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: .BAD4 = // CHECK:STDOUT: } // CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [concrete = constants.%I4.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.de506c.1 [concrete] {} { // CHECK:STDOUT: %.loc17_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc17_7.2: type = converted %.loc17_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %I4.ref: type = name_ref I4, file.%I4.decl [concrete = constants.%I4.type] @@ -563,7 +563,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.de506c.2 [concrete] {} { // CHECK:STDOUT: %.loc31_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc31_7.2: type = converted %.loc31_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %I4.ref: type = name_ref I4, file.%I4.decl [concrete = constants.%I4.type] @@ -631,9 +631,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T6:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc17_7.2 as %.loc17_15; +// CHECK:STDOUT: impl @impl.de506c.1: %.loc17_7.2 as %.loc17_15; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc31_7.2 as %.loc31_15 { +// CHECK:STDOUT: impl @impl.de506c.2: %.loc31_7.2 as %.loc31_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } @@ -674,7 +674,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: .K = %K.decl // CHECK:STDOUT: } // CHECK:STDOUT: %K.decl: type = interface_decl @K [concrete = constants.%K.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.138 [concrete] {} { // CHECK:STDOUT: %.loc5_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_7.2: type = converted %.loc5_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [concrete = constants.%K.type] @@ -692,7 +692,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc5: = impl_witness (constants.%empty_struct_type) [concrete = constants.%impl_witness.6de] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.4b0 [concrete] {} { // CHECK:STDOUT: %.loc17_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc17_7.2: type = converted %.loc17_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [concrete = constants.%K.type] @@ -716,9 +716,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const V:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc5_7.2 as %.loc5_14; +// CHECK:STDOUT: impl @impl.138: %.loc5_7.2 as %.loc5_14; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc17_7.2 as %K.ref { +// CHECK:STDOUT: impl @impl.4b0: %.loc17_7.2 as %K.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/no_prelude/import_generic.carbon b/toolchain/check/testdata/impl/no_prelude/import_generic.carbon index 499e8c8e7f1f4..5fd7d4f42bc0d 100644 --- a/toolchain/check/testdata/impl/no_prelude/import_generic.carbon +++ b/toolchain/check/testdata/impl/no_prelude/import_generic.carbon @@ -110,11 +110,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %I.type.325: type = facet_type <@I, @I(%T)> [symbolic] // CHECK:STDOUT: %Self: %I.type.325 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %require_complete.cfe: = require_complete_type %I.type.325 [symbolic] -// CHECK:STDOUT: %impl_witness.eff: = impl_witness (), @impl.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.eff: = impl_witness (), @impl.084(%T) [symbolic] // CHECK:STDOUT: %ptr: type = ptr_type %T [symbolic] // CHECK:STDOUT: %I.type.0e2: type = facet_type <@I, @I(%ptr)> [symbolic] // CHECK:STDOUT: %require_complete.0e6: = require_complete_type %I.type.0e2 [symbolic] -// CHECK:STDOUT: %impl_witness.465: = impl_witness (), @impl.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.465: = impl_witness (), @impl.cd2(%T) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -130,7 +130,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc5_13.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc5_13.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: impl_decl @impl.084 [concrete] { // CHECK:STDOUT: %T.patt.loc8_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc8_14.1, runtime_param [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -141,8 +141,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param.loc8: type = value_param runtime_param // CHECK:STDOUT: %T.loc8_14.1: type = bind_symbolic_name T, 0, %T.param.loc8 [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.1(constants.%T) [symbolic = @impl.1.%impl_witness (constants.%impl_witness.eff)] -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.084(constants.%T) [symbolic = @impl.084.%impl_witness (constants.%impl_witness.eff)] +// CHECK:STDOUT: impl_decl @impl.084 [concrete] { // CHECK:STDOUT: %T.patt.loc8_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc8_14.1, runtime_param [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -153,7 +153,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param.loc9: type = value_param runtime_param // CHECK:STDOUT: %T.loc9: type = bind_symbolic_name T, 0, %T.param.loc9 [symbolic = constants.%T] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: impl_decl @impl.cd2 [concrete] { // CHECK:STDOUT: %T.patt.loc12_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc12_14.1, runtime_param [symbolic = %T.patt.loc12_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -165,7 +165,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc12_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (), @impl.2(constants.%T) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.465)] +// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (), @impl.cd2(constants.%T) [symbolic = @impl.cd2.%impl_witness (constants.%impl_witness.465)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic interface @I(%T.loc5_13.1: type) { @@ -185,12 +185,12 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(%T.loc8_14.1: type) { +// CHECK:STDOUT: generic impl @impl.084(%T.loc8_14.1: type) { // CHECK:STDOUT: %T.loc8_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc8_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %I.type.loc8_32.2: type = facet_type <@I, @I(%T.loc8_14.2)> [symbolic = %I.type.loc8_32.2 (constants.%I.type.325)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.1.%I.type.loc8_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.084.%I.type.loc8_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.084(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -200,13 +200,13 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc12_14.1: type) { +// CHECK:STDOUT: generic impl @impl.cd2(%T.loc12_14.1: type) { // CHECK:STDOUT: %T.loc12_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc12_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc12_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc12_32.2: type = ptr_type @impl.2.%T.loc12_14.2 (%T) [symbolic = %ptr.loc12_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc12_32.2: type = ptr_type @impl.cd2.%T.loc12_14.2 (%T) [symbolic = %ptr.loc12_32.2 (constants.%ptr)] // CHECK:STDOUT: %I.type.loc12_33.2: type = facet_type <@I, @I(%ptr.loc12_32.2)> [symbolic = %I.type.loc12_33.2 (constants.%I.type.0e2)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%I.type.loc12_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc12_14.2) [symbolic = %impl_witness (constants.%impl_witness.465)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.cd2.%I.type.loc12_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.cd2(%T.loc12_14.2) [symbolic = %impl_witness (constants.%impl_witness.465)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -235,7 +235,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I(%T.loc5_13.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.084(constants.%T) { // CHECK:STDOUT: %T.loc8_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc8_14.2 => constants.%T // CHECK:STDOUT: %I.type.loc8_32.2 => constants.%I.type.325 @@ -243,9 +243,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.eff // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.1.%T.loc8_14.2) {} +// CHECK:STDOUT: specific @I(@impl.084.%T.loc8_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T.loc8_14.2) {} +// CHECK:STDOUT: specific @impl.084(%T.loc8_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I(constants.%ptr) { // CHECK:STDOUT: %T.loc5_13.2 => constants.%ptr @@ -256,7 +256,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Self.2 => constants.%Self // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.cd2(constants.%T) { // CHECK:STDOUT: %T.loc12_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc12_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc12_32.2 => constants.%ptr @@ -265,9 +265,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.465 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.2.%ptr.loc12_32.2) {} +// CHECK:STDOUT: specific @I(@impl.cd2.%ptr.loc12_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc12_14.2) {} +// CHECK:STDOUT: specific @impl.cd2(%T.loc12_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_generic.impl.carbon // CHECK:STDOUT: @@ -282,15 +282,15 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.cfe: = require_complete_type %I.type.325 [symbolic] -// CHECK:STDOUT: %impl_witness.eff58b.1: = impl_witness (), @impl.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.eff58b.1: = impl_witness (), @impl.08450a.1(%T) [symbolic] // CHECK:STDOUT: %ptr: type = ptr_type %T [symbolic] // CHECK:STDOUT: %I.type.0e2: type = facet_type <@I, @I(%ptr)> [symbolic] // CHECK:STDOUT: %require_complete.0e6: = require_complete_type %I.type.0e2 [symbolic] -// CHECK:STDOUT: %impl_witness.46542c.1: = impl_witness (), @impl.2(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.eff58b.2: = impl_witness (), @impl.3(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.eff58b.3: = impl_witness (), @impl.4(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.46542c.2: = impl_witness (), @impl.5(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.46542c.3: = impl_witness (), @impl.6(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.46542c.1: = impl_witness (), @impl.cd2fdc.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.eff58b.2: = impl_witness (), @impl.08450a.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.eff58b.3: = impl_witness (), @impl.08450a.3(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.46542c.2: = impl_witness (), @impl.cd2fdc.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.46542c.3: = impl_witness (), @impl.cd2fdc.3(%T) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -301,13 +301,13 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Main.import_ref.003 = import_ref Main//import_generic, loc8_33, unloaded // CHECK:STDOUT: %Main.import_ref.8f2: = import_ref Main//import_generic, loc4_10, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.2c4 = import_ref Main//import_generic, inst14 [no loc], unloaded -// CHECK:STDOUT: %Main.import_ref.f6b058.2: type = import_ref Main//import_generic, loc8_14, loaded [symbolic = @impl.1.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.f6b058.2: type = import_ref Main//import_generic, loc8_14, loaded [symbolic = @impl.08450a.1.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.29aca8.1: type = import_ref Main//import_generic, loc8_24, loaded [concrete = constants.%C] -// CHECK:STDOUT: %Main.import_ref.4be: type = import_ref Main//import_generic, loc8_32, loaded [symbolic = @impl.1.%I.type (constants.%I.type.325)] +// CHECK:STDOUT: %Main.import_ref.4be: type = import_ref Main//import_generic, loc8_32, loaded [symbolic = @impl.08450a.1.%I.type (constants.%I.type.325)] // CHECK:STDOUT: %Main.import_ref.4e1 = import_ref Main//import_generic, loc12_35, unloaded -// CHECK:STDOUT: %Main.import_ref.f6b058.3: type = import_ref Main//import_generic, loc12_14, loaded [symbolic = @impl.2.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.f6b058.3: type = import_ref Main//import_generic, loc12_14, loaded [symbolic = @impl.cd2fdc.1.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.29aca8.2: type = import_ref Main//import_generic, loc12_24, loaded [concrete = constants.%C] -// CHECK:STDOUT: %Main.import_ref.3e2: type = import_ref Main//import_generic, loc12_33, loaded [symbolic = @impl.2.%I.type (constants.%I.type.0e2)] +// CHECK:STDOUT: %Main.import_ref.3e2: type = import_ref Main//import_generic, loc12_33, loaded [symbolic = @impl.cd2fdc.1.%I.type (constants.%I.type.0e2)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -317,7 +317,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_6.1 = import // CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: impl_decl @impl.3 [concrete] { +// CHECK:STDOUT: impl_decl @impl.08450a.2 [concrete] { // CHECK:STDOUT: %T.patt.loc8_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc8_14.1, runtime_param [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -328,8 +328,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc8_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.3(constants.%T) [symbolic = @impl.3.%impl_witness (constants.%impl_witness.eff58b.2)] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] { +// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.08450a.2(constants.%T) [symbolic = @impl.08450a.2.%impl_witness (constants.%impl_witness.eff58b.2)] +// CHECK:STDOUT: impl_decl @impl.08450a.3 [concrete] { // CHECK:STDOUT: %T.patt.loc14_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc14_14.1, runtime_param [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -340,8 +340,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc14_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc14_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.4(constants.%T) [symbolic = @impl.4.%impl_witness (constants.%impl_witness.eff58b.3)] -// CHECK:STDOUT: impl_decl @impl.5 [concrete] { +// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.08450a.3(constants.%T) [symbolic = @impl.08450a.3.%impl_witness (constants.%impl_witness.eff58b.3)] +// CHECK:STDOUT: impl_decl @impl.cd2fdc.2 [concrete] { // CHECK:STDOUT: %T.patt.loc20_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc20_14.1, runtime_param [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -353,8 +353,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc20_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc20_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc20: = impl_witness (), @impl.5(constants.%T) [symbolic = @impl.5.%impl_witness (constants.%impl_witness.46542c.2)] -// CHECK:STDOUT: impl_decl @impl.6 [concrete] { +// CHECK:STDOUT: %impl_witness.loc20: = impl_witness (), @impl.cd2fdc.2(constants.%T) [symbolic = @impl.cd2fdc.2.%impl_witness (constants.%impl_witness.46542c.2)] +// CHECK:STDOUT: impl_decl @impl.cd2fdc.3 [concrete] { // CHECK:STDOUT: %T.patt.loc26_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc26_14.1, runtime_param [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -366,7 +366,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc26_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc26_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc26: = impl_witness (), @impl.6(constants.%T) [symbolic = @impl.6.%impl_witness (constants.%impl_witness.46542c.3)] +// CHECK:STDOUT: %impl_witness.loc26: = impl_witness (), @impl.cd2fdc.3(constants.%T) [symbolic = @impl.cd2fdc.3.%impl_witness (constants.%impl_witness.46542c.3)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic interface @I(imports.%Main.import_ref.f6b058.1: type) [from "import_generic.carbon"] { @@ -384,12 +384,12 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(imports.%Main.import_ref.f6b058.2: type) [from "import_generic.carbon"] { +// CHECK:STDOUT: generic impl @impl.08450a.1(imports.%Main.import_ref.f6b058.2: type) [from "import_generic.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.325)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.1.%I.type (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T) [symbolic = %impl_witness (constants.%impl_witness.eff58b.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.08450a.1.%I.type (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.08450a.1(%T) [symbolic = %impl_witness (constants.%impl_witness.eff58b.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -399,13 +399,13 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(imports.%Main.import_ref.f6b058.3: type) [from "import_generic.carbon"] { +// CHECK:STDOUT: generic impl @impl.cd2fdc.1(imports.%Main.import_ref.f6b058.3: type) [from "import_generic.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] -// CHECK:STDOUT: %ptr: type = ptr_type @impl.2.%T (%T) [symbolic = %ptr (constants.%ptr)] +// CHECK:STDOUT: %ptr: type = ptr_type @impl.cd2fdc.1.%T (%T) [symbolic = %ptr (constants.%ptr)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%ptr)> [symbolic = %I.type (constants.%I.type.0e2)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%I.type (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T) [symbolic = %impl_witness (constants.%impl_witness.46542c.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.cd2fdc.1.%I.type (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.cd2fdc.1(%T) [symbolic = %impl_witness (constants.%impl_witness.46542c.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -415,22 +415,22 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.3(%T.loc8_14.1: type) { +// CHECK:STDOUT: generic impl @impl.08450a.2(%T.loc8_14.1: type) { // CHECK:STDOUT: %T.loc8_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc8_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %I.type.loc8_32.2: type = facet_type <@I, @I(%T.loc8_14.2)> [symbolic = %I.type.loc8_32.2 (constants.%I.type.325)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.3.%I.type.loc8_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.3(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff58b.2)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.08450a.2.%I.type.loc8_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.08450a.2(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff58b.2)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %C.ref as %I.type.loc8_32.1; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.4(%T.loc14_14.1: type) { +// CHECK:STDOUT: generic impl @impl.08450a.3(%T.loc14_14.1: type) { // CHECK:STDOUT: %T.loc14_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc14_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: %I.type.loc14_32.2: type = facet_type <@I, @I(%T.loc14_14.2)> [symbolic = %I.type.loc14_32.2 (constants.%I.type.325)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.4.%I.type.loc14_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.4(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff58b.3)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.08450a.3.%I.type.loc14_32.2 (%I.type.325) [symbolic = %require_complete (constants.%require_complete.cfe)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.08450a.3(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.eff58b.3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -440,24 +440,24 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.5(%T.loc20_14.1: type) { +// CHECK:STDOUT: generic impl @impl.cd2fdc.2(%T.loc20_14.1: type) { // CHECK:STDOUT: %T.loc20_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc20_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc20_32.2: type = ptr_type @impl.5.%T.loc20_14.2 (%T) [symbolic = %ptr.loc20_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc20_32.2: type = ptr_type @impl.cd2fdc.2.%T.loc20_14.2 (%T) [symbolic = %ptr.loc20_32.2 (constants.%ptr)] // CHECK:STDOUT: %I.type.loc20_33.2: type = facet_type <@I, @I(%ptr.loc20_32.2)> [symbolic = %I.type.loc20_33.2 (constants.%I.type.0e2)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.5.%I.type.loc20_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.5(%T.loc20_14.2) [symbolic = %impl_witness (constants.%impl_witness.46542c.2)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.cd2fdc.2.%I.type.loc20_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.cd2fdc.2(%T.loc20_14.2) [symbolic = %impl_witness (constants.%impl_witness.46542c.2)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %C.ref as %I.type.loc20_33.1; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.6(%T.loc26_14.1: type) { +// CHECK:STDOUT: generic impl @impl.cd2fdc.3(%T.loc26_14.1: type) { // CHECK:STDOUT: %T.loc26_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc26_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc26_32.2: type = ptr_type @impl.6.%T.loc26_14.2 (%T) [symbolic = %ptr.loc26_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc26_32.2: type = ptr_type @impl.cd2fdc.3.%T.loc26_14.2 (%T) [symbolic = %ptr.loc26_32.2 (constants.%ptr)] // CHECK:STDOUT: %I.type.loc26_33.2: type = facet_type <@I, @I(%ptr.loc26_32.2)> [symbolic = %I.type.loc26_33.2 (constants.%I.type.0e2)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.6.%I.type.loc26_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.6(%T.loc26_14.2) [symbolic = %impl_witness (constants.%impl_witness.46542c.3)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.cd2fdc.3.%I.type.loc26_33.2 (%I.type.0e2) [symbolic = %require_complete (constants.%require_complete.0e6)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.cd2fdc.3(%T.loc26_14.2) [symbolic = %impl_witness (constants.%impl_witness.46542c.3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -485,7 +485,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I(%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.08450a.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %T.patt => constants.%T // CHECK:STDOUT: %I.type => constants.%I.type.325 @@ -493,9 +493,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.eff58b.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.1.%T) {} +// CHECK:STDOUT: specific @I(@impl.08450a.1.%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T) {} +// CHECK:STDOUT: specific @impl.08450a.1(%T) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I(constants.%ptr) { // CHECK:STDOUT: %T => constants.%ptr @@ -506,7 +506,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Self => constants.%Self // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.cd2fdc.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %T.patt => constants.%T // CHECK:STDOUT: %ptr => constants.%ptr @@ -515,11 +515,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.46542c.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.2.%ptr) {} +// CHECK:STDOUT: specific @I(@impl.cd2fdc.1.%ptr) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T) {} +// CHECK:STDOUT: specific @impl.cd2fdc.1(%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(constants.%T) { +// CHECK:STDOUT: specific @impl.08450a.2(constants.%T) { // CHECK:STDOUT: %T.loc8_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc8_14.2 => constants.%T // CHECK:STDOUT: %I.type.loc8_32.2 => constants.%I.type.325 @@ -527,11 +527,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.eff58b.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.3.%T.loc8_14.2) {} +// CHECK:STDOUT: specific @I(@impl.08450a.2.%T.loc8_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(%T.loc8_14.2) {} +// CHECK:STDOUT: specific @impl.08450a.2(%T.loc8_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(constants.%T) { +// CHECK:STDOUT: specific @impl.08450a.3(constants.%T) { // CHECK:STDOUT: %T.loc14_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc14_14.2 => constants.%T // CHECK:STDOUT: %I.type.loc14_32.2 => constants.%I.type.325 @@ -539,11 +539,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.eff58b.3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.4.%T.loc14_14.2) {} +// CHECK:STDOUT: specific @I(@impl.08450a.3.%T.loc14_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(%T.loc14_14.2) {} +// CHECK:STDOUT: specific @impl.08450a.3(%T.loc14_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.5(constants.%T) { +// CHECK:STDOUT: specific @impl.cd2fdc.2(constants.%T) { // CHECK:STDOUT: %T.loc20_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc20_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc20_32.2 => constants.%ptr @@ -552,11 +552,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.46542c.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.5.%ptr.loc20_32.2) {} +// CHECK:STDOUT: specific @I(@impl.cd2fdc.2.%ptr.loc20_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.5(%T.loc20_14.2) {} +// CHECK:STDOUT: specific @impl.cd2fdc.2(%T.loc20_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.6(constants.%T) { +// CHECK:STDOUT: specific @impl.cd2fdc.3(constants.%T) { // CHECK:STDOUT: %T.loc26_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc26_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc26_32.2 => constants.%ptr @@ -565,9 +565,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.46542c.3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I(@impl.6.%ptr.loc26_32.2) {} +// CHECK:STDOUT: specific @I(@impl.cd2fdc.3.%ptr.loc26_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.6(%T.loc26_14.2) {} +// CHECK:STDOUT: specific @impl.cd2fdc.3(%T.loc26_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_generic_decl.carbon // CHECK:STDOUT: @@ -582,11 +582,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %J.type.b72: type = facet_type <@J, @J(%T)> [symbolic] // CHECK:STDOUT: %Self: %J.type.b72 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %require_complete.287: = require_complete_type %J.type.b72 [symbolic] -// CHECK:STDOUT: %impl_witness.0ef: = impl_witness (), @impl.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.0ef: = impl_witness (), @impl.199(%T) [symbolic] // CHECK:STDOUT: %ptr: type = ptr_type %T [symbolic] // CHECK:STDOUT: %J.type.628: type = facet_type <@J, @J(%ptr)> [symbolic] // CHECK:STDOUT: %require_complete.c60: = require_complete_type %J.type.628 [symbolic] -// CHECK:STDOUT: %impl_witness.b80: = impl_witness (), @impl.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.b80: = impl_witness (), @impl.dfd(%T) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -602,7 +602,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc5_13.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc5_13.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.1 [concrete] { +// CHECK:STDOUT: impl_decl @impl.199 [concrete] { // CHECK:STDOUT: %T.patt.loc11_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc11_14.1, runtime_param [symbolic = %T.patt.loc11_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -613,8 +613,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc11_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc11_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (), @impl.1(constants.%T) [symbolic = @impl.1.%impl_witness (constants.%impl_witness.0ef)] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] { +// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (), @impl.199(constants.%T) [symbolic = @impl.199.%impl_witness (constants.%impl_witness.0ef)] +// CHECK:STDOUT: impl_decl @impl.dfd [concrete] { // CHECK:STDOUT: %T.patt.loc17_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc17_14.1, runtime_param [symbolic = %T.patt.loc17_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -626,7 +626,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc17_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc17_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (), @impl.2(constants.%T) [symbolic = @impl.2.%impl_witness (constants.%impl_witness.b80)] +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (), @impl.dfd(constants.%T) [symbolic = @impl.dfd.%impl_witness (constants.%impl_witness.b80)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic interface @J(%T.loc5_13.1: type) { @@ -646,23 +646,23 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(%T.loc11_14.1: type) { +// CHECK:STDOUT: generic impl @impl.199(%T.loc11_14.1: type) { // CHECK:STDOUT: %T.loc11_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc11_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc11_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_14.2 (constants.%T.patt)] // CHECK:STDOUT: %J.type.loc11_32.2: type = facet_type <@J, @J(%T.loc11_14.2)> [symbolic = %J.type.loc11_32.2 (constants.%J.type.b72)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.1.%J.type.loc11_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T.loc11_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.199.%J.type.loc11_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.199(%T.loc11_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %D.ref as %J.type.loc11_32.1; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(%T.loc17_14.1: type) { +// CHECK:STDOUT: generic impl @impl.dfd(%T.loc17_14.1: type) { // CHECK:STDOUT: %T.loc17_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc17_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc17_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc17_32.2: type = ptr_type @impl.2.%T.loc17_14.2 (%T) [symbolic = %ptr.loc17_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc17_32.2: type = ptr_type @impl.dfd.%T.loc17_14.2 (%T) [symbolic = %ptr.loc17_32.2 (constants.%ptr)] // CHECK:STDOUT: %J.type.loc17_33.2: type = facet_type <@J, @J(%ptr.loc17_32.2)> [symbolic = %J.type.loc17_33.2 (constants.%J.type.628)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%J.type.loc17_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T.loc17_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.dfd.%J.type.loc17_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.dfd(%T.loc17_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %D.ref as %J.type.loc17_33.1; // CHECK:STDOUT: } @@ -686,7 +686,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @J(%T.loc5_13.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.199(constants.%T) { // CHECK:STDOUT: %T.loc11_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc11_14.2 => constants.%T // CHECK:STDOUT: %J.type.loc11_32.2 => constants.%J.type.b72 @@ -694,9 +694,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.0ef // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.1.%T.loc11_14.2) {} +// CHECK:STDOUT: specific @J(@impl.199.%T.loc11_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T.loc11_14.2) {} +// CHECK:STDOUT: specific @impl.199(%T.loc11_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @J(constants.%ptr) { // CHECK:STDOUT: %T.loc5_13.2 => constants.%ptr @@ -707,7 +707,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Self.2 => constants.%Self // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.dfd(constants.%T) { // CHECK:STDOUT: %T.loc17_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc17_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc17_32.2 => constants.%ptr @@ -716,9 +716,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.b80 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.2.%ptr.loc17_32.2) {} +// CHECK:STDOUT: specific @J(@impl.dfd.%ptr.loc17_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T.loc17_14.2) {} +// CHECK:STDOUT: specific @impl.dfd(%T.loc17_14.2) {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_generic_decl.impl.carbon // CHECK:STDOUT: @@ -733,15 +733,15 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.287: = require_complete_type %J.type.b72 [symbolic] -// CHECK:STDOUT: %impl_witness.0ef94b.1: = impl_witness (), @impl.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.0ef94b.1: = impl_witness (), @impl.199bba.1(%T) [symbolic] // CHECK:STDOUT: %ptr: type = ptr_type %T [symbolic] // CHECK:STDOUT: %J.type.628: type = facet_type <@J, @J(%ptr)> [symbolic] // CHECK:STDOUT: %require_complete.c60: = require_complete_type %J.type.628 [symbolic] -// CHECK:STDOUT: %impl_witness.b80f53.1: = impl_witness (), @impl.2(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.0ef94b.2: = impl_witness (), @impl.3(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.0ef94b.3: = impl_witness (), @impl.4(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.b80f53.2: = impl_witness (), @impl.5(%T) [symbolic] -// CHECK:STDOUT: %impl_witness.b80f53.3: = impl_witness (), @impl.6(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.b80f53.1: = impl_witness (), @impl.dfd2f7.1(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.0ef94b.2: = impl_witness (), @impl.199bba.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.0ef94b.3: = impl_witness (), @impl.199bba.3(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.b80f53.2: = impl_witness (), @impl.dfd2f7.2(%T) [symbolic] +// CHECK:STDOUT: %impl_witness.b80f53.3: = impl_witness (), @impl.dfd2f7.3(%T) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -751,12 +751,12 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Main.import_ref.ff5 = import_ref Main//import_generic_decl, inst31 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.8f2: = import_ref Main//import_generic_decl, loc4_10, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.cab = import_ref Main//import_generic_decl, inst14 [no loc], unloaded -// CHECK:STDOUT: %Main.import_ref.f6b058.2: type = import_ref Main//import_generic_decl, loc11_14, loaded [symbolic = @impl.1.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.f6b058.2: type = import_ref Main//import_generic_decl, loc11_14, loaded [symbolic = @impl.199bba.1.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.aa9f8a.1: type = import_ref Main//import_generic_decl, loc11_24, loaded [concrete = constants.%D] -// CHECK:STDOUT: %Main.import_ref.ded: type = import_ref Main//import_generic_decl, loc11_32, loaded [symbolic = @impl.1.%J.type (constants.%J.type.b72)] -// CHECK:STDOUT: %Main.import_ref.f6b058.3: type = import_ref Main//import_generic_decl, loc17_14, loaded [symbolic = @impl.2.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.ded: type = import_ref Main//import_generic_decl, loc11_32, loaded [symbolic = @impl.199bba.1.%J.type (constants.%J.type.b72)] +// CHECK:STDOUT: %Main.import_ref.f6b058.3: type = import_ref Main//import_generic_decl, loc17_14, loaded [symbolic = @impl.dfd2f7.1.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.aa9f8a.2: type = import_ref Main//import_generic_decl, loc17_24, loaded [concrete = constants.%D] -// CHECK:STDOUT: %Main.import_ref.0d3: type = import_ref Main//import_generic_decl, loc17_33, loaded [symbolic = @impl.2.%J.type (constants.%J.type.628)] +// CHECK:STDOUT: %Main.import_ref.0d3: type = import_ref Main//import_generic_decl, loc17_33, loaded [symbolic = @impl.dfd2f7.1.%J.type (constants.%J.type.628)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -766,7 +766,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_6.1 = import // CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: impl_decl @impl.3 [concrete] { +// CHECK:STDOUT: impl_decl @impl.199bba.2 [concrete] { // CHECK:STDOUT: %T.patt.loc8_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc8_14.1, runtime_param [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -777,8 +777,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc8_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.3(constants.%T) [symbolic = @impl.3.%impl_witness (constants.%impl_witness.0ef94b.2)] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] { +// CHECK:STDOUT: %impl_witness.loc8: = impl_witness (), @impl.199bba.2(constants.%T) [symbolic = @impl.199bba.2.%impl_witness (constants.%impl_witness.0ef94b.2)] +// CHECK:STDOUT: impl_decl @impl.199bba.3 [concrete] { // CHECK:STDOUT: %T.patt.loc14_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc14_14.1, runtime_param [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -789,8 +789,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc14_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc14_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.4(constants.%T) [symbolic = @impl.4.%impl_witness (constants.%impl_witness.0ef94b.3)] -// CHECK:STDOUT: impl_decl @impl.5 [concrete] { +// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (), @impl.199bba.3(constants.%T) [symbolic = @impl.199bba.3.%impl_witness (constants.%impl_witness.0ef94b.3)] +// CHECK:STDOUT: impl_decl @impl.dfd2f7.2 [concrete] { // CHECK:STDOUT: %T.patt.loc20_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc20_14.1, runtime_param [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -802,8 +802,8 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc20_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc20_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc20: = impl_witness (), @impl.5(constants.%T) [symbolic = @impl.5.%impl_witness (constants.%impl_witness.b80f53.2)] -// CHECK:STDOUT: impl_decl @impl.6 [concrete] { +// CHECK:STDOUT: %impl_witness.loc20: = impl_witness (), @impl.dfd2f7.2(constants.%T) [symbolic = @impl.dfd2f7.2.%impl_witness (constants.%impl_witness.b80f53.2)] +// CHECK:STDOUT: impl_decl @impl.dfd2f7.3 [concrete] { // CHECK:STDOUT: %T.patt.loc26_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] // CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc26_14.1, runtime_param [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] // CHECK:STDOUT: } { @@ -815,7 +815,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %T.param: type = value_param runtime_param // CHECK:STDOUT: %T.loc26_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc26_14.2 (constants.%T)] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc26: = impl_witness (), @impl.6(constants.%T) [symbolic = @impl.6.%impl_witness (constants.%impl_witness.b80f53.3)] +// CHECK:STDOUT: %impl_witness.loc26: = impl_witness (), @impl.dfd2f7.3(constants.%T) [symbolic = @impl.dfd2f7.3.%impl_witness (constants.%impl_witness.b80f53.3)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic interface @J(imports.%Main.import_ref.f6b058.1: type) [from "fail_import_generic_decl.carbon"] { @@ -833,43 +833,43 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.1(imports.%Main.import_ref.f6b058.2: type) [from "fail_import_generic_decl.carbon"] { +// CHECK:STDOUT: generic impl @impl.199bba.1(imports.%Main.import_ref.f6b058.2: type) [from "fail_import_generic_decl.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] // CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b72)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.1.%J.type (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.1(%T) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.199bba.1.%J.type (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.199bba.1(%T) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.1)] // CHECK:STDOUT: // CHECK:STDOUT: impl: imports.%Main.import_ref.aa9f8a.1 as imports.%Main.import_ref.ded; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.2(imports.%Main.import_ref.f6b058.3: type) [from "fail_import_generic_decl.carbon"] { +// CHECK:STDOUT: generic impl @impl.dfd2f7.1(imports.%Main.import_ref.f6b058.3: type) [from "fail_import_generic_decl.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] -// CHECK:STDOUT: %ptr: type = ptr_type @impl.2.%T (%T) [symbolic = %ptr (constants.%ptr)] +// CHECK:STDOUT: %ptr: type = ptr_type @impl.dfd2f7.1.%T (%T) [symbolic = %ptr (constants.%ptr)] // CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%ptr)> [symbolic = %J.type (constants.%J.type.628)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.2.%J.type (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.2(%T) [symbolic = %impl_witness (constants.%impl_witness.b80f53.1)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.dfd2f7.1.%J.type (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.dfd2f7.1(%T) [symbolic = %impl_witness (constants.%impl_witness.b80f53.1)] // CHECK:STDOUT: // CHECK:STDOUT: impl: imports.%Main.import_ref.aa9f8a.2 as imports.%Main.import_ref.0d3; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.3(%T.loc8_14.1: type) { +// CHECK:STDOUT: generic impl @impl.199bba.2(%T.loc8_14.1: type) { // CHECK:STDOUT: %T.loc8_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc8_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_14.2 (constants.%T.patt)] // CHECK:STDOUT: %J.type.loc8_32.2: type = facet_type <@J, @J(%T.loc8_14.2)> [symbolic = %J.type.loc8_32.2 (constants.%J.type.b72)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.3.%J.type.loc8_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.3(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.2)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.199bba.2.%J.type.loc8_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.199bba.2(%T.loc8_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.2)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %D.ref as %J.type.loc8_32.1; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.4(%T.loc14_14.1: type) { +// CHECK:STDOUT: generic impl @impl.199bba.3(%T.loc14_14.1: type) { // CHECK:STDOUT: %T.loc14_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc14_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc14_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc14_14.2 (constants.%T.patt)] // CHECK:STDOUT: %J.type.loc14_32.2: type = facet_type <@J, @J(%T.loc14_14.2)> [symbolic = %J.type.loc14_32.2 (constants.%J.type.b72)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.4.%J.type.loc14_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.4(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.3)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.199bba.3.%J.type.loc14_32.2 (%J.type.b72) [symbolic = %require_complete (constants.%require_complete.287)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.199bba.3(%T.loc14_14.2) [symbolic = %impl_witness (constants.%impl_witness.0ef94b.3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -879,24 +879,24 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.5(%T.loc20_14.1: type) { +// CHECK:STDOUT: generic impl @impl.dfd2f7.2(%T.loc20_14.1: type) { // CHECK:STDOUT: %T.loc20_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc20_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc20_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc20_32.2: type = ptr_type @impl.5.%T.loc20_14.2 (%T) [symbolic = %ptr.loc20_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc20_32.2: type = ptr_type @impl.dfd2f7.2.%T.loc20_14.2 (%T) [symbolic = %ptr.loc20_32.2 (constants.%ptr)] // CHECK:STDOUT: %J.type.loc20_33.2: type = facet_type <@J, @J(%ptr.loc20_32.2)> [symbolic = %J.type.loc20_33.2 (constants.%J.type.628)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.5.%J.type.loc20_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.5(%T.loc20_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80f53.2)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.dfd2f7.2.%J.type.loc20_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.dfd2f7.2(%T.loc20_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80f53.2)] // CHECK:STDOUT: // CHECK:STDOUT: impl: %D.ref as %J.type.loc20_33.1; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @impl.6(%T.loc26_14.1: type) { +// CHECK:STDOUT: generic impl @impl.dfd2f7.3(%T.loc26_14.1: type) { // CHECK:STDOUT: %T.loc26_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc26_14.2 (constants.%T)] // CHECK:STDOUT: %T.patt.loc26_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc26_14.2 (constants.%T.patt)] -// CHECK:STDOUT: %ptr.loc26_32.2: type = ptr_type @impl.6.%T.loc26_14.2 (%T) [symbolic = %ptr.loc26_32.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc26_32.2: type = ptr_type @impl.dfd2f7.3.%T.loc26_14.2 (%T) [symbolic = %ptr.loc26_32.2 (constants.%ptr)] // CHECK:STDOUT: %J.type.loc26_33.2: type = facet_type <@J, @J(%ptr.loc26_32.2)> [symbolic = %J.type.loc26_33.2 (constants.%J.type.628)] -// CHECK:STDOUT: %require_complete: = require_complete_type @impl.6.%J.type.loc26_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] -// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.6(%T.loc26_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80f53.3)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.dfd2f7.3.%J.type.loc26_33.2 (%J.type.628) [symbolic = %require_complete (constants.%require_complete.c60)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl.dfd2f7.3(%T.loc26_14.2) [symbolic = %impl_witness (constants.%impl_witness.b80f53.3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -924,7 +924,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @J(%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(constants.%T) { +// CHECK:STDOUT: specific @impl.199bba.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %T.patt => constants.%T // CHECK:STDOUT: %J.type => constants.%J.type.b72 @@ -932,9 +932,9 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.0ef94b.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.1.%T) {} +// CHECK:STDOUT: specific @J(@impl.199bba.1.%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.1(%T) {} +// CHECK:STDOUT: specific @impl.199bba.1(%T) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @J(constants.%ptr) { // CHECK:STDOUT: %T => constants.%ptr @@ -945,7 +945,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %Self => constants.%Self // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(constants.%T) { +// CHECK:STDOUT: specific @impl.dfd2f7.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %T.patt => constants.%T // CHECK:STDOUT: %ptr => constants.%ptr @@ -954,11 +954,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.b80f53.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.2.%ptr) {} +// CHECK:STDOUT: specific @J(@impl.dfd2f7.1.%ptr) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.2(%T) {} +// CHECK:STDOUT: specific @impl.dfd2f7.1(%T) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(constants.%T) { +// CHECK:STDOUT: specific @impl.199bba.2(constants.%T) { // CHECK:STDOUT: %T.loc8_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc8_14.2 => constants.%T // CHECK:STDOUT: %J.type.loc8_32.2 => constants.%J.type.b72 @@ -966,11 +966,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.0ef94b.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.3.%T.loc8_14.2) {} +// CHECK:STDOUT: specific @J(@impl.199bba.2.%T.loc8_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.3(%T.loc8_14.2) {} +// CHECK:STDOUT: specific @impl.199bba.2(%T.loc8_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(constants.%T) { +// CHECK:STDOUT: specific @impl.199bba.3(constants.%T) { // CHECK:STDOUT: %T.loc14_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc14_14.2 => constants.%T // CHECK:STDOUT: %J.type.loc14_32.2 => constants.%J.type.b72 @@ -978,11 +978,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.0ef94b.3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.4.%T.loc14_14.2) {} +// CHECK:STDOUT: specific @J(@impl.199bba.3.%T.loc14_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.4(%T.loc14_14.2) {} +// CHECK:STDOUT: specific @impl.199bba.3(%T.loc14_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.5(constants.%T) { +// CHECK:STDOUT: specific @impl.dfd2f7.2(constants.%T) { // CHECK:STDOUT: %T.loc20_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc20_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc20_32.2 => constants.%ptr @@ -991,11 +991,11 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.b80f53.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.5.%ptr.loc20_32.2) {} +// CHECK:STDOUT: specific @J(@impl.dfd2f7.2.%ptr.loc20_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.5(%T.loc20_14.2) {} +// CHECK:STDOUT: specific @impl.dfd2f7.2(%T.loc20_14.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.6(constants.%T) { +// CHECK:STDOUT: specific @impl.dfd2f7.3(constants.%T) { // CHECK:STDOUT: %T.loc26_14.2 => constants.%T // CHECK:STDOUT: %T.patt.loc26_14.2 => constants.%T // CHECK:STDOUT: %ptr.loc26_32.2 => constants.%ptr @@ -1004,7 +1004,7 @@ impl forall [T:! type] D as J(T*) {} // CHECK:STDOUT: %impl_witness => constants.%impl_witness.b80f53.3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J(@impl.6.%ptr.loc26_32.2) {} +// CHECK:STDOUT: specific @J(@impl.dfd2f7.3.%ptr.loc26_32.2) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @impl.6(%T.loc26_14.2) {} +// CHECK:STDOUT: specific @impl.dfd2f7.3(%T.loc26_14.2) {} // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon b/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon index a6f4109b2daf5..c52bc4132f233 100644 --- a/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon +++ b/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon @@ -534,12 +534,12 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C3.decl: type = class_decl @C3 [concrete = constants.%C3] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.16e [concrete] {} { // CHECK:STDOUT: %C3.ref: type = name_ref C3, file.%C3.decl [concrete = constants.%C3] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc9: = impl_witness () [concrete = constants.%impl_witness.85b] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.ec6 [concrete] {} { // CHECK:STDOUT: %C3.ref: type = name_ref C3, file.%C3.decl [concrete = constants.%C3] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -569,9 +569,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C3.ref as %I.ref; +// CHECK:STDOUT: impl @impl.16e: %C3.ref as %I.ref; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C3.ref as %.loc10_14 { +// CHECK:STDOUT: impl @impl.ec6: %C3.ref as %.loc10_14 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } @@ -629,7 +629,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C4.decl: type = class_decl @C4 [concrete = constants.%C4] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.bbb [concrete] {} { // CHECK:STDOUT: %C4.ref: type = name_ref C4, file.%C4.decl [concrete = constants.%C4] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -646,7 +646,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc9: = impl_witness (constants.%empty_struct_type) [concrete = constants.%impl_witness.6de] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.265 [concrete] {} { // CHECK:STDOUT: %C4.ref: type = name_ref C4, file.%C4.decl [concrete = constants.%C4] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -676,9 +676,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C4.ref as %.loc9_14; +// CHECK:STDOUT: impl @impl.bbb: %C4.ref as %.loc9_14; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C4.ref as %.loc10_14 { +// CHECK:STDOUT: impl @impl.265: %C4.ref as %.loc10_14 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } @@ -747,7 +747,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C5.decl: type = class_decl @C5 [concrete = constants.%C5] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.eaa268.1 [concrete] {} { // CHECK:STDOUT: %C5.ref: type = name_ref C5, file.%C5.decl [concrete = constants.%C5] // CHECK:STDOUT: %I3.ref: type = name_ref I3, imports.%Main.I3 [concrete = constants.%I3.type] // CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -780,7 +780,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.eaa268.2 [concrete] {} { // CHECK:STDOUT: %C5.ref: type = name_ref C5, file.%C5.decl [concrete = constants.%C5] // CHECK:STDOUT: %I3.ref: type = name_ref I3, imports.%Main.I3 [concrete = constants.%I3.type] // CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -836,9 +836,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T3:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C5.ref as %.loc18_15; +// CHECK:STDOUT: impl @impl.eaa268.1: %C5.ref as %.loc18_15; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C5.ref as %.loc32_15 { +// CHECK:STDOUT: impl @impl.eaa268.2: %C5.ref as %.loc32_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } @@ -902,7 +902,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C6.decl: type = class_decl @C6 [concrete = constants.%C6] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.bee [concrete] {} { // CHECK:STDOUT: %C6.ref: type = name_ref C6, file.%C6.decl [concrete = constants.%C6] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] @@ -919,7 +919,7 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc5: = impl_witness (constants.%empty_struct_type) [concrete = constants.%impl_witness.6de] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.482 [concrete] {} { // CHECK:STDOUT: %C6.ref: type = name_ref C6, file.%C6.decl [concrete = constants.%C6] // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: } @@ -937,9 +937,9 @@ impl CD as IF where .F = 0 { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C6.ref as %.loc5_14; +// CHECK:STDOUT: impl @impl.bee: %C6.ref as %.loc5_14; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C6.ref as %I.ref { +// CHECK:STDOUT: impl @impl.482: %C6.ref as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/no_prelude/no_definition_in_impl_file.carbon b/toolchain/check/testdata/impl/no_prelude/no_definition_in_impl_file.carbon index 9c5cae59ae3ee..7497e5a59ab83 100644 --- a/toolchain/check/testdata/impl/no_prelude/no_definition_in_impl_file.carbon +++ b/toolchain/check/testdata/impl/no_prelude/no_definition_in_impl_file.carbon @@ -153,13 +153,13 @@ impl () as D; // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_6.1 = import // CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.064930.2 [concrete] {} { // CHECK:STDOUT: %.loc8_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %A.ref: type = name_ref A, imports.%Main.A [concrete = constants.%A.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc8: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.064930.3 [concrete] {} { // CHECK:STDOUT: %.loc14_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc14_7.2: type = converted %.loc14_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %A.ref: type = name_ref A, imports.%Main.A [concrete = constants.%A.type] @@ -173,11 +173,11 @@ impl () as D; // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%Main.import_ref.e5c as imports.%Main.import_ref.831 [from "fail_decl_in_api_definition_in_impl.carbon"]; +// CHECK:STDOUT: impl @impl.064930.1: imports.%Main.import_ref.e5c as imports.%Main.import_ref.831 [from "fail_decl_in_api_definition_in_impl.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc8_7.2 as %A.ref; +// CHECK:STDOUT: impl @impl.064930.2: %.loc8_7.2 as %A.ref; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %.loc14_7.2 as %A.ref { +// CHECK:STDOUT: impl @impl.064930.3: %.loc14_7.2 as %A.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc14 // CHECK:STDOUT: } @@ -317,7 +317,7 @@ impl () as D; // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_6.1 = import // CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.590fe9.2 [concrete] {} { // CHECK:STDOUT: %.loc8_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc8_7.2: type = converted %.loc8_7.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %C.ref: type = name_ref C, imports.%Main.C [concrete = constants.%C.type] @@ -331,9 +331,9 @@ impl () as D; // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%Main.import_ref.e5c as imports.%Main.import_ref.653 [from "fail_decl_in_api_decl_in_impl.carbon"]; +// CHECK:STDOUT: impl @impl.590fe9.1: imports.%Main.import_ref.e5c as imports.%Main.import_ref.653 [from "fail_decl_in_api_decl_in_impl.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %.loc8_7.2 as %C.ref; +// CHECK:STDOUT: impl @impl.590fe9.2: %.loc8_7.2 as %C.ref; // CHECK:STDOUT: // CHECK:STDOUT: --- decl_only_in_impl.carbon // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon b/toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon index 06a7d0e6cbcd2..46509f38fee3b 100644 --- a/toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon +++ b/toolchain/check/testdata/impl/no_prelude/self_in_signature.carbon @@ -51,12 +51,12 @@ impl D as SelfNested { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] -// CHECK:STDOUT: %impl_witness.9ff: = impl_witness (@impl.1.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.9ff: = impl_witness (@impl.c4a.%F.decl) [concrete] // CHECK:STDOUT: %F.type.fc6: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.5e2: %F.type.fc6 = struct_value () [concrete] // CHECK:STDOUT: %UseSelf.facet.e62: %UseSelf.type = facet_value %C, %impl_witness.9ff [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %impl_witness.320: = impl_witness (@impl.2.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.320: = impl_witness (@impl.659.%F.decl) [concrete] // CHECK:STDOUT: %F.type.0aa: type = fn_type @F.3 [concrete] // CHECK:STDOUT: %F.f71: %F.type.0aa = struct_value () [concrete] // CHECK:STDOUT: %UseSelf.facet.848: %UseSelf.type = facet_value %D, %impl_witness.320 [concrete] @@ -72,14 +72,14 @@ impl D as SelfNested { // CHECK:STDOUT: %F.998: %F.type.6ed = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.assoc_type: type = assoc_entity_type %SelfNested.type [concrete] // CHECK:STDOUT: %assoc0.a58: %SelfNested.assoc_type = assoc_entity element0, @SelfNested.%F.decl [concrete] -// CHECK:STDOUT: %impl_witness.f4e: = impl_witness (@impl.3.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.f4e: = impl_witness (@impl.730.%F.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %struct_type.x.y.2f0: type = struct_type {.x: %C, .y: %empty_tuple.type} [concrete] // CHECK:STDOUT: %tuple.type.a17: type = tuple_type (%ptr.019, %struct_type.x.y.2f0) [concrete] // CHECK:STDOUT: %F.type.ef0: type = fn_type @F.5 [concrete] // CHECK:STDOUT: %F.9a9: %F.type.ef0 = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.facet.f66: %SelfNested.type = facet_value %C, %impl_witness.f4e [concrete] -// CHECK:STDOUT: %impl_witness.4b5: = impl_witness (@impl.4.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.4b5: = impl_witness (@impl.82d.%F.decl) [concrete] // CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] // CHECK:STDOUT: %struct_type.x.y.527: type = struct_type {.x: %D, .y: %empty_tuple.type} [concrete] // CHECK:STDOUT: %tuple.type.a5f: type = tuple_type (%ptr.19c, %struct_type.x.y.527) [concrete] @@ -98,27 +98,27 @@ impl D as SelfNested { // CHECK:STDOUT: %UseSelf.decl: type = interface_decl @UseSelf [concrete = constants.%UseSelf.type] {} {} // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c4a [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %UseSelf.ref: type = name_ref UseSelf, file.%UseSelf.decl [concrete = constants.%UseSelf.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.1.%F.decl) [concrete = constants.%impl_witness.9ff] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.c4a.%F.decl) [concrete = constants.%impl_witness.9ff] +// CHECK:STDOUT: impl_decl @impl.659 [concrete] {} { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %UseSelf.ref: type = name_ref UseSelf, file.%UseSelf.decl [concrete = constants.%UseSelf.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.2.%F.decl) [concrete = constants.%impl_witness.320] +// CHECK:STDOUT: %impl_witness.loc23: = impl_witness (@impl.659.%F.decl) [concrete = constants.%impl_witness.320] // CHECK:STDOUT: %SelfNested.decl: type = interface_decl @SelfNested [concrete = constants.%SelfNested.type] {} {} -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.730 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc31: = impl_witness (@impl.3.%F.decl) [concrete = constants.%impl_witness.f4e] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc31: = impl_witness (@impl.730.%F.decl) [concrete = constants.%impl_witness.f4e] +// CHECK:STDOUT: impl_decl @impl.82d [concrete] {} { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc35: = impl_witness (@impl.4.%F.decl) [concrete = constants.%impl_witness.4b5] +// CHECK:STDOUT: %impl_witness.loc35: = impl_witness (@impl.82d.%F.decl) [concrete = constants.%impl_witness.4b5] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @UseSelf { @@ -190,7 +190,7 @@ impl D as SelfNested { // CHECK:STDOUT: witness = (%F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %UseSelf.ref { +// CHECK:STDOUT: impl @impl.c4a: %C.ref as %UseSelf.ref { // CHECK:STDOUT: %F.decl: %F.type.fc6 = fn_decl @F.2 [concrete = constants.%F.5e2] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -216,7 +216,7 @@ impl D as SelfNested { // CHECK:STDOUT: witness = file.%impl_witness.loc19 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %D.ref as %UseSelf.ref { +// CHECK:STDOUT: impl @impl.659: %D.ref as %UseSelf.ref { // CHECK:STDOUT: %F.decl: %F.type.0aa = fn_decl @F.3 [concrete = constants.%F.f71] { // CHECK:STDOUT: %self.patt: %D = binding_pattern self // CHECK:STDOUT: %self.param_patt: %D = value_param_pattern %self.patt, runtime_param0 @@ -225,12 +225,12 @@ impl D as SelfNested { // CHECK:STDOUT: %return.patt: %D = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %D = out_param_pattern %return.patt, runtime_param2 // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.ref.loc24_32: type = name_ref Self, @impl.2.%D.ref [concrete = constants.%D] +// CHECK:STDOUT: %Self.ref.loc24_32: type = name_ref Self, @impl.659.%D.ref [concrete = constants.%D] // CHECK:STDOUT: %self.param: %D = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref.loc24_14: type = name_ref Self, @impl.2.%D.ref [concrete = constants.%D] +// CHECK:STDOUT: %Self.ref.loc24_14: type = name_ref Self, @impl.659.%D.ref [concrete = constants.%D] // CHECK:STDOUT: %self: %D = bind_name self, %self.param // CHECK:STDOUT: %x.param: %D = value_param runtime_param1 -// CHECK:STDOUT: %Self.ref.loc24_23: type = name_ref Self, @impl.2.%D.ref [concrete = constants.%D] +// CHECK:STDOUT: %Self.ref.loc24_23: type = name_ref Self, @impl.659.%D.ref [concrete = constants.%D] // CHECK:STDOUT: %x: %D = bind_name x, %x.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param2 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -241,7 +241,7 @@ impl D as SelfNested { // CHECK:STDOUT: witness = file.%impl_witness.loc23 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %C.ref as %SelfNested.ref { +// CHECK:STDOUT: impl @impl.730: %C.ref as %SelfNested.ref { // CHECK:STDOUT: %F.decl: %F.type.ef0 = fn_decl @F.5 [concrete = constants.%F.9a9] { // CHECK:STDOUT: %x.patt: %tuple.type.a17 = binding_pattern x // CHECK:STDOUT: %x.param_patt: %tuple.type.a17 = value_param_pattern %x.patt, runtime_param0 @@ -266,16 +266,16 @@ impl D as SelfNested { // CHECK:STDOUT: witness = file.%impl_witness.loc31 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: %D.ref as %SelfNested.ref { +// CHECK:STDOUT: impl @impl.82d: %D.ref as %SelfNested.ref { // CHECK:STDOUT: %F.decl: %F.type.a9d = fn_decl @F.6 [concrete = constants.%F.c41] { // CHECK:STDOUT: %x.patt: %tuple.type.a5f = binding_pattern x // CHECK:STDOUT: %x.param_patt: %tuple.type.a5f = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: %tuple.type.a5f = value_param runtime_param0 // CHECK:STDOUT: %.loc36_37.1: type = splice_block %.loc36_37.3 [concrete = constants.%tuple.type.a5f] { -// CHECK:STDOUT: %Self.ref.loc36_12: type = name_ref Self, @impl.4.%D.ref [concrete = constants.%D] +// CHECK:STDOUT: %Self.ref.loc36_12: type = name_ref Self, @impl.82d.%D.ref [concrete = constants.%D] // CHECK:STDOUT: %ptr: type = ptr_type %D [concrete = constants.%ptr.19c] -// CHECK:STDOUT: %Self.ref.loc36_24: type = name_ref Self, @impl.4.%D.ref [concrete = constants.%D] +// CHECK:STDOUT: %Self.ref.loc36_24: type = name_ref Self, @impl.82d.%D.ref [concrete = constants.%D] // CHECK:STDOUT: %.loc36_35.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc36_35.2: type = converted %.loc36_35.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %D, .y: %empty_tuple.type} [concrete = constants.%struct_type.x.y.527] diff --git a/toolchain/check/testdata/index/array_element_access.carbon b/toolchain/check/testdata/index/array_element_access.carbon index f2c8a2d1c0263..cb94806e2cad5 100644 --- a/toolchain/check/testdata/index/array_element_access.carbon +++ b/toolchain/check/testdata/index/array_element_access.carbon @@ -26,8 +26,8 @@ var d: i32 = a[b]; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/expr_category.carbon b/toolchain/check/testdata/index/expr_category.carbon index a9067947c07fe..0378e19e20dd6 100644 --- a/toolchain/check/testdata/index/expr_category.carbon +++ b/toolchain/check/testdata/index/expr_category.carbon @@ -45,8 +45,8 @@ fn ValueBinding(b: array(i32, 3)) { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/fail_array_large_index.carbon b/toolchain/check/testdata/index/fail_array_large_index.carbon index 0f2eb9bf8c2c6..f566be1ce638c 100644 --- a/toolchain/check/testdata/index/fail_array_large_index.carbon +++ b/toolchain/check/testdata/index/fail_array_large_index.carbon @@ -34,8 +34,8 @@ var c: i32 = a[0x7FFF_FFFF]; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon index ac4d0245fc334..ec1b314bd05eb 100644 --- a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon +++ b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon @@ -30,8 +30,8 @@ var b: i32 = a[2.6]; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon index 4daab3c109254..c8eb8000e8fbb 100644 --- a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon +++ b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon @@ -27,8 +27,8 @@ var b: i32 = a[1]; // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/fail_expr_category.carbon b/toolchain/check/testdata/index/fail_expr_category.carbon index 67dabc908b945..3c8efc2dea6ca 100644 --- a/toolchain/check/testdata/index/fail_expr_category.carbon +++ b/toolchain/check/testdata/index/fail_expr_category.carbon @@ -52,8 +52,8 @@ fn G(b: array(i32, 3)) { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/index/fail_negative_indexing.carbon b/toolchain/check/testdata/index/fail_negative_indexing.carbon index dbb571c24ef7c..a67dcad948b66 100644 --- a/toolchain/check/testdata/index/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/index/fail_negative_indexing.carbon @@ -29,8 +29,8 @@ var d: i32 = c[-10]; // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon b/toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon index 31a9282225ea5..779c8529a09c5 100644 --- a/toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon +++ b/toolchain/check/testdata/interface/fail_todo_assoc_const_default.carbon @@ -36,8 +36,8 @@ interface I { // CHECK:STDOUT: %int_42.20e: Core.IntLiteral = int_value 42 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/interface/no_prelude/generic.carbon b/toolchain/check/testdata/interface/no_prelude/generic.carbon index a849e1341c656..67996a630f894 100644 --- a/toolchain/check/testdata/interface/no_prelude/generic.carbon +++ b/toolchain/check/testdata/interface/no_prelude/generic.carbon @@ -88,7 +88,7 @@ fn G(T:! Generic(B)) { // CHECK:STDOUT: %F.e46: %F.type.18c = struct_value () [concrete] // CHECK:STDOUT: %WithAssocFn.assoc_type.480: type = assoc_entity_type %WithAssocFn.type.683 [concrete] // CHECK:STDOUT: %assoc0.136: %WithAssocFn.assoc_type.480 = assoc_entity element0, @WithAssocFn.%F.decl [concrete] -// CHECK:STDOUT: %impl_witness.49b: = impl_witness (@impl.2.%F.decl) [concrete] +// CHECK:STDOUT: %impl_witness.49b: = impl_witness (@impl.90b.%F.decl) [concrete] // CHECK:STDOUT: %F.type.005: type = fn_type @F.2 [concrete] // CHECK:STDOUT: %F.317: %F.type.005 = struct_value () [concrete] // CHECK:STDOUT: %WithAssocFn.facet: %WithAssocFn.type.683 = facet_value %C, %impl_witness.49b [concrete] @@ -228,12 +228,12 @@ fn G(T:! Generic(B)) { // CHECK:STDOUT: interface; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %Self.ref as %Simple.type { +// CHECK:STDOUT: impl @impl.763: %Self.ref as %Simple.type { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = @C.%impl_witness.loc14 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %Self.ref as %WithAssocFn.type { +// CHECK:STDOUT: impl @impl.90b: %Self.ref as %WithAssocFn.type { // CHECK:STDOUT: %F.decl: %F.type.005 = fn_decl @F.2 [concrete = constants.%F.317] { // CHECK:STDOUT: %return.patt: %X = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %X = out_param_pattern %return.patt, runtime_param0 @@ -258,20 +258,20 @@ fn G(T:! Generic(B)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.763 [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %Simple.ref: %Simple.type.3b3 = name_ref Simple, file.%Simple.decl [concrete = constants.%Simple.generic] // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Simple.type: type = facet_type <@Simple, @Simple(constants.%C)> [concrete = constants.%Simple.type.51f] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc14: = impl_witness () [concrete = constants.%impl_witness.1bc] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.90b [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %WithAssocFn.ref: %WithAssocFn.type.509 = name_ref WithAssocFn, file.%WithAssocFn.decl [concrete = constants.%WithAssocFn.generic] // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %WithAssocFn.type: type = facet_type <@WithAssocFn, @WithAssocFn(constants.%C)> [concrete = constants.%WithAssocFn.type.683] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.2.%F.decl) [concrete = constants.%impl_witness.49b] +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.90b.%F.decl) [concrete = constants.%impl_witness.49b] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/generic_vs_params.carbon b/toolchain/check/testdata/interface/no_prelude/generic_vs_params.carbon index 7bb41acee30fe..3e62671693458 100644 --- a/toolchain/check/testdata/interface/no_prelude/generic_vs_params.carbon +++ b/toolchain/check/testdata/interface/no_prelude/generic_vs_params.carbon @@ -111,25 +111,25 @@ interface A(T: type) {} // CHECK:STDOUT: %T.loc8_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_9.2 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %X.decl: type = class_decl @X [concrete = constants.%X] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c96 [concrete] {} { // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %NotGenericNoParams.ref: type = name_ref NotGenericNoParams, file.%NotGenericNoParams.decl [concrete = constants.%NotGenericNoParams.type] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc14: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.f59 [concrete] {} { // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %NotGenericButParams.ref: %NotGenericButParams.type.f26 = name_ref NotGenericButParams, file.%NotGenericButParams.decl [concrete = constants.%NotGenericButParams.generic] // CHECK:STDOUT: %NotGenericButParams.type: type = facet_type <@NotGenericButParams> [concrete = constants.%NotGenericButParams.type.014] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc15: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.87f [concrete] {} { // CHECK:STDOUT: %X.ref.loc16_6: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %GenericAndParams.ref: %GenericAndParams.type.cde = name_ref GenericAndParams, file.%GenericAndParams.decl [concrete = constants.%GenericAndParams.generic.827] // CHECK:STDOUT: %X.ref.loc16_28: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %GenericAndParams.type: type = facet_type <@GenericAndParams.1, @GenericAndParams.1(constants.%X)> [concrete = constants.%GenericAndParams.type.4b6] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc16: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.3f8 [concrete] {} { // CHECK:STDOUT: %X.ref.loc17_6: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %X.ref.loc17_13: type = name_ref X, file.%X.decl [concrete = constants.%X] @@ -137,7 +137,7 @@ interface A(T: type) {} // CHECK:STDOUT: %GenericNoParams.ref: type = name_ref GenericNoParams, @C.%GenericNoParams.decl [concrete = constants.%GenericNoParams.type.f90] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness.loc17: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl.5 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.15f [concrete] {} { // CHECK:STDOUT: %X.ref.loc18_6: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %X.ref.loc18_13: type = name_ref X, file.%X.decl [concrete = constants.%X] @@ -216,27 +216,27 @@ interface A(T: type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %X.ref as %NotGenericNoParams.ref { +// CHECK:STDOUT: impl @impl.c96: %X.ref as %NotGenericNoParams.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc14 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %X.ref as %NotGenericButParams.type { +// CHECK:STDOUT: impl @impl.f59: %X.ref as %NotGenericButParams.type { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %X.ref.loc16_6 as %GenericAndParams.type { +// CHECK:STDOUT: impl @impl.87f: %X.ref.loc16_6 as %GenericAndParams.type { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: %X.ref.loc17_6 as %GenericNoParams.ref { +// CHECK:STDOUT: impl @impl.3f8: %X.ref.loc17_6 as %GenericNoParams.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.5: %X.ref.loc18_6 as %GenericAndParams.type { +// CHECK:STDOUT: impl @impl.15f: %X.ref.loc18_6 as %GenericAndParams.type { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/interface/todo_define_not_default.carbon b/toolchain/check/testdata/interface/todo_define_not_default.carbon index 16268bf4b9f34..61db9f8d76925 100644 --- a/toolchain/check/testdata/interface/todo_define_not_default.carbon +++ b/toolchain/check/testdata/interface/todo_define_not_default.carbon @@ -40,8 +40,8 @@ interface I { // CHECK:STDOUT: %int_42.20e: Core.IntLiteral = int_value 42 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/ir/duplicate_name_same_line.carbon b/toolchain/check/testdata/ir/duplicate_name_same_line.carbon index 5ba2423ced793..4e70ef1274780 100644 --- a/toolchain/check/testdata/ir/duplicate_name_same_line.carbon +++ b/toolchain/check/testdata/ir/duplicate_name_same_line.carbon @@ -21,8 +21,8 @@ fn A() { if (true) { var n: i32 = 1; } if (true) { var n: i32 = 2; } } // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/let/compile_time_bindings.carbon b/toolchain/check/testdata/let/compile_time_bindings.carbon index 3a81dce338e43..3cf060bd3bf30 100644 --- a/toolchain/check/testdata/let/compile_time_bindings.carbon +++ b/toolchain/check/testdata/let/compile_time_bindings.carbon @@ -595,8 +595,8 @@ impl i32 as Empty { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -665,8 +665,8 @@ impl i32 as Empty { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -924,8 +924,8 @@ impl i32 as Empty { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -950,7 +950,7 @@ impl i32 as Empty { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Empty.decl: type = interface_decl @Empty [concrete = constants.%Empty.type] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.cfd [concrete] {} { // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Empty.ref: type = name_ref Empty, file.%Empty.decl [concrete = constants.%Empty.type] @@ -966,7 +966,7 @@ impl i32 as Empty { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32.loc6 as %Empty.ref { +// CHECK:STDOUT: impl @impl.cfd: %i32.loc6 as %Empty.ref { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %Zero.patt: %i32 = binding_pattern Zero // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/let/convert.carbon b/toolchain/check/testdata/let/convert.carbon index 26abe3a794d20..dbba4197c5b5b 100644 --- a/toolchain/check/testdata/let/convert.carbon +++ b/toolchain/check/testdata/let/convert.carbon @@ -30,8 +30,8 @@ fn F() -> i32 { // CHECK:STDOUT: %tuple.type.37f: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/let/fail_duplicate_decl.carbon b/toolchain/check/testdata/let/fail_duplicate_decl.carbon index eebb47119240a..fa3d6252062a8 100644 --- a/toolchain/check/testdata/let/fail_duplicate_decl.carbon +++ b/toolchain/check/testdata/let/fail_duplicate_decl.carbon @@ -30,8 +30,8 @@ fn F() { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/let/fail_modifiers.carbon b/toolchain/check/testdata/let/fail_modifiers.carbon index 1412145c11e25..eb354b9e4fabc 100644 --- a/toolchain/check/testdata/let/fail_modifiers.carbon +++ b/toolchain/check/testdata/let/fail_modifiers.carbon @@ -92,8 +92,8 @@ protected protected let i: i32 = 1; // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/let/global.carbon b/toolchain/check/testdata/let/global.carbon index f6fa30402bfb5..1ee27fd1ff253 100644 --- a/toolchain/check/testdata/let/global.carbon +++ b/toolchain/check/testdata/let/global.carbon @@ -20,8 +20,8 @@ fn F() -> i32 { return n; } // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/let/shadowed_decl.carbon b/toolchain/check/testdata/let/shadowed_decl.carbon index 41439b4c856ee..5ada1f8855958 100644 --- a/toolchain/check/testdata/let/shadowed_decl.carbon +++ b/toolchain/check/testdata/let/shadowed_decl.carbon @@ -24,8 +24,8 @@ fn F(a: i32) -> i32 { // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/namespace/add_to_import.carbon b/toolchain/check/testdata/namespace/add_to_import.carbon index 1edd6ddcef7ed..547a6ffe256dd 100644 --- a/toolchain/check/testdata/namespace/add_to_import.carbon +++ b/toolchain/check/testdata/namespace/add_to_import.carbon @@ -50,8 +50,8 @@ var a: i32 = NS.A(); // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/namespace/alias.carbon b/toolchain/check/testdata/namespace/alias.carbon index 35aaa2852ddf7..97742cee28539 100644 --- a/toolchain/check/testdata/namespace/alias.carbon +++ b/toolchain/check/testdata/namespace/alias.carbon @@ -30,8 +30,8 @@ fn D() -> i32 { return C(); } // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/namespace/fail_decl_in_alias.carbon b/toolchain/check/testdata/namespace/fail_decl_in_alias.carbon index a3165a36f8b88..0f060107ffaf7 100644 --- a/toolchain/check/testdata/namespace/fail_decl_in_alias.carbon +++ b/toolchain/check/testdata/namespace/fail_decl_in_alias.carbon @@ -32,8 +32,8 @@ fn ns.A() -> i32 { return 0; } // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/namespace/shadow.carbon b/toolchain/check/testdata/namespace/shadow.carbon index e0ddf8b927c03..a6f1490cab58c 100644 --- a/toolchain/check/testdata/namespace/shadow.carbon +++ b/toolchain/check/testdata/namespace/shadow.carbon @@ -43,8 +43,8 @@ fn N.M.B() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/operators/builtin/assignment.carbon b/toolchain/check/testdata/operators/builtin/assignment.carbon index a2774258b62ea..a51b14c67a102 100644 --- a/toolchain/check/testdata/operators/builtin/assignment.carbon +++ b/toolchain/check/testdata/operators/builtin/assignment.carbon @@ -36,8 +36,8 @@ fn Main() { // CHECK:STDOUT: %int_12.6a3: Core.IntLiteral = int_value 12 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon b/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon index 64d23ed81e9ce..9db54e5c3c482 100644 --- a/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon @@ -70,8 +70,8 @@ fn Main() { // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon b/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon index 160e9d1aa7a94..095c0c3aba34c 100644 --- a/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon @@ -34,8 +34,8 @@ fn Main() { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon b/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon index 29e416b0444cf..219a1a9cab11a 100644 --- a/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon @@ -30,8 +30,8 @@ fn Main() { // CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/operators/overloaded/add.carbon b/toolchain/check/testdata/operators/overloaded/add.carbon index 37fedf9e59b73..6214c5fb8716d 100644 --- a/toolchain/check/testdata/operators/overloaded/add.carbon +++ b/toolchain/check/testdata/operators/overloaded/add.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %Add.type: type = facet_type <@Add> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.545: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.796: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.796: = impl_witness (@impl.b32.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.7a3: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.c84: %Op.type.7a3 = struct_value () [concrete] // CHECK:STDOUT: %Add.facet: %Add.type = facet_value %C, %impl_witness.796 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %AddAssign.type: type = facet_type <@AddAssign> [concrete] // CHECK:STDOUT: %Op.type.421: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.14c.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.0b8: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.d8e: %Op.type.0b8 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.b32 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Add.ref: type = name_ref Add, imports.%Core.Add [concrete = constants.%Add.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.796] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.b32.%Op.decl) [concrete = constants.%impl_witness.796] +// CHECK:STDOUT: impl_decl @impl.14c [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %AddAssign.ref: type = name_ref AddAssign, imports.%Core.AddAssign [concrete = constants.%AddAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.95d] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.14c.%Op.decl) [concrete = constants.%impl_witness.95d] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Add.ref { +// CHECK:STDOUT: impl @impl.b32: %C.ref as %Add.ref { // CHECK:STDOUT: %Op.decl: %Op.type.7a3 = fn_decl @Op.2 [concrete = constants.%Op.c84] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %AddAssign.ref { +// CHECK:STDOUT: impl @impl.14c: %C.ref as %AddAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.0b8 = fn_decl @Op.4 [concrete = constants.%Op.d8e] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/bit_and.carbon b/toolchain/check/testdata/operators/overloaded/bit_and.carbon index 136a17eb95590..d43f01bd4299d 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_and.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_and.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitAnd.type: type = facet_type <@BitAnd> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.27a: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.5af: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.5af: = impl_witness (@impl.c1a.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.45e: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.c43: %Op.type.45e = struct_value () [concrete] // CHECK:STDOUT: %BitAnd.facet: %BitAnd.type = facet_value %C, %impl_witness.5af [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %BitAndAssign.type: type = facet_type <@BitAndAssign> [concrete] // CHECK:STDOUT: %Op.type.93f: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.762: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.762: = impl_witness (@impl.4ac.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.969: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.747: %Op.type.969 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c1a [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitAnd.ref: type = name_ref BitAnd, imports.%Core.BitAnd [concrete = constants.%BitAnd.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.5af] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.c1a.%Op.decl) [concrete = constants.%impl_witness.5af] +// CHECK:STDOUT: impl_decl @impl.4ac [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitAndAssign.ref: type = name_ref BitAndAssign, imports.%Core.BitAndAssign [concrete = constants.%BitAndAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.762] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.4ac.%Op.decl) [concrete = constants.%impl_witness.762] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %BitAnd.ref { +// CHECK:STDOUT: impl @impl.c1a: %C.ref as %BitAnd.ref { // CHECK:STDOUT: %Op.decl: %Op.type.45e = fn_decl @Op.2 [concrete = constants.%Op.c43] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %BitAndAssign.ref { +// CHECK:STDOUT: impl @impl.4ac: %C.ref as %BitAndAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.969 = fn_decl @Op.4 [concrete = constants.%Op.747] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon index cf5c85c7a9762..2c9957e9fe82b 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon @@ -32,7 +32,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %BitComplement.type: type = facet_type <@BitComplement> [concrete] // CHECK:STDOUT: %Op.type.f25: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.5a3.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.544: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.bf2: %Op.type.544 = struct_value () [concrete] // CHECK:STDOUT: %BitComplement.facet: %BitComplement.type = facet_value %C, %impl_witness [concrete] @@ -59,12 +59,12 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.5a3 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitComplement.ref: type = name_ref BitComplement, imports.%Core.BitComplement [concrete = constants.%BitComplement.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.5a3.%Op.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -80,7 +80,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %BitComplement.ref { +// CHECK:STDOUT: impl @impl.5a3: %C.ref as %BitComplement.ref { // CHECK:STDOUT: %Op.decl: %Op.type.544 = fn_decl @Op.2 [concrete = constants.%Op.bf2] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/bit_or.carbon b/toolchain/check/testdata/operators/overloaded/bit_or.carbon index 46b195a0e5271..2df993a64f69f 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_or.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_or.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitOr.type: type = facet_type <@BitOr> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.9bb: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.e68: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.e68: = impl_witness (@impl.8f6.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.951: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.59a: %Op.type.951 = struct_value () [concrete] // CHECK:STDOUT: %BitOr.facet: %BitOr.type = facet_value %C, %impl_witness.e68 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %BitOrAssign.type: type = facet_type <@BitOrAssign> [concrete] // CHECK:STDOUT: %Op.type.099: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.85b: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.85b: = impl_witness (@impl.04f.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.8ba: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.b27: %Op.type.8ba = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.8f6 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitOr.ref: type = name_ref BitOr, imports.%Core.BitOr [concrete = constants.%BitOr.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.e68] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.8f6.%Op.decl) [concrete = constants.%impl_witness.e68] +// CHECK:STDOUT: impl_decl @impl.04f [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitOrAssign.ref: type = name_ref BitOrAssign, imports.%Core.BitOrAssign [concrete = constants.%BitOrAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.85b] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.04f.%Op.decl) [concrete = constants.%impl_witness.85b] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %BitOr.ref { +// CHECK:STDOUT: impl @impl.8f6: %C.ref as %BitOr.ref { // CHECK:STDOUT: %Op.decl: %Op.type.951 = fn_decl @Op.2 [concrete = constants.%Op.59a] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %BitOrAssign.ref { +// CHECK:STDOUT: impl @impl.04f: %C.ref as %BitOrAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.8ba = fn_decl @Op.4 [concrete = constants.%Op.b27] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon index 1ff1a96a7a33d..d6be7949efab4 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitXor.type: type = facet_type <@BitXor> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.e96: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.01d: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.01d: = impl_witness (@impl.2e5.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.672: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.442: %Op.type.672 = struct_value () [concrete] // CHECK:STDOUT: %BitXor.facet: %BitXor.type = facet_value %C, %impl_witness.01d [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %BitXorAssign.type: type = facet_type <@BitXorAssign> [concrete] // CHECK:STDOUT: %Op.type.58d: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.8dc: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.8dc: = impl_witness (@impl.9ba.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.8ab: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.67d: %Op.type.8ab = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.2e5 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitXor.ref: type = name_ref BitXor, imports.%Core.BitXor [concrete = constants.%BitXor.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.01d] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.2e5.%Op.decl) [concrete = constants.%impl_witness.01d] +// CHECK:STDOUT: impl_decl @impl.9ba [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitXorAssign.ref: type = name_ref BitXorAssign, imports.%Core.BitXorAssign [concrete = constants.%BitXorAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.8dc] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.9ba.%Op.decl) [concrete = constants.%impl_witness.8dc] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %BitXor.ref { +// CHECK:STDOUT: impl @impl.2e5: %C.ref as %BitXor.ref { // CHECK:STDOUT: %Op.decl: %Op.type.672 = fn_decl @Op.2 [concrete = constants.%Op.442] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %BitXorAssign.ref { +// CHECK:STDOUT: impl @impl.9ba: %C.ref as %BitXorAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.8ab = fn_decl @Op.4 [concrete = constants.%Op.67d] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/dec.carbon b/toolchain/check/testdata/operators/overloaded/dec.carbon index 14adc0af9e967..d2c05ae770f92 100644 --- a/toolchain/check/testdata/operators/overloaded/dec.carbon +++ b/toolchain/check/testdata/operators/overloaded/dec.carbon @@ -32,7 +32,7 @@ fn TestOp() { // CHECK:STDOUT: %Dec.type: type = facet_type <@Dec> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.633: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.7f9.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.9e0: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.cf9: %Op.type.9e0 = struct_value () [concrete] @@ -60,16 +60,16 @@ fn TestOp() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.7f9 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Dec.ref: type = name_ref Dec, imports.%Core.Dec [concrete = constants.%Dec.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.7f9.%Op.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Dec.ref { +// CHECK:STDOUT: impl @impl.7f9: %C.ref as %Dec.ref { // CHECK:STDOUT: %Op.decl: %Op.type.9e0 = fn_decl @Op.2 [concrete = constants.%Op.cf9] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/div.carbon b/toolchain/check/testdata/operators/overloaded/div.carbon index 6eae3fa8fa96f..1417c7c20c403 100644 --- a/toolchain/check/testdata/operators/overloaded/div.carbon +++ b/toolchain/check/testdata/operators/overloaded/div.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %Div.type: type = facet_type <@Div> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.784: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.745: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.745: = impl_witness (@impl.534.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.750: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.21e: %Op.type.750 = struct_value () [concrete] // CHECK:STDOUT: %Div.facet: %Div.type = facet_value %C, %impl_witness.745 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %DivAssign.type: type = facet_type <@DivAssign> [concrete] // CHECK:STDOUT: %Op.type.b95: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.d13: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.d13: = impl_witness (@impl.73d.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.b04: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.27c: %Op.type.b04 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.534 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Div.ref: type = name_ref Div, imports.%Core.Div [concrete = constants.%Div.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.745] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.534.%Op.decl) [concrete = constants.%impl_witness.745] +// CHECK:STDOUT: impl_decl @impl.73d [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %DivAssign.ref: type = name_ref DivAssign, imports.%Core.DivAssign [concrete = constants.%DivAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.d13] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.73d.%Op.decl) [concrete = constants.%impl_witness.d13] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Div.ref { +// CHECK:STDOUT: impl @impl.534: %C.ref as %Div.ref { // CHECK:STDOUT: %Op.decl: %Op.type.750 = fn_decl @Op.2 [concrete = constants.%Op.21e] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %DivAssign.ref { +// CHECK:STDOUT: impl @impl.73d: %C.ref as %DivAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.b04 = fn_decl @Op.4 [concrete = constants.%Op.27c] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/eq.carbon b/toolchain/check/testdata/operators/overloaded/eq.carbon index e0e083b4f59b6..7dfb8ed6c8f14 100644 --- a/toolchain/check/testdata/operators/overloaded/eq.carbon +++ b/toolchain/check/testdata/operators/overloaded/eq.carbon @@ -92,7 +92,7 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: %Eq.type: type = facet_type <@Eq> [concrete] // CHECK:STDOUT: %Equal.type.79c: type = fn_type @Equal.1 [concrete] // CHECK:STDOUT: %NotEqual.type.e6c: type = fn_type @NotEqual.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Equal.decl, @impl.1.%NotEqual.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.100.%Equal.decl, @impl.100.%NotEqual.decl) [concrete] // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] // CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] // CHECK:STDOUT: %Equal.type.b4a: type = fn_type @Equal.2 [concrete] @@ -127,12 +127,12 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.100 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Eq.ref: type = name_ref Eq, imports.%Core.Eq [concrete = constants.%Eq.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Equal.decl, @impl.1.%NotEqual.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.100.%Equal.decl, @impl.100.%NotEqual.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestEqual.decl: %TestEqual.type = fn_decl @TestEqual [concrete = constants.%TestEqual] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -175,7 +175,7 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Eq.ref { +// CHECK:STDOUT: impl @impl.100: %C.ref as %Eq.ref { // CHECK:STDOUT: %Equal.decl: %Equal.type.b4a = fn_decl @Equal.2 [concrete = constants.%Equal.f96] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -365,7 +365,7 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %Eq.type: type = facet_type <@Eq> [concrete] // CHECK:STDOUT: %Equal.type.79c: type = fn_type @Equal.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Equal.decl, @impl.1.%NotEqual.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.100.%Equal.decl, @impl.100.%NotEqual.decl) [concrete] // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] // CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] // CHECK:STDOUT: %Equal.type.b4a: type = fn_type @Equal.2 [concrete] @@ -402,12 +402,12 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.100 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Eq.ref: type = name_ref Eq, imports.%Core.Eq [concrete = constants.%Eq.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Equal.decl, @impl.1.%NotEqual.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.100.%Equal.decl, @impl.100.%NotEqual.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestRhsBad.decl: %TestRhsBad.type = fn_decl @TestRhsBad [concrete = constants.%TestRhsBad] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -450,7 +450,7 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Eq.ref { +// CHECK:STDOUT: impl @impl.100: %C.ref as %Eq.ref { // CHECK:STDOUT: %Equal.decl: %Equal.type.b4a = fn_decl @Equal.2 [concrete = constants.%Equal.f96] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon index 0867717ddce9e..d3755af9995e9 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon @@ -50,14 +50,14 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.e3a: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.ec3: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.ec3: = impl_witness (@impl.c51.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.73a: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.0c9: %Op.type.73a = struct_value () [concrete] // CHECK:STDOUT: %Inc.facet: %Inc.type = facet_value %C, %impl_witness.ec3 [concrete] // CHECK:STDOUT: %AddAssign.type: type = facet_type <@AddAssign> [concrete] // CHECK:STDOUT: %Op.type.421: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.14c.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.0b8: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.d8e: %Op.type.0b8 = struct_value () [concrete] // CHECK:STDOUT: %AddAssign.facet: %AddAssign.type = facet_value %C, %impl_witness.95d [concrete] @@ -89,18 +89,18 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c51 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Inc.ref: type = name_ref Inc, imports.%Core.Inc [concrete = constants.%Inc.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.ec3] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.c51.%Op.decl) [concrete = constants.%impl_witness.ec3] +// CHECK:STDOUT: impl_decl @impl.14c [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %AddAssign.ref: type = name_ref AddAssign, imports.%Core.AddAssign [concrete = constants.%AddAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.95d] +// CHECK:STDOUT: %impl_witness.loc18: = impl_witness (@impl.14c.%Op.decl) [concrete = constants.%impl_witness.95d] // CHECK:STDOUT: %TestIncNonRef.decl: %TestIncNonRef.type = fn_decl @TestIncNonRef [concrete = constants.%TestIncNonRef] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -124,7 +124,7 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Inc.ref { +// CHECK:STDOUT: impl @impl.c51: %C.ref as %Inc.ref { // CHECK:STDOUT: %Op.decl: %Op.type.73a = fn_decl @Op.2 [concrete = constants.%Op.0c9] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 @@ -144,7 +144,7 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %AddAssign.ref { +// CHECK:STDOUT: impl @impl.14c: %C.ref as %AddAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.0b8 = fn_decl @Op.4 [concrete = constants.%Op.d8e] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/fail_error_recovery.carbon b/toolchain/check/testdata/operators/overloaded/fail_error_recovery.carbon index 4423c41dc7623..0570d64a95bbc 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_error_recovery.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_error_recovery.carbon @@ -39,8 +39,8 @@ fn G(n: i32) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %impl_witness.01d: = impl_witness (imports.%Core.import_ref.344), @impl.14(%int_32) [concrete] -// CHECK:STDOUT: %Op.type.210: type = fn_type @Op.2, @impl.14(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.01d: = impl_witness (imports.%Core.import_ref.344), @impl.2c2(%int_32) [concrete] +// CHECK:STDOUT: %Op.type.210: type = fn_type @Op.2, @impl.2c2(%int_32) [concrete] // CHECK:STDOUT: %Op.c82: %Op.type.210 = struct_value () [concrete] // CHECK:STDOUT: %Add.facet: %Add.type = facet_value %i32, %impl_witness.01d [concrete] // CHECK:STDOUT: %.ede: type = fn_type_with_self_type %Op.type.545, %Add.facet [concrete] diff --git a/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon b/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon index 08cf8774ac692..5d3ec51cdb4cb 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon @@ -59,13 +59,13 @@ fn TestAssign(b: D) { // CHECK:STDOUT: %Add.type: type = facet_type <@Add> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.545: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.796: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.796: = impl_witness (@impl.b32.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.7a3: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.c84: %Op.type.7a3 = struct_value () [concrete] // CHECK:STDOUT: %Add.facet: %Add.type = facet_value %C, %impl_witness.796 [concrete] // CHECK:STDOUT: %AddAssign.type: type = facet_type <@AddAssign> [concrete] // CHECK:STDOUT: %Op.type.421: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.95d: = impl_witness (@impl.14c.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.0b8: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.d8e: %Op.type.0b8 = struct_value () [concrete] @@ -102,18 +102,18 @@ fn TestAssign(b: D) { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.b32 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Add.ref: type = name_ref Add, imports.%Core.Add [concrete = constants.%Add.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.796] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.b32.%Op.decl) [concrete = constants.%impl_witness.796] +// CHECK:STDOUT: impl_decl @impl.14c [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %AddAssign.ref: type = name_ref AddAssign, imports.%Core.AddAssign [concrete = constants.%AddAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.95d] +// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.14c.%Op.decl) [concrete = constants.%impl_witness.95d] // CHECK:STDOUT: %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -142,7 +142,7 @@ fn TestAssign(b: D) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Add.ref { +// CHECK:STDOUT: impl @impl.b32: %C.ref as %Add.ref { // CHECK:STDOUT: %Op.decl: %Op.type.7a3 = fn_decl @Op.2 [concrete = constants.%Op.c84] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -168,7 +168,7 @@ fn TestAssign(b: D) { // CHECK:STDOUT: witness = file.%impl_witness.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %AddAssign.ref { +// CHECK:STDOUT: impl @impl.14c: %C.ref as %AddAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.0b8 = fn_decl @Op.4 [concrete = constants.%Op.d8e] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/implicit_as.carbon b/toolchain/check/testdata/operators/overloaded/implicit_as.carbon index 7e00ad83f7c2a..06d34d7df3e4f 100644 --- a/toolchain/check/testdata/operators/overloaded/implicit_as.carbon +++ b/toolchain/check/testdata/operators/overloaded/implicit_as.carbon @@ -47,13 +47,13 @@ fn Test() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.ac8: type = facet_type <@ImplicitAs, @ImplicitAs(%X)> [concrete] // CHECK:STDOUT: %Convert.type.665: type = fn_type @Convert.1, @ImplicitAs(%X) [concrete] -// CHECK:STDOUT: %impl_witness.226: = impl_witness (@impl.1.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.226: = impl_witness (@impl.8f9.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.853: type = fn_type @Convert.2 [concrete] // CHECK:STDOUT: %Convert.08a: %Convert.type.853 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.a10: %ImplicitAs.type.ac8 = facet_value %i32, %impl_witness.226 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.c53: = impl_witness (@impl.2.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.c53: = impl_witness (@impl.c94.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.8a1: type = fn_type @Convert.3 [concrete] // CHECK:STDOUT: %Convert.c7a: %Convert.type.8a1 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.208: %ImplicitAs.type.205 = facet_value %X, %impl_witness.c53 [concrete] @@ -96,7 +96,7 @@ fn Test() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %X.decl: type = class_decl @X [concrete = constants.%X] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.8f9 [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] @@ -104,8 +104,8 @@ fn Test() { // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%X)> [concrete = constants.%ImplicitAs.type.ac8] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.1.%Convert.decl) [concrete = constants.%impl_witness.226] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.8f9.%Convert.decl) [concrete = constants.%impl_witness.226] +// CHECK:STDOUT: impl_decl @impl.c94 [concrete] {} { // CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %ImplicitAs.ref: %ImplicitAs.type.cc7 = name_ref ImplicitAs, imports.%Core.ImplicitAs [concrete = constants.%ImplicitAs.generic] @@ -113,7 +113,7 @@ fn Test() { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%i32)> [concrete = constants.%ImplicitAs.type.205] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.2.%Convert.decl) [concrete = constants.%impl_witness.c53] +// CHECK:STDOUT: %impl_witness.loc19: = impl_witness (@impl.c94.%Convert.decl) [concrete = constants.%impl_witness.c53] // CHECK:STDOUT: %Sink_i32.decl: %Sink_i32.type = fn_decl @Sink_i32 [concrete = constants.%Sink_i32] { // CHECK:STDOUT: %n.patt: %i32 = binding_pattern n // CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0 @@ -148,7 +148,7 @@ fn Test() { // CHECK:STDOUT: %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %i32 as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.8f9: %i32 as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.853 = fn_decl @Convert.2 [concrete = constants.%Convert.08a] { // CHECK:STDOUT: %self.patt: %i32 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %i32 = value_param_pattern %self.patt, runtime_param0 @@ -172,7 +172,7 @@ fn Test() { // CHECK:STDOUT: witness = file.%impl_witness.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %X.ref as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.c94: %X.ref as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.8a1 = fn_decl @Convert.3 [concrete = constants.%Convert.c7a] { // CHECK:STDOUT: %self.patt: %X = binding_pattern self // CHECK:STDOUT: %self.param_patt: %X = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/inc.carbon b/toolchain/check/testdata/operators/overloaded/inc.carbon index 868f8e8d4e46f..54e80d06f8016 100644 --- a/toolchain/check/testdata/operators/overloaded/inc.carbon +++ b/toolchain/check/testdata/operators/overloaded/inc.carbon @@ -32,7 +32,7 @@ fn TestOp() { // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.e3a: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c51.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.73a: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.0c9: %Op.type.73a = struct_value () [concrete] @@ -60,16 +60,16 @@ fn TestOp() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c51 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Inc.ref: type = name_ref Inc, imports.%Core.Inc [concrete = constants.%Inc.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c51.%Op.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Inc.ref { +// CHECK:STDOUT: impl @impl.c51: %C.ref as %Inc.ref { // CHECK:STDOUT: %Op.decl: %Op.type.73a = fn_decl @Op.2 [concrete = constants.%Op.0c9] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/index.carbon b/toolchain/check/testdata/operators/overloaded/index.carbon index c314f8ce7e825..2fd15d1b9c7cf 100644 --- a/toolchain/check/testdata/operators/overloaded/index.carbon +++ b/toolchain/check/testdata/operators/overloaded/index.carbon @@ -242,7 +242,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.504 = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.type.917: type = facet_type <@IndexWith, @IndexWith(%i32, %i32)> [concrete] // CHECK:STDOUT: %At.type.d77: type = fn_type @At.1, @IndexWith(%i32, %i32) [concrete] -// CHECK:STDOUT: %impl_witness.123: = impl_witness (@impl.1.%At.decl) [concrete] +// CHECK:STDOUT: %impl_witness.123: = impl_witness (@impl.18b.%At.decl) [concrete] // CHECK:STDOUT: %At.type.9ac: type = fn_type @At.2 [concrete] // CHECK:STDOUT: %At.642: %At.type.9ac = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.facet: %IndexWith.type.917 = facet_value %tuple.type.d07, %impl_witness.123 [concrete] @@ -252,8 +252,8 @@ let x: i32 = c[0]; // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -288,7 +288,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: .e = %e // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.18b [concrete] {} { // CHECK:STDOUT: %int_32.loc4_7: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc4_7: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_32.loc4_12: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] @@ -303,7 +303,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: %i32.loc4_40: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(constants.%i32, constants.%i32)> [concrete = constants.%IndexWith.type.917] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%At.decl) [concrete = constants.%impl_witness.123] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.18b.%At.decl) [concrete = constants.%impl_witness.123] // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %s.patt: %tuple.type.d07 = binding_pattern s // CHECK:STDOUT: } @@ -342,7 +342,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: %e: ref %i32 = bind_name e, %.loc11_17.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %.loc4_15.2 as %IndexWith.type { +// CHECK:STDOUT: impl @impl.18b: %.loc4_15.2 as %IndexWith.type { // CHECK:STDOUT: %At.decl: %At.type.9ac = fn_decl @At.2 [concrete = constants.%At.642] { // CHECK:STDOUT: %self.patt: %tuple.type.d07 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %tuple.type.d07 = value_param_pattern %self.patt, runtime_param0 @@ -354,7 +354,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: %int_32.loc5_40: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_40: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %self.param: %tuple.type.d07 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.1.%.loc4_15.2 [concrete = constants.%tuple.type.d07] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.18b.%.loc4_15.2 [concrete = constants.%tuple.type.d07] // CHECK:STDOUT: %self: %tuple.type.d07 = bind_name self, %self.param // CHECK:STDOUT: %subscript.param: %i32 = value_param runtime_param1 // CHECK:STDOUT: %.loc5: type = splice_block %i32.loc5_32 [concrete = constants.%i32] { diff --git a/toolchain/check/testdata/operators/overloaded/left_shift.carbon b/toolchain/check/testdata/operators/overloaded/left_shift.carbon index 21d9630b44543..69d2c33b28a63 100644 --- a/toolchain/check/testdata/operators/overloaded/left_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/left_shift.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %LeftShift.type: type = facet_type <@LeftShift> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.789: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.df4: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.df4: = impl_witness (@impl.c6e.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.de2: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.df9: %Op.type.de2 = struct_value () [concrete] // CHECK:STDOUT: %LeftShift.facet: %LeftShift.type = facet_value %C, %impl_witness.df4 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %LeftShiftAssign.type: type = facet_type <@LeftShiftAssign> [concrete] // CHECK:STDOUT: %Op.type.1de: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.842: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.842: = impl_witness (@impl.29d.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.386: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.8fc: %Op.type.386 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c6e [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %LeftShift.ref: type = name_ref LeftShift, imports.%Core.LeftShift [concrete = constants.%LeftShift.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.df4] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.c6e.%Op.decl) [concrete = constants.%impl_witness.df4] +// CHECK:STDOUT: impl_decl @impl.29d [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %LeftShiftAssign.ref: type = name_ref LeftShiftAssign, imports.%Core.LeftShiftAssign [concrete = constants.%LeftShiftAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.842] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.29d.%Op.decl) [concrete = constants.%impl_witness.842] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %LeftShift.ref { +// CHECK:STDOUT: impl @impl.c6e: %C.ref as %LeftShift.ref { // CHECK:STDOUT: %Op.decl: %Op.type.de2 = fn_decl @Op.2 [concrete = constants.%Op.df9] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %LeftShiftAssign.ref { +// CHECK:STDOUT: impl @impl.29d: %C.ref as %LeftShiftAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.386 = fn_decl @Op.4 [concrete = constants.%Op.8fc] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/mod.carbon b/toolchain/check/testdata/operators/overloaded/mod.carbon index ac54279c1b3f3..a9568e27eadca 100644 --- a/toolchain/check/testdata/operators/overloaded/mod.carbon +++ b/toolchain/check/testdata/operators/overloaded/mod.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %Mod.type: type = facet_type <@Mod> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.860: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.5d5: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.5d5: = impl_witness (@impl.f96.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.fd2: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.777: %Op.type.fd2 = struct_value () [concrete] // CHECK:STDOUT: %Mod.facet: %Mod.type = facet_value %C, %impl_witness.5d5 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %ModAssign.type: type = facet_type <@ModAssign> [concrete] // CHECK:STDOUT: %Op.type.fae: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.5ee: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.5ee: = impl_witness (@impl.587.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.fa2: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.d6c: %Op.type.fa2 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.f96 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Mod.ref: type = name_ref Mod, imports.%Core.Mod [concrete = constants.%Mod.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.5d5] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.f96.%Op.decl) [concrete = constants.%impl_witness.5d5] +// CHECK:STDOUT: impl_decl @impl.587 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %ModAssign.ref: type = name_ref ModAssign, imports.%Core.ModAssign [concrete = constants.%ModAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.5ee] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.587.%Op.decl) [concrete = constants.%impl_witness.5ee] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Mod.ref { +// CHECK:STDOUT: impl @impl.f96: %C.ref as %Mod.ref { // CHECK:STDOUT: %Op.decl: %Op.type.fd2 = fn_decl @Op.2 [concrete = constants.%Op.777] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %ModAssign.ref { +// CHECK:STDOUT: impl @impl.587: %C.ref as %ModAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.fa2 = fn_decl @Op.4 [concrete = constants.%Op.d6c] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/mul.carbon b/toolchain/check/testdata/operators/overloaded/mul.carbon index 5a21d19e7beff..b34feba4c177d 100644 --- a/toolchain/check/testdata/operators/overloaded/mul.carbon +++ b/toolchain/check/testdata/operators/overloaded/mul.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %Mul.type: type = facet_type <@Mul> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.3ae: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.289: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.289: = impl_witness (@impl.4f2.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.fa5: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.550: %Op.type.fa5 = struct_value () [concrete] // CHECK:STDOUT: %Mul.facet: %Mul.type = facet_value %C, %impl_witness.289 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %MulAssign.type: type = facet_type <@MulAssign> [concrete] // CHECK:STDOUT: %Op.type.340: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.de9: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.de9: = impl_witness (@impl.009.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.c02: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.a8c: %Op.type.c02 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.4f2 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Mul.ref: type = name_ref Mul, imports.%Core.Mul [concrete = constants.%Mul.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.289] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.4f2.%Op.decl) [concrete = constants.%impl_witness.289] +// CHECK:STDOUT: impl_decl @impl.009 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %MulAssign.ref: type = name_ref MulAssign, imports.%Core.MulAssign [concrete = constants.%MulAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.de9] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.009.%Op.decl) [concrete = constants.%impl_witness.de9] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Mul.ref { +// CHECK:STDOUT: impl @impl.4f2: %C.ref as %Mul.ref { // CHECK:STDOUT: %Op.decl: %Op.type.fa5 = fn_decl @Op.2 [concrete = constants.%Op.550] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %MulAssign.ref { +// CHECK:STDOUT: impl @impl.009: %C.ref as %MulAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.c02 = fn_decl @Op.4 [concrete = constants.%Op.a8c] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/negate.carbon b/toolchain/check/testdata/operators/overloaded/negate.carbon index d9305affb68c2..709cb430235e5 100644 --- a/toolchain/check/testdata/operators/overloaded/negate.carbon +++ b/toolchain/check/testdata/operators/overloaded/negate.carbon @@ -32,7 +32,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] // CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c34.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.67d: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.64c: %Op.type.67d = struct_value () [concrete] // CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value %C, %impl_witness [concrete] @@ -59,12 +59,12 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.c34 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Negate.ref: type = name_ref Negate, imports.%Core.Negate [concrete = constants.%Negate.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.c34.%Op.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -80,7 +80,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Negate.ref { +// CHECK:STDOUT: impl @impl.c34: %C.ref as %Negate.ref { // CHECK:STDOUT: %Op.decl: %Op.type.67d = fn_decl @Op.2 [concrete = constants.%Op.64c] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/ordered.carbon b/toolchain/check/testdata/operators/overloaded/ordered.carbon index 280b42b861688..d49af2565f0ab 100644 --- a/toolchain/check/testdata/operators/overloaded/ordered.carbon +++ b/toolchain/check/testdata/operators/overloaded/ordered.carbon @@ -86,7 +86,7 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: %LessOrEquivalent.type.859: type = fn_type @LessOrEquivalent.1 [concrete] // CHECK:STDOUT: %Greater.type.270: type = fn_type @Greater.1 [concrete] // CHECK:STDOUT: %GreaterOrEquivalent.type.8af: type = fn_type @GreaterOrEquivalent.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Less.decl, @impl.1.%LessOrEquivalent.decl, @impl.1.%Greater.decl, @impl.1.%GreaterOrEquivalent.decl) [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.d54.%Less.decl, @impl.d54.%LessOrEquivalent.decl, @impl.d54.%Greater.decl, @impl.d54.%GreaterOrEquivalent.decl) [concrete] // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] // CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] // CHECK:STDOUT: %Less.type.25a: type = fn_type @Less.2 [concrete] @@ -133,12 +133,12 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.d54 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Ordered.ref: type = name_ref Ordered, imports.%Core.Ordered [concrete = constants.%Ordered.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.1.%Less.decl, @impl.1.%LessOrEquivalent.decl, @impl.1.%Greater.decl, @impl.1.%GreaterOrEquivalent.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.d54.%Less.decl, @impl.d54.%LessOrEquivalent.decl, @impl.d54.%Greater.decl, @impl.d54.%GreaterOrEquivalent.decl) [concrete = constants.%impl_witness] // CHECK:STDOUT: %TestLess.decl: %TestLess.type = fn_decl @TestLess [concrete = constants.%TestLess] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -221,7 +221,7 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Ordered.ref { +// CHECK:STDOUT: impl @impl.d54: %C.ref as %Ordered.ref { // CHECK:STDOUT: %Less.decl: %Less.type.25a = fn_decl @Less.2 [concrete = constants.%Less.738] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/right_shift.carbon b/toolchain/check/testdata/operators/overloaded/right_shift.carbon index fef52598f5d0e..2f034b0f4b817 100644 --- a/toolchain/check/testdata/operators/overloaded/right_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/right_shift.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %RightShift.type: type = facet_type <@RightShift> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.4f4: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.404: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.404: = impl_witness (@impl.3c1.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.092: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.79a: %Op.type.092 = struct_value () [concrete] // CHECK:STDOUT: %RightShift.facet: %RightShift.type = facet_value %C, %impl_witness.404 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %RightShiftAssign.type: type = facet_type <@RightShiftAssign> [concrete] // CHECK:STDOUT: %Op.type.6f6: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.686: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.686: = impl_witness (@impl.4f0.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.aab: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.7b2: %Op.type.aab = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.3c1 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %RightShift.ref: type = name_ref RightShift, imports.%Core.RightShift [concrete = constants.%RightShift.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.404] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.3c1.%Op.decl) [concrete = constants.%impl_witness.404] +// CHECK:STDOUT: impl_decl @impl.4f0 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %RightShiftAssign.ref: type = name_ref RightShiftAssign, imports.%Core.RightShiftAssign [concrete = constants.%RightShiftAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.686] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.4f0.%Op.decl) [concrete = constants.%impl_witness.686] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %RightShift.ref { +// CHECK:STDOUT: impl @impl.3c1: %C.ref as %RightShift.ref { // CHECK:STDOUT: %Op.decl: %Op.type.092 = fn_decl @Op.2 [concrete = constants.%Op.79a] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %RightShiftAssign.ref { +// CHECK:STDOUT: impl @impl.4f0: %C.ref as %RightShiftAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.aab = fn_decl @Op.4 [concrete = constants.%Op.7b2] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/operators/overloaded/sub.carbon b/toolchain/check/testdata/operators/overloaded/sub.carbon index 8f48af231d3e4..b87c7b01b8bcc 100644 --- a/toolchain/check/testdata/operators/overloaded/sub.carbon +++ b/toolchain/check/testdata/operators/overloaded/sub.carbon @@ -40,14 +40,14 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %Sub.type: type = facet_type <@Sub> [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Op.type.111: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness.3b8: = impl_witness (@impl.1.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.3b8: = impl_witness (@impl.3f9.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.c74: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.151: %Op.type.c74 = struct_value () [concrete] // CHECK:STDOUT: %Sub.facet: %Sub.type = facet_value %C, %impl_witness.3b8 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %SubAssign.type: type = facet_type <@SubAssign> [concrete] // CHECK:STDOUT: %Op.type.f0d: type = fn_type @Op.3 [concrete] -// CHECK:STDOUT: %impl_witness.91c: = impl_witness (@impl.2.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.91c: = impl_witness (@impl.588.%Op.decl) [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %Op.type.966: type = fn_type @Op.4 [concrete] // CHECK:STDOUT: %Op.a55: %Op.type.966 = struct_value () [concrete] @@ -80,18 +80,18 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @impl.1 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.3f9 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Sub.ref: type = name_ref Sub, imports.%Core.Sub [concrete = constants.%Sub.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.1.%Op.decl) [concrete = constants.%impl_witness.3b8] -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.3f9.%Op.decl) [concrete = constants.%impl_witness.3b8] +// CHECK:STDOUT: impl_decl @impl.588 [concrete] {} { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %SubAssign.ref: type = name_ref SubAssign, imports.%Core.SubAssign [concrete = constants.%SubAssign.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.2.%Op.decl) [concrete = constants.%impl_witness.91c] +// CHECK:STDOUT: %impl_witness.loc22: = impl_witness (@impl.588.%Op.decl) [concrete = constants.%impl_witness.91c] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -128,7 +128,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: %C.ref as %Sub.ref { +// CHECK:STDOUT: impl @impl.3f9: %C.ref as %Sub.ref { // CHECK:STDOUT: %Op.decl: %Op.type.c74 = fn_decl @Op.2 [concrete = constants.%Op.151] { // CHECK:STDOUT: %self.patt: %C = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 @@ -154,7 +154,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C.ref as %SubAssign.ref { +// CHECK:STDOUT: impl @impl.588: %C.ref as %SubAssign.ref { // CHECK:STDOUT: %Op.decl: %Op.type.966 = fn_decl @Op.4 [concrete = constants.%Op.a55] { // CHECK:STDOUT: %self.patt: %ptr.019 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %ptr.019 = value_param_pattern %self.patt, runtime_param0 diff --git a/toolchain/check/testdata/package_expr/syntax.carbon b/toolchain/check/testdata/package_expr/syntax.carbon index 2be81d764fe47..d540b68419357 100644 --- a/toolchain/check/testdata/package_expr/syntax.carbon +++ b/toolchain/check/testdata/package_expr/syntax.carbon @@ -49,8 +49,8 @@ fn Main() { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -121,8 +121,8 @@ fn Main() { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/packages/implicit_imports_prelude.carbon b/toolchain/check/testdata/packages/implicit_imports_prelude.carbon index 5bd3126790fea..067148ecdedb8 100644 --- a/toolchain/check/testdata/packages/implicit_imports_prelude.carbon +++ b/toolchain/check/testdata/packages/implicit_imports_prelude.carbon @@ -30,8 +30,8 @@ var b: i32 = a; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/packages/raw_core.carbon b/toolchain/check/testdata/packages/raw_core.carbon index bbb22b357ce31..f9117879c2a0b 100644 --- a/toolchain/check/testdata/packages/raw_core.carbon +++ b/toolchain/check/testdata/packages/raw_core.carbon @@ -201,8 +201,8 @@ var c: r#Core = {.n = 0 as Core.Int(32)}; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] diff --git a/toolchain/check/testdata/pointer/address_of_deref.carbon b/toolchain/check/testdata/pointer/address_of_deref.carbon index 5cbf247848d46..5675cf14c197b 100644 --- a/toolchain/check/testdata/pointer/address_of_deref.carbon +++ b/toolchain/check/testdata/pointer/address_of_deref.carbon @@ -23,8 +23,8 @@ fn F() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/pointer/address_of_lvalue.carbon b/toolchain/check/testdata/pointer/address_of_lvalue.carbon index fff11aece5059..ae81ee9aabbf2 100644 --- a/toolchain/check/testdata/pointer/address_of_lvalue.carbon +++ b/toolchain/check/testdata/pointer/address_of_lvalue.carbon @@ -34,8 +34,8 @@ fn F() { // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/pointer/basic.carbon b/toolchain/check/testdata/pointer/basic.carbon index 153b32cb6add3..9cd01132fa463 100644 --- a/toolchain/check/testdata/pointer/basic.carbon +++ b/toolchain/check/testdata/pointer/basic.carbon @@ -25,8 +25,8 @@ fn F() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/pointer/import.carbon b/toolchain/check/testdata/pointer/import.carbon index ee72710812ee3..dbf6e59447ca3 100644 --- a/toolchain/check/testdata/pointer/import.carbon +++ b/toolchain/check/testdata/pointer/import.carbon @@ -29,8 +29,8 @@ var a: i32* = a_ref; // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/code_after_return_value.carbon b/toolchain/check/testdata/return/code_after_return_value.carbon index 6051a72b11a11..a98788607ee52 100644 --- a/toolchain/check/testdata/return/code_after_return_value.carbon +++ b/toolchain/check/testdata/return/code_after_return_value.carbon @@ -32,8 +32,8 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/fail_return_with_returned_var.carbon b/toolchain/check/testdata/return/fail_return_with_returned_var.carbon index e8bebd2fd8fe8..03ecf03672674 100644 --- a/toolchain/check/testdata/return/fail_return_with_returned_var.carbon +++ b/toolchain/check/testdata/return/fail_return_with_returned_var.carbon @@ -43,8 +43,8 @@ fn G() -> C { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/fail_returned_var_shadow.carbon b/toolchain/check/testdata/return/fail_returned_var_shadow.carbon index 595dc48521222..bf75ba31a9215 100644 --- a/toolchain/check/testdata/return/fail_returned_var_shadow.carbon +++ b/toolchain/check/testdata/return/fail_returned_var_shadow.carbon @@ -51,8 +51,8 @@ fn DifferentScopes() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] 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 3494a00d44e0e..7f40397be9136 100644 --- a/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon +++ b/toolchain/check/testdata/return/no_prelude/import_convert_function.carbon @@ -314,7 +314,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.d38: %Convert.type.010 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.assoc_type.06a: type = assoc_entity_type %ImplicitAs.type.94e [concrete] // CHECK:STDOUT: %assoc0.69d: %ImplicitAs.assoc_type.06a = assoc_entity element0, imports.%Core.import_ref.1c7 [concrete] -// CHECK:STDOUT: %impl_witness.39cb: = impl_witness (@impl.2.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.39cb: = impl_witness (@impl.837.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.fff: type = fn_type @Convert.3 [concrete] // CHECK:STDOUT: %Convert.606: %Convert.type.fff = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.a04: %ImplicitAs.type.94e = facet_value %C.808, %impl_witness.39cb [concrete] @@ -322,7 +322,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.92d: = bound_method %int_1.5b8, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_1.f38: %i32.builtin = int_value 1 [concrete] // CHECK:STDOUT: %C.8be: type = class_type @C, @C(%int_1.f38) [concrete] -// CHECK:STDOUT: %impl_witness.ecb: = impl_witness (@impl.3.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.ecb: = impl_witness (@impl.511.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.89f: type = fn_type @Convert.4 [concrete] // CHECK:STDOUT: %Convert.689: %Convert.type.89f = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.827: %ImplicitAs.type.94e = facet_value %C.8be, %impl_witness.ecb [concrete] @@ -330,7 +330,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.1b9: = bound_method %int_2.ecc, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_2.5a1: %i32.builtin = int_value 2 [concrete] // CHECK:STDOUT: %C.c17: type = class_type @C, @C(%int_2.5a1) [concrete] -// CHECK:STDOUT: %impl_witness.8b8: = impl_witness (@impl.4.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.8b8: = impl_witness (@impl.141.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.e90: type = fn_type @Convert.5 [concrete] // CHECK:STDOUT: %Convert.ec9: %Convert.type.e90 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f40: %ImplicitAs.type.94e = facet_value %C.c17, %impl_witness.8b8 [concrete] @@ -338,7 +338,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.b6b: = bound_method %int_3.1ba, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_3.a0f: %i32.builtin = int_value 3 [concrete] // CHECK:STDOUT: %C.414: type = class_type @C, @C(%int_3.a0f) [concrete] -// CHECK:STDOUT: %impl_witness.1c0: = impl_witness (@impl.5.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.1c0: = impl_witness (@impl.e6b.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.5db: type = fn_type @Convert.6 [concrete] // CHECK:STDOUT: %Convert.193: %Convert.type.5db = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.4b0: %ImplicitAs.type.94e = facet_value %C.414, %impl_witness.1c0 [concrete] @@ -346,7 +346,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.626: = bound_method %int_4.0c1, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_4.4f1: %i32.builtin = int_value 4 [concrete] // CHECK:STDOUT: %C.488: type = class_type @C, @C(%int_4.4f1) [concrete] -// CHECK:STDOUT: %impl_witness.7c9: = impl_witness (@impl.6.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.7c9: = impl_witness (@impl.056.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.4e7: type = fn_type @Convert.7 [concrete] // CHECK:STDOUT: %Convert.52a: %Convert.type.4e7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e09: %ImplicitAs.type.94e = facet_value %C.488, %impl_witness.7c9 [concrete] @@ -354,7 +354,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.910: = bound_method %int_5.64b, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_5.967: %i32.builtin = int_value 5 [concrete] // CHECK:STDOUT: %C.3e2: type = class_type @C, @C(%int_5.967) [concrete] -// CHECK:STDOUT: %impl_witness.4b9: = impl_witness (@impl.7.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.4b9: = impl_witness (@impl.154.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.658: type = fn_type @Convert.8 [concrete] // CHECK:STDOUT: %Convert.9b6: %Convert.type.658 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.210: %ImplicitAs.type.94e = facet_value %C.3e2, %impl_witness.4b9 [concrete] @@ -362,7 +362,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.e3a: = bound_method %int_6.462, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_6.ec5: %i32.builtin = int_value 6 [concrete] // CHECK:STDOUT: %C.78c: type = class_type @C, @C(%int_6.ec5) [concrete] -// CHECK:STDOUT: %impl_witness.4bf: = impl_witness (@impl.8.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.4bf: = impl_witness (@impl.a6d.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.623: type = fn_type @Convert.9 [concrete] // CHECK:STDOUT: %Convert.8c9: %Convert.type.623 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e67: %ImplicitAs.type.94e = facet_value %C.78c, %impl_witness.4bf [concrete] @@ -370,7 +370,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Convert.bound.06a: = bound_method %int_7.29f, %Convert.cb5 [concrete] // CHECK:STDOUT: %int_7.6ae: %i32.builtin = int_value 7 [concrete] // CHECK:STDOUT: %C.6aa: type = class_type @C, @C(%int_7.6ae) [concrete] -// CHECK:STDOUT: %impl_witness.74c: = impl_witness (@impl.9.%Convert.decl) [concrete] +// CHECK:STDOUT: %impl_witness.74c: = impl_witness (@impl.ebc.%Convert.decl) [concrete] // CHECK:STDOUT: %Convert.type.3f8: type = fn_type @Convert.10 [concrete] // CHECK:STDOUT: %Convert.71a: %Convert.type.3f8 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.367: %ImplicitAs.type.94e = facet_value %C.6aa, %impl_witness.74c [concrete] @@ -425,7 +425,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param0 // CHECK:STDOUT: %return: ref %D = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl.2 [concrete] {} { +// CHECK:STDOUT: impl_decl @impl.837 [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -439,8 +439,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (@impl.2.%Convert.decl) [concrete = constants.%impl_witness.39cb] -// CHECK:STDOUT: impl_decl @impl.3 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (@impl.837.%Convert.decl) [concrete = constants.%impl_witness.39cb] +// CHECK:STDOUT: impl_decl @impl.511 [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -454,8 +454,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (@impl.3.%Convert.decl) [concrete = constants.%impl_witness.ecb] -// CHECK:STDOUT: impl_decl @impl.4 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (@impl.511.%Convert.decl) [concrete = constants.%impl_witness.ecb] +// CHECK:STDOUT: impl_decl @impl.141 [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -469,8 +469,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (@impl.4.%Convert.decl) [concrete = constants.%impl_witness.8b8] -// CHECK:STDOUT: impl_decl @impl.5 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc12: = impl_witness (@impl.141.%Convert.decl) [concrete = constants.%impl_witness.8b8] +// CHECK:STDOUT: impl_decl @impl.e6b [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -484,8 +484,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.5.%Convert.decl) [concrete = constants.%impl_witness.1c0] -// CHECK:STDOUT: impl_decl @impl.6 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc13: = impl_witness (@impl.e6b.%Convert.decl) [concrete = constants.%impl_witness.1c0] +// CHECK:STDOUT: impl_decl @impl.056 [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -499,8 +499,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (@impl.6.%Convert.decl) [concrete = constants.%impl_witness.7c9] -// CHECK:STDOUT: impl_decl @impl.7 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc14: = impl_witness (@impl.056.%Convert.decl) [concrete = constants.%impl_witness.7c9] +// CHECK:STDOUT: impl_decl @impl.154 [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -514,8 +514,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.7.%Convert.decl) [concrete = constants.%impl_witness.4b9] -// CHECK:STDOUT: impl_decl @impl.8 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.154.%Convert.decl) [concrete = constants.%impl_witness.4b9] +// CHECK:STDOUT: impl_decl @impl.a6d [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_6: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -529,8 +529,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.8.%Convert.decl) [concrete = constants.%impl_witness.4bf] -// CHECK:STDOUT: impl_decl @impl.9 [concrete] {} { +// CHECK:STDOUT: %impl_witness.loc16: = impl_witness (@impl.a6d.%Convert.decl) [concrete = constants.%impl_witness.4bf] +// CHECK:STDOUT: impl_decl @impl.ebc [concrete] {} { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %int_7: Core.IntLiteral = int_value 7 [concrete = constants.%int_7.29f] // CHECK:STDOUT: %impl.elem0: %.624 = impl_witness_access constants.%impl_witness.39c7, element0 [concrete = constants.%Convert.cb5] @@ -544,7 +544,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%D)> [concrete = constants.%ImplicitAs.type.94e] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.9.%Convert.decl) [concrete = constants.%impl_witness.74c] +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.ebc.%Convert.decl) [concrete = constants.%impl_witness.74c] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic interface @ImplicitAs(imports.%Core.import_ref.f6b058.1: type) [from "core.carbon"] { @@ -567,12 +567,12 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%Core.import_ref.872 as imports.%Core.import_ref.4d9 [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.68b: imports.%Core.import_ref.872 as imports.%Core.import_ref.4d9 [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.de9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.837: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.fff = fn_decl @Convert.3 [concrete = constants.%Convert.606] { // CHECK:STDOUT: %self.patt: %C.808 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.808 = value_param_pattern %self.patt, runtime_param0 @@ -581,7 +581,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.808 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.2.%C [concrete = constants.%C.808] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.837.%C [concrete = constants.%C.808] // CHECK:STDOUT: %self: %C.808 = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -594,7 +594,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.511: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.89f = fn_decl @Convert.4 [concrete = constants.%Convert.689] { // CHECK:STDOUT: %self.patt: %C.8be = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.8be = value_param_pattern %self.patt, runtime_param0 @@ -603,7 +603,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.8be = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.3.%C [concrete = constants.%C.8be] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.511.%C [concrete = constants.%C.8be] // CHECK:STDOUT: %self: %C.8be = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -616,7 +616,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc11 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.141: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.e90 = fn_decl @Convert.5 [concrete = constants.%Convert.ec9] { // CHECK:STDOUT: %self.patt: %C.c17 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.c17 = value_param_pattern %self.patt, runtime_param0 @@ -625,7 +625,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.c17 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.4.%C [concrete = constants.%C.c17] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.141.%C [concrete = constants.%C.c17] // CHECK:STDOUT: %self: %C.c17 = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -638,7 +638,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc12 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.5: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.e6b: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.5db = fn_decl @Convert.6 [concrete = constants.%Convert.193] { // CHECK:STDOUT: %self.patt: %C.414 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.414 = value_param_pattern %self.patt, runtime_param0 @@ -647,7 +647,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.414 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.5.%C [concrete = constants.%C.414] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.e6b.%C [concrete = constants.%C.414] // CHECK:STDOUT: %self: %C.414 = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -660,7 +660,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc13 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.6: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.056: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.4e7 = fn_decl @Convert.7 [concrete = constants.%Convert.52a] { // CHECK:STDOUT: %self.patt: %C.488 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.488 = value_param_pattern %self.patt, runtime_param0 @@ -669,7 +669,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.488 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.6.%C [concrete = constants.%C.488] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.056.%C [concrete = constants.%C.488] // CHECK:STDOUT: %self: %C.488 = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -682,7 +682,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc14 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.7: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.154: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.658 = fn_decl @Convert.8 [concrete = constants.%Convert.9b6] { // CHECK:STDOUT: %self.patt: %C.3e2 = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.3e2 = value_param_pattern %self.patt, runtime_param0 @@ -691,7 +691,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.3e2 = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.7.%C [concrete = constants.%C.3e2] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.154.%C [concrete = constants.%C.3e2] // CHECK:STDOUT: %self: %C.3e2 = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -704,7 +704,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.8: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.a6d: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.623 = fn_decl @Convert.9 [concrete = constants.%Convert.8c9] { // CHECK:STDOUT: %self.patt: %C.78c = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.78c = value_param_pattern %self.patt, runtime_param0 @@ -713,7 +713,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.78c = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.8.%C [concrete = constants.%C.78c] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.a6d.%C [concrete = constants.%C.78c] // CHECK:STDOUT: %self: %C.78c = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -726,7 +726,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: witness = file.%impl_witness.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.9: %C as %ImplicitAs.type { +// CHECK:STDOUT: impl @impl.ebc: %C as %ImplicitAs.type { // CHECK:STDOUT: %Convert.decl: %Convert.type.3f8 = fn_decl @Convert.10 [concrete = constants.%Convert.71a] { // CHECK:STDOUT: %self.patt: %C.6aa = binding_pattern self // CHECK:STDOUT: %self.param_patt: %C.6aa = value_param_pattern %self.patt, runtime_param0 @@ -735,7 +735,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } { // CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %self.param: %C.6aa = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.9.%C [concrete = constants.%C.6aa] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.ebc.%C [concrete = constants.%C.6aa] // CHECK:STDOUT: %self: %C.6aa = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %D = out_param runtime_param1 // CHECK:STDOUT: %return: ref %D = return_slot %return.param @@ -1276,47 +1276,47 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.1: imports.%Core.import_ref.872 as imports.%Core.import_ref.4d9 [from "core.carbon"] { +// CHECK:STDOUT: impl @impl.68b: imports.%Core.import_ref.872 as imports.%Core.import_ref.4d9 [from "core.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Core.import_ref.de9 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.2: imports.%P.import_ref.624 as imports.%P.import_ref.b769fa.1 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.b24: imports.%P.import_ref.624 as imports.%P.import_ref.b769fa.1 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.316 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.3: imports.%P.import_ref.8ff as imports.%P.import_ref.b769fa.2 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.277: imports.%P.import_ref.8ff as imports.%P.import_ref.b769fa.2 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.776 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.4: imports.%P.import_ref.f4d as imports.%P.import_ref.b769fa.3 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.b5f: imports.%P.import_ref.f4d as imports.%P.import_ref.b769fa.3 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.848 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.5: imports.%P.import_ref.dd2 as imports.%P.import_ref.b769fa.4 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.90b: imports.%P.import_ref.dd2 as imports.%P.import_ref.b769fa.4 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.036 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.6: imports.%P.import_ref.2c7 as imports.%P.import_ref.b769fa.5 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.161: imports.%P.import_ref.2c7 as imports.%P.import_ref.b769fa.5 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.e33 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.7: imports.%P.import_ref.759 as imports.%P.import_ref.b769fa.6 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.54a: imports.%P.import_ref.759 as imports.%P.import_ref.b769fa.6 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.1aa // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.8: imports.%P.import_ref.56e as imports.%P.import_ref.b769fa.7 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.d71: imports.%P.import_ref.56e as imports.%P.import_ref.b769fa.7 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.058 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl.9: imports.%P.import_ref.8ba as imports.%P.import_ref.b769fa.8 [from "library.carbon"] { +// CHECK:STDOUT: impl @impl.16b: imports.%P.import_ref.8ba as imports.%P.import_ref.b769fa.8 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.d6f // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/return/returned_var.carbon b/toolchain/check/testdata/return/returned_var.carbon index 2a22a2efbc614..bfbe468748953 100644 --- a/toolchain/check/testdata/return/returned_var.carbon +++ b/toolchain/check/testdata/return/returned_var.carbon @@ -39,8 +39,8 @@ fn G() -> i32 { // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/returned_var_scope.carbon b/toolchain/check/testdata/return/returned_var_scope.carbon index e7e312642b85c..fb3e5ddcf5807 100644 --- a/toolchain/check/testdata/return/returned_var_scope.carbon +++ b/toolchain/check/testdata/return/returned_var_scope.carbon @@ -38,8 +38,8 @@ fn EnclosingButAfter(b: bool) -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/struct.carbon b/toolchain/check/testdata/return/struct.carbon index 16a862b600c2e..0158bcf09aa6b 100644 --- a/toolchain/check/testdata/return/struct.carbon +++ b/toolchain/check/testdata/return/struct.carbon @@ -24,8 +24,8 @@ fn Main() -> {.a: i32} { // CHECK:STDOUT: %struct_type.a.a6c: type = struct_type {.a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/tuple.carbon b/toolchain/check/testdata/return/tuple.carbon index f47109ffeec85..05086ebc8dbe7 100644 --- a/toolchain/check/testdata/return/tuple.carbon +++ b/toolchain/check/testdata/return/tuple.carbon @@ -27,8 +27,8 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/return/value.carbon b/toolchain/check/testdata/return/value.carbon index 9e3866095e849..a480bb376a4ef 100644 --- a/toolchain/check/testdata/return/value.carbon +++ b/toolchain/check/testdata/return/value.carbon @@ -22,8 +22,8 @@ fn Main() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/fail_non_member_access.carbon b/toolchain/check/testdata/struct/fail_non_member_access.carbon index cdafc9ec7d2ae..c4da54198f937 100644 --- a/toolchain/check/testdata/struct/fail_non_member_access.carbon +++ b/toolchain/check/testdata/struct/fail_non_member_access.carbon @@ -25,8 +25,8 @@ var y: i32 = x.b; // CHECK:STDOUT: %struct_type.a.a6c: type = struct_type {.a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index 699f56f075dad..548a4988ed4f4 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -62,8 +62,8 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %struct_type.a.a6c: type = struct_type {.a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -292,8 +292,8 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.b9e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.ea0: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.a8d(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.a8d(%int_32) [concrete] // CHECK:STDOUT: %Convert.4cb: %Convert.type.e14 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.b9e = facet_value Core.IntLiteral, %impl_witness.847 [concrete] // CHECK:STDOUT: %.088: type = fn_type_with_self_type %Convert.type.ea0, %ImplicitAs.facet [concrete] @@ -580,8 +580,8 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.b9e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.ea0: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.a8d(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.a8d(%int_32) [concrete] // CHECK:STDOUT: %Convert.4cb: %Convert.type.e14 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.b9e = facet_value Core.IntLiteral, %impl_witness.847 [concrete] // CHECK:STDOUT: %.088: type = fn_type_with_self_type %Convert.type.ea0, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/member_access.carbon b/toolchain/check/testdata/struct/member_access.carbon index c8f6e543a6b50..1495e6a4ba29f 100644 --- a/toolchain/check/testdata/struct/member_access.carbon +++ b/toolchain/check/testdata/struct/member_access.carbon @@ -26,8 +26,8 @@ var z: i32 = y; // CHECK:STDOUT: %struct_type.a.b.fbb: type = struct_type {.a: f64, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/one_entry.carbon b/toolchain/check/testdata/struct/one_entry.carbon index 8bea30a1c5c56..796108c18ca0a 100644 --- a/toolchain/check/testdata/struct/one_entry.carbon +++ b/toolchain/check/testdata/struct/one_entry.carbon @@ -21,8 +21,8 @@ var y: {.a: i32} = x; // CHECK:STDOUT: %struct_type.a.a6c: type = struct_type {.a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/partially_const.carbon b/toolchain/check/testdata/struct/partially_const.carbon index b3ec95b34a1de..459c3ce1ead84 100644 --- a/toolchain/check/testdata/struct/partially_const.carbon +++ b/toolchain/check/testdata/struct/partially_const.carbon @@ -24,8 +24,8 @@ fn Make(n: i32) -> {.a: i32, .b: i32, .c: i32} { // CHECK:STDOUT: %struct_type.a.b.c.1ee: type = struct_type {.a: Core.IntLiteral, .b: %i32, .c: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/tuple_as_element.carbon b/toolchain/check/testdata/struct/tuple_as_element.carbon index d38ff0d4ced38..afa27a0f583dd 100644 --- a/toolchain/check/testdata/struct/tuple_as_element.carbon +++ b/toolchain/check/testdata/struct/tuple_as_element.carbon @@ -25,8 +25,8 @@ var y: {.a: i32, .b: (i32,)} = x; // CHECK:STDOUT: %struct_type.a.b.057: type = struct_type {.a: Core.IntLiteral, .b: %tuple.type.985} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/struct/two_entries.carbon b/toolchain/check/testdata/struct/two_entries.carbon index 47ff34b7aa0e7..e3bc259dc9962 100644 --- a/toolchain/check/testdata/struct/two_entries.carbon +++ b/toolchain/check/testdata/struct/two_entries.carbon @@ -25,8 +25,8 @@ var y: {.a: i32, .b: i32} = x; // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/element_access.carbon b/toolchain/check/testdata/tuple/access/element_access.carbon index e599e4f4516ab..6f1db14be6428 100644 --- a/toolchain/check/testdata/tuple/access/element_access.carbon +++ b/toolchain/check/testdata/tuple/access/element_access.carbon @@ -23,8 +23,8 @@ var c: i32 = b.0; // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_access_error.carbon b/toolchain/check/testdata/tuple/access/fail_access_error.carbon index bebd16ddd22ad..dbf509ebe703c 100644 --- a/toolchain/check/testdata/tuple/access/fail_access_error.carbon +++ b/toolchain/check/testdata/tuple/access/fail_access_error.carbon @@ -27,8 +27,8 @@ var b: i32 = a.(oops); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_large_index.carbon b/toolchain/check/testdata/tuple/access/fail_large_index.carbon index eef9454e17e19..6f7571a341805 100644 --- a/toolchain/check/testdata/tuple/access/fail_large_index.carbon +++ b/toolchain/check/testdata/tuple/access/fail_large_index.carbon @@ -32,8 +32,8 @@ var d: i32 = b.(0x7FFF_FFFF); // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon index 30f1b6442fa82..17ed689a0b421 100644 --- a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon @@ -28,8 +28,8 @@ var b: i32 = a.(-10); // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_non_deterministic_type.carbon b/toolchain/check/testdata/tuple/access/fail_non_deterministic_type.carbon index 851863b6cf867..35c8a88245efb 100644 --- a/toolchain/check/testdata/tuple/access/fail_non_deterministic_type.carbon +++ b/toolchain/check/testdata/tuple/access/fail_non_deterministic_type.carbon @@ -28,8 +28,8 @@ var c: i32 = a.(b); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_non_int_indexing.carbon b/toolchain/check/testdata/tuple/access/fail_non_int_indexing.carbon index f4d909c47e50b..3d996ba86dfc8 100644 --- a/toolchain/check/testdata/tuple/access/fail_non_int_indexing.carbon +++ b/toolchain/check/testdata/tuple/access/fail_non_int_indexing.carbon @@ -30,8 +30,8 @@ var b: i32 = a.(2.6); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon b/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon index 6740690d1f5c6..ab007f875d53a 100644 --- a/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon +++ b/toolchain/check/testdata/tuple/access/fail_non_tuple_access.carbon @@ -38,8 +38,8 @@ fn Main() { // CHECK:STDOUT: %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_out_of_bound_access.carbon b/toolchain/check/testdata/tuple/access/fail_out_of_bound_access.carbon index 7abd19cd7a5c5..76a45a7192a30 100644 --- a/toolchain/check/testdata/tuple/access/fail_out_of_bound_access.carbon +++ b/toolchain/check/testdata/tuple/access/fail_out_of_bound_access.carbon @@ -27,8 +27,8 @@ var b: i32 = a.2; // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/fail_out_of_bound_not_literal.carbon b/toolchain/check/testdata/tuple/access/fail_out_of_bound_not_literal.carbon index 5785caec4044a..ca5447ae762f3 100644 --- a/toolchain/check/testdata/tuple/access/fail_out_of_bound_not_literal.carbon +++ b/toolchain/check/testdata/tuple/access/fail_out_of_bound_not_literal.carbon @@ -27,8 +27,8 @@ var b: i32 = a.({.index = 2}.index); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/access/index_not_literal.carbon b/toolchain/check/testdata/tuple/access/index_not_literal.carbon index c2399799d7d8c..3c83c49998f06 100644 --- a/toolchain/check/testdata/tuple/access/index_not_literal.carbon +++ b/toolchain/check/testdata/tuple/access/index_not_literal.carbon @@ -29,8 +29,8 @@ var d: i32 = a.({.index = 1 as i32}.index); // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.f7f: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.f7f [concrete] @@ -44,16 +44,16 @@ var d: i32 = a.({.index = 1 as i32}.index); // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.4, @As(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] // CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [concrete] // CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [concrete] // CHECK:STDOUT: %Convert.bound.129: = bound_method %int_0.5c6, %Convert.197 [concrete] // CHECK:STDOUT: %Convert.specific_fn.dc5: = specific_function %Convert.bound.129, @Convert.5(%int_32) [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.023: = impl_witness (imports.%Core.import_ref.85c), @impl.971(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.971(%int_32) [concrete] // CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet.e25: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [concrete] // CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet.e25 [concrete] diff --git a/toolchain/check/testdata/tuple/access/return_value_access.carbon b/toolchain/check/testdata/tuple/access/return_value_access.carbon index 2f49e2a9b28b7..450e62a09a5d9 100644 --- a/toolchain/check/testdata/tuple/access/return_value_access.carbon +++ b/toolchain/check/testdata/tuple/access/return_value_access.carbon @@ -27,8 +27,8 @@ fn Run() -> i32 { // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/fail_element_type_mismatch.carbon b/toolchain/check/testdata/tuple/fail_element_type_mismatch.carbon index aa0c72b194587..dedd60e42d596 100644 --- a/toolchain/check/testdata/tuple/fail_element_type_mismatch.carbon +++ b/toolchain/check/testdata/tuple/fail_element_type_mismatch.carbon @@ -29,8 +29,8 @@ var x: (i32, i32) = (2, 65.89); // CHECK:STDOUT: %tuple.type.2c1: type = tuple_type (Core.IntLiteral, f64) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/import.carbon b/toolchain/check/testdata/tuple/import.carbon index ff54fb4546770..e811009149965 100644 --- a/toolchain/check/testdata/tuple/import.carbon +++ b/toolchain/check/testdata/tuple/import.carbon @@ -65,8 +65,8 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] @@ -321,8 +321,8 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.b9e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.ea0: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.a8d(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.a8d(%int_32) [concrete] // CHECK:STDOUT: %Convert.4cb: %Convert.type.e14 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.b9e = facet_value Core.IntLiteral, %impl_witness.847 [concrete] // CHECK:STDOUT: %.088: type = fn_type_with_self_type %Convert.type.ea0, %ImplicitAs.facet [concrete] @@ -626,8 +626,8 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.b9e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.ea0: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.847: = impl_witness (imports.%Implicit.import_ref.773), @impl.a8d(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.e14: type = fn_type @Convert.2, @impl.a8d(%int_32) [concrete] // CHECK:STDOUT: %Convert.4cb: %Convert.type.e14 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.b9e = facet_value Core.IntLiteral, %impl_witness.847 [concrete] // CHECK:STDOUT: %.088: type = fn_type_with_self_type %Convert.type.ea0, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/nested_tuple.carbon b/toolchain/check/testdata/tuple/nested_tuple.carbon index d75e8ebe8318a..45f55e8a14594 100644 --- a/toolchain/check/testdata/tuple/nested_tuple.carbon +++ b/toolchain/check/testdata/tuple/nested_tuple.carbon @@ -26,8 +26,8 @@ var x: ((i32, i32), i32) = ((12, 76), 6); // CHECK:STDOUT: %tuple.type.acf: type = tuple_type (%tuple.type.f94, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/nested_tuple_in_place.carbon b/toolchain/check/testdata/tuple/nested_tuple_in_place.carbon index dcf669a8d3673..cbe745c9da1d3 100644 --- a/toolchain/check/testdata/tuple/nested_tuple_in_place.carbon +++ b/toolchain/check/testdata/tuple/nested_tuple_in_place.carbon @@ -40,8 +40,8 @@ fn H() { // CHECK:STDOUT: %tuple.type.667: type = tuple_type (Core.IntLiteral, %tuple.type.189, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/one_element.carbon b/toolchain/check/testdata/tuple/one_element.carbon index d612edd24402c..80ba258a87934 100644 --- a/toolchain/check/testdata/tuple/one_element.carbon +++ b/toolchain/check/testdata/tuple/one_element.carbon @@ -22,8 +22,8 @@ var y: (i32,) = x; // CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/check/testdata/tuple/two_elements.carbon b/toolchain/check/testdata/tuple/two_elements.carbon index 5485c82118d71..9e02fce48942b 100644 --- a/toolchain/check/testdata/tuple/two_elements.carbon +++ b/toolchain/check/testdata/tuple/two_elements.carbon @@ -26,8 +26,8 @@ var y: (i32, i32) = x; // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [concrete] +// CHECK:STDOUT: %impl_witness.d39: = impl_witness (imports.%Core.import_ref.a5b), @impl.4f9(%int_32) [concrete] +// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.4f9(%int_32) [concrete] // CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete] // CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete] diff --git a/toolchain/sem_ir/inst_fingerprinter.cpp b/toolchain/sem_ir/inst_fingerprinter.cpp index eee6729eb5425..6620db1e999e9 100644 --- a/toolchain/sem_ir/inst_fingerprinter.cpp +++ b/toolchain/sem_ir/inst_fingerprinter.cpp @@ -22,7 +22,8 @@ struct Worklist { // The file containing the instruction we're currently processing. const File* sem_ir = nullptr; // The instructions we need to compute fingerprints for. - llvm::SmallVector>> + llvm::SmallVector< + std::pair>> todo; // The contents of the current instruction as accumulated so far. This is used // to build a Merkle tree containing a fingerprint for the current @@ -336,38 +337,41 @@ struct Worklist { CARBON_CHECK(!todo.empty()); while (true) { const size_t init_size = todo.size(); - auto [next_sem_ir, next_inst_id_or_block] = todo.back(); + auto [next_sem_ir, next] = todo.back(); sem_ir = next_sem_ir; contents.clear(); - if (auto* inst_block_id = - std::get_if(&next_inst_id_or_block)) { - // Add all the instructions in the block so they all contribute to the - // `contents`. - Add(*inst_block_id); + if (!std::holds_alternative(next)) { + // Add the contents of the `next` instruction so they all contribute to + // the `contents`. + if (auto* impl_id = std::get_if(&next)) { + Add(*impl_id); + } else if (auto* inst_block_id = std::get_if(&next)) { + Add(*inst_block_id); + } // If we didn't add any more work, then we have a fingerprint for the - // instruction block, otherwise we wait until that work is completed. If - // the block is the last thing in `todo`, we return the fingerprint. + // `next` instruction, otherwise we wait until that work is completed. + // If the `next` is the last thing in `todo`, we return the fingerprint. // Otherwise we would just discard it because we don't currently cache - // the fingerprint for blocks, but we really only expect `InstBlockId` - // to be at the bottom of the `todo` stack since they are not added to - // `todo` during Run(). + // the fingerprint for things other than `InstId`, but we really only + // expect other `next` types to be at the bottom of the `todo` stack + // since they are not added to `todo` during Run(). if (todo.size() == init_size) { auto fingerprint = Finish(); todo.pop_back(); CARBON_CHECK(todo.empty(), - "An InstBlockId was inserted into `todo` during Run()"); + "A non-InstId was inserted into `todo` during Run()"); return fingerprint; } - // Move on to processing the instructions in the block; we will come + // Move on to processing the instructions added above; we will come // back to this branch once they are done. continue; } - auto next_inst_id = std::get(next_inst_id_or_block); + auto next_inst_id = std::get(next); // If we already have a fingerprint for this instruction, we have nothing // to do. Just pop it from `todo`. @@ -429,4 +433,11 @@ auto InstFingerprinter::GetOrCompute(const File* file, return worklist.Run(); } +auto InstFingerprinter::GetOrCompute(const File* file, ImplId impl_id) + -> uint64_t { + Worklist worklist = {.todo = {{file, impl_id}}, + .fingerprints = &fingerprints_}; + return worklist.Run(); +} + } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/inst_fingerprinter.h b/toolchain/sem_ir/inst_fingerprinter.h index 23ffbf386b3be..f8fef9a81623f 100644 --- a/toolchain/sem_ir/inst_fingerprinter.h +++ b/toolchain/sem_ir/inst_fingerprinter.h @@ -20,6 +20,9 @@ class InstFingerprinter { // Gets or computes a fingerprint for the given instruction block. auto GetOrCompute(const File* file, InstBlockId inst_block_id) -> uint64_t; + // Gets or computes a fingerprint for the given impl. + auto GetOrCompute(const File* file, ImplId impl_id) -> uint64_t; + private: // The fingerprint for each instruction that has had its fingerprint computed, // indexed by the InstId's index. diff --git a/toolchain/sem_ir/inst_namer.cpp b/toolchain/sem_ir/inst_namer.cpp index 9334840870e35..527158db5c751 100644 --- a/toolchain/sem_ir/inst_namer.cpp +++ b/toolchain/sem_ir/inst_namer.cpp @@ -103,12 +103,12 @@ InstNamer::InstNamer(const File* sem_ir) : sem_ir_(sem_ir) { // Build each impl scope. for (auto [impl_id, impl_info] : sem_ir->impls().enumerate()) { auto impl_scope = GetScopeFor(impl_id); - // TODO: Provide a location for the impl for use as a disambiguator. - auto impl_loc = Parse::NodeId::None; + auto impl_fingerprint = fingerprinter_.GetOrCompute(sem_ir_, impl_id); // TODO: Invent a name based on the self and constraint types. GetScopeInfo(impl_scope).name = - globals_.AllocateName(*this, impl_loc, "impl"); - AddBlockLabel(impl_scope, impl_info.body_block_id, "impl", impl_loc); + globals_.AllocateName(*this, impl_fingerprint, "impl"); + AddBlockLabel(impl_scope, impl_info.body_block_id, "impl", + impl_fingerprint); CollectNamesInBlock(impl_scope, impl_info.body_block_id); CollectNamesInGeneric(impl_scope, impl_info.generic_id); } @@ -292,22 +292,24 @@ auto InstNamer::Namespace::AllocateName( } } -auto InstNamer::AddBlockLabel(ScopeId scope_id, InstBlockId block_id, - std::string name, SemIR::LocId loc_id) -> void { +auto InstNamer::AddBlockLabel( + ScopeId scope_id, InstBlockId block_id, std::string name, + std::variant loc_id_or_fingerprint) -> void { if (!block_id.has_value() || labels_[block_id.index].second) { return; } - if (!loc_id.has_value()) { + if (auto* loc_id = std::get_if(&loc_id_or_fingerprint); + loc_id && !loc_id->has_value()) { if (const auto& block = sem_ir_->inst_blocks().Get(block_id); !block.empty()) { - loc_id = sem_ir_->insts().GetLocId(block.front()); + loc_id_or_fingerprint = sem_ir_->insts().GetLocId(block.front()); } } labels_[block_id.index] = { - scope_id, GetScopeInfo(scope_id).labels.AllocateName(*this, loc_id, - std::move(name))}; + scope_id, GetScopeInfo(scope_id).labels.AllocateName( + *this, loc_id_or_fingerprint, std::move(name))}; } // Finds and adds a suitable block label for the given SemIR instruction that diff --git a/toolchain/sem_ir/inst_namer.h b/toolchain/sem_ir/inst_namer.h index 5e593b6e63e59..0021aa306a193 100644 --- a/toolchain/sem_ir/inst_namer.h +++ b/toolchain/sem_ir/inst_namer.h @@ -156,7 +156,8 @@ class InstNamer { auto AddBlockLabel(ScopeId scope_id, InstBlockId block_id, std::string name = "", - SemIR::LocId loc_id = SemIR::LocId::None) -> void; + std::variant + loc_id_or_fingerprint = SemIR::LocId::None) -> void; // Finds and adds a suitable block label for the given SemIR instruction that // represents some kind of branch. From 977578add1e3d0aa303e736e2a8dde1fde056748 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 16:00:55 -0800 Subject: [PATCH 29/56] Update icons for slightly better sizing (#5013) Changes utils/vscode/images/icon.png to 256x256 (["The path to the icon of at least 128x128 pixels (256x256 for Retina screens)."](https://code.visualstudio.com/api/references/extension-manifest#fields)), and updates the favicon.png to use the same source image. For reference, changing this to: https://docs.google.com/drawings/d/16V_E_LS7zqZu6VkNdZgIMqSwc96eV_fw98nIYoY1bBg/edit The image changes slightly because I don't recall my prior source (and it didn't seem important to precisely match font size), but hopefully the drawing helps. --- utils/vscode/images/icon.png | Bin 28 -> 7197 bytes website/favicon.png | Bin 1150 -> 1248 bytes 2 files changed, 0 insertions(+), 0 deletions(-) mode change 120000 => 100644 utils/vscode/images/icon.png diff --git a/utils/vscode/images/icon.png b/utils/vscode/images/icon.png deleted file mode 120000 index 88e81e887cc92..0000000000000 --- a/utils/vscode/images/icon.png +++ /dev/null @@ -1 +0,0 @@ -../../../website/favicon.png \ No newline at end of file diff --git a/utils/vscode/images/icon.png b/utils/vscode/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8d8f5a4858671251a9196b15530afc3c9743e231 GIT binary patch literal 7197 zcmXw8cRbYb8@E?R_9iPcqi|OCI@z)!GepFp5YEavBRiX{GBPqxW|@ULq!i9Lj>?FW zyK~3ytKaYU*FCT2^W5`&p3mp`JmdXIwKO+kpyQzkdOi-DG3b~@Z%i( z%A16Q7X{YWxgGAZTNcs5_N6l!luHl0qGJ$5E5zA;*+`Mcl2yBzD%#>IC4|iMbL$YP z6-BxS1tL7Za@{)qkCYYLu_Vt%tW}Yyg}j7r{6t#oXL*T)q#}~znU*_~o4>b$_jeoi zey$7#zTRir9_VZ|FT1;Z_tA`|uqd*A!+-bp`tM(SYkV6rj|NatU*S{mzI5KwIP}+* z$bzWT?sJj)fQ*9qF6Qd?_6f&ZG(v4Q%MpD?9_YI>k~8p`FIB9nKcH)+8&TgQO4{EZ zIS4(yO&e8JvDt^f)r7=_yxktT)$3F$s3I8Vg4P&y)T0qP{rqilI-;UR^UIOKqV!L1 zFtLg27a`DxTxf)gT2)&m8B!dQyRBa-2~vBh zcB;xtClq1IioSw2MGGLx$_n-w(Z6QSW(;+W1!6N{7WgpH`3}Fm(1D%4Sx0*s zFc-h*F_(YI_ROv7V_vjAdPmooQFT^z3Rk~vZqhFDu!@oSO#g}_N)&w$Of)=J7oE=F z3X#`QAxRyX_*6P)5T;qo2Wda{0^jr&6ZMo2-lap2SE=)wbqT6P(g@j-kXz$bw3wIM z?n80eHHLRstc9Maai;AVD-Mo=;+u6RphIl-p)7+NpWhuugBjGXic%bXhipvjOLVkG zFD&Y&ILfoW*2k)RdQ%vYT9lehr$9OOyoG&P=#|-56**?>1A?~o28PI}Eg5BoZLhpi zFIn&Y*2$nE)Z`;O@(qVTp6+5<&tz~Bh(OQ+X z6=(IWbD`-G;(4NF;QWF^3*p+LluouMv|yQ6Y&KH(5i6eBXW)iVb@1hD ziSNUG|Bf)c+tOtrEf_KBo@cLx^txCp2^(h)l`Z~A90mFA=_B<7QBSBG>&k051~3*h zweZWAUcI>kDbQA!iKwz5tA%4?#J+&Q>3rh#wT;BFmx{Eq&*!aoMXA(iEB5D5X_~MB z6Jd&kNR_~ftu!tuv@OfH=L7s!sEAGRJ%rCG?PSV>#7hrm3GB~ksV~*Dyf*+z)Z(_U z=}L{Z7=VOpaWZ(tdJ+QaWug>bS(2LIa>$!8s~en^)v@|eD-es& zTuoNhh6lv`7_IHkFZ4b)+P72&A_s`~2{LFROK9!1H*8;k zfF0LjECvNOciprjB=2pGpK3Qrd`oD^3Qypoe_U5u5qLf@cTGZpS~r zKxe!YTL#b6up5HsTuY&IW;!Lx0rQ%(!3Ibp#zKl4FALHhvfasK;8CQZqUXBYcQm6u z+q(m6IGZAs#rZnebn^w0j&KdtW>FI_b&X1kiq9;8L?$>R65`Sthr zt*?}qbm{1qRF~8Aq5nEG5tbEZJL_>c%Y-#dA ztBITuKH~B3Zwd~B(0=5}WOviux5_Fi^Dq4FGO1yo_bK{Q|C9KrRV7~{P%*g-qWTUk8-ek@y4qd@Cmd?$3 z)d~WE1T8rFP+q&!@ojwJwNr9_Lhqwr9L|xuox{L^3UY8v+P)^O;8%Z4QKt6Dde?tq zI%m}?zQ-n2z2MBege^DX@&3y0$y!saRU)gnIlT`{6*P7*(3aV2*z)S{BA;?v<-nES z$x}Q)(9*+Tu=z9YLnW{T(O|y`Y@xo};r6lM8Wfq4zwiCMEanWirsxq;=;XO+F$_D$E^6zqbF2b}MmgqYObwBf{b?DzkA817e1O1D#>s}@^Ti+|7_#OAM zA%B}YcN+eVW<4l97SqW~Spnyom#KZ(Z)}URSalW~klW*r!XS*!WXI?l_)bsVC*Fz) zb+FhSGmJ_M`nS5jPip0QC8+h)Lzu}VcFp^)vbH+kqj@Vot@Iu%N$`)WbD~> z4c1CcIetn$@tMN)??=mF4?oHgHMu1nLf=0tkz3D3v07-X30k98R}ut&WZf0}=+>|= zj8ONO=@G}dVaf$>AV=^|=jzOkn66p3>H--o!ZdP%t5ASH&mpLJ^_r9)*u{CqEL z&_?0tO9GRo%3nHT&+$xK2*aY;8wzjHXyGT+Q>lNBA#t+~xZw9KRqOGoFZv*DzH@a4 z;zfdAQv^*41}L3{)Ou8{MwOdcR=7SQJA7@}+b@skSF7k0LA2_G-rnNCI)u7~coaDE ztyTr^!O;!jiT6q^sDku3Lf8p~h9mv44yqQRmLVRMx11}^o@t%+!0hjPIEJvDrKg<{ zPa6x9eoH7^zZfS?Ym6UDGHugwrAgVrKhR<1Z1s zQ_}xzj5mfSML7s>(X6EpRsx~Zc5OTE-ob{Wd~<#l4hoarSd_P0dFC_e6xjbIu)ugIR_eitt;VM;ns5_L(sTs6EDTSS zW=Ue;t@Cg^D)h`u4R9WP2E~W~UbBkn@qimJS%dC29*+d0tc@5rhDIv6w8{-O8swvX z1a#LsBoW3OEv~QfAb6F;3mP)XZyz0dIzCz*ih~~Mzx%z|ZY$&YH=jP-2tzfU>hl2- z%X0>mX;k)|6)mVB#TF!vcSAMw283*DQbV3^GZf#*Y&mz0KDHe;JDI+%!I(jwCv)P- z&C(dU@iMBGTl9(Nmj7H`2C_nUE!#-Is;wz4UH~$*Il3uTPjI!&l@trZ&c$rUWiuI5$%>#d#ldF;95lore$Cn)xo9sntcc*1_klp#kk5qO z4_1ezILvUL^_Xze?6f`=(OodFDRfOdABq6DRLCj@-?$=q>B&_@&sAsQ;qyVj6u6Ex zWi%6w2^}uRe^v#0?pZ8l$boOWZ$iJEK|T*T@Z|0&yB!;8aQ;G7;a0$pt^lakhr;JB zPr##9=YO*F7*oBpFYmv7x+26LYa3H0UKW~zOco}6#!hqyb+vDDSOYnYRj%g2Ce(zX?^q>8^`{NYOOUsw8%er2llk}nrd4Cp4#Nz4jk z% zq!?>eJKpBGn-+r#*}Ur4SK;V#8(=?Pbl>8x17yJ^N)NWs4@EWb+tpGWwW=6jN%A^c ze4zXet$67wuuzHW6il1tQ#1O|sy5AQ%46^Aw@~+z_UIC>p!XdQN#yRr>ynDM*+InP zuNOvJ<`G+V^A>zv6dzP*MiZ7Yp1Km&IWIJK<=gbuL<~1UY{_&xowP1E?Khl3Q!xPR znoaah?ehlU|KHBc;i}V@y!o%+O99jZJ)s;s@cFc*=aI90ZVNy)x!6$7yP+4Gmuax~ z(bLyOURsW1J}bBM(7Kp&>cb@xB~+SuQP~z{`yrV&gX)}Q+FYNToeRk;Ax>2<$N!6* zt9p6;j}{GfUAVBUkHk{1`O$|lMY+O!P7*(36x89$XTZD*zVOL=u>|6O)r$sKaK^s5 zP|oc_f@Q5tzYs{$A`NG4{Vxe3#c}{Dlfz9y}6+$Z8v28Ar63G3Bh0l46si?e*P==Jz^_^qRRdIdvOj>*t6IB>$Z$Zh(s_{&Sti6xTZ`!>~9E&#W0hv-ovU`FZ(Ex zJ9mrWDsWX_11BZ___xEwNx@2yAH{rE+-5nh-N6FNpJ^PXT*SG-%>HJNA`n+Ek_CPO z)|r;6*#b8xSr~m{JqN!zU1HknInJmRb7Sju_lh+{Vmf=`5sIKGbD3zEE9*M2^a+{n z*l|A_rstcf-z;6u2C!$!Z~nMocRwuqA3F&Ktp-;_Y;gm6yg!xS9M+-cuK|oD&;A8# z*B?aGh>3|o&kS{e2FVt1?Mm=nE2D4`dBtX09j<$*ao|D=k7xh#jkrhv?L9r;F17*x zvk{POmkEv<%u6{V4*`0wC4i5e4un<%s=cx|PHRiHwd8#|{l3HlZ7?2Jq5zB=4S>@H z2ATWMMV@w&>T=3DZv!{7$)Qbm^o3%YaCi2`=3(2mmLeK8nM)*0b7|0xSb74N!jT0Y zt-Z%iOy25SOX4LEGM)nG`^q8D8;tr(x+8&Sn#Sc;5Jmt4w7=s6_K&X%&(J|#@pZ8s$pJtMR&Raeh}(D6ylE1jSflrj3Un)N7So8_dfug z297Ana$x)Qnb-2;-S4<*Hd>~em@Jr=F)Aou;asuOd%AddEQ6P*nXe#i-%KygkNYE| z?l&(1)X!n;yQci!)BU*#xEaRKOx5cH+n|NPJD~Zl_i+3x7lTVf>T@TQ^q7?>+qR{r zEEzERjM!9x{6D10_D<~EXUn_4qhSBokiiSe^dk9;JUUtV2?Wyel?Q&++(S{?Yp|Sa}M4Uw+>OcpO5&wS{H-t;Xz-5R-uZ=x zBj!`gSvyiOJLsb2b1>AO5e^e^FWe@n8&OK+B=INYU)rV}1glr&*x&(88-oMlDM+=D5)n7cIk5 z9&;7}G+Ro3^E5Aijp=-CzH6%?B5W^$7FBSOyXhaC|Y@NtIJZVz$>nMxv`! zjfj@>2`iMJj43Do=e)uRR_afhr%f;~oh997*$SRx=|LP-g6)?2i7P!l zf5vz(92ajle1rxD0e3@sdi=qACgK?F&i+~j{!7oOiFIS2i=8k)-Lu<~ zd}3s}2oLcYWHO{Gr^D>b8I4Z)D3q#YLfDWHAkZ5N4fSQc`Aroat~~KE#eIL!f+Nab z2j*br(y)~XDR0g1RR(FRjV%L*ObXX6-6-3Yi9J;MjE2fPFW<1Gtq9q4`OaNku;`pF z0a5S%=(dL(O^Rfy2xBpG7DT-?w)b9x*$Jwfzim_uWF>((sE+@eJcxP7ZVu+8S$@UDNltVdtsLaFd zFy_UFanu3_r#>=n6G2B?)3yZBlt8_cY+|^-V z>RvsWa~O(_b9x9Dv#MS>aKPkRX#NRP;yB3N1_nCYQ#XCoo%NyWlx|?|l}v-d-mUd5 zlGz4E9{*%#G(9{Ka{>~B^1}FwogN^Q&O^DFRSVk3q106qa9fOd2@5Uv36Vt5ndU%3 z#>q8Rp=AHvB{}+)s3Wr&dk<>%y!4f0qlZG{EEzbms)Gfmz~j>ZyP=G3aPHN_XAA&z zRryr4E6szq(eCx3o=;-pCC)qidzVD6VYoS!%3|32kG2Q^uC;%HY>H1*R%oLEZOTW` zQW{w#oCniXX=mh9 zk;k44p6{MS9A0bpo~C2eA_RSTI3|-%R@HnYf}r-bqc6#5*ESr8H_8O_tdxpmOHUNV zSJj3jY$qs5H=O?~;iS1uPTjKGKqKiVk|1o9B~1zDL_b7O2iPrfa%o0|JDh!#0_N>Y z#frXF-^VH^7*NJK0HRF}+J}tubN*0^0B;_B(qfVwz(j^PQ3IfO! z-L#SX)nHOpcbG`oM*|QQae<0~hXNS1XvTNZH@K!j0F+n>jO#zSd<)4ZD0BJ5`6R=& z6=0XO7+QY@XvQ70QZotg&9}I^^0PAh0}ShOxmu*0xfMhh=OQ8G*HYaE4`h%*@MaiH z^Vxufs1geDeA}>U^BVvm9(eN%aNm1Nh6r2zBQ|z@32@TApEO3$_YUIgCGWz(+s>Oy zBE4<*DgD2-x(A)%(9}S>@KM>hKMG@qHha_O@TWxq-IbDaB4_RAUtbzu{!J{9#;f4f z!0+7<42F#o z%^6*Ik7Td#kXdLNgz$;z))GFL%1cPRKaeu;0Zm{|u(IJ(HqDjAOBi8CDaOp?IG4Bc zt`2X$Ya_NL6xkfQRZ2lSz^Fdij0V_bX}og1M!J$CI%HUCe4FfMx@6?? zDlV~x*YIrACn#D6t4B%OxyHV>r9zagCM`;>b$A-I`2{c!OBqPed^(_inD-CPhhMBvPl6{?Fv&jhLX;(Nbg7_KPM$suI5sJ&Aqwu>bX@yhm^CstqB@~!(=+62t6%bB_jA(yTe^n@-Z^+o z@z#=PZ~I){ecle{?{oo%#>0@T_Ua=6pg@A%%sNQFlLf?g35~F2lr5K@sG`-n)68>p zna7hnN7~j4A-|tyU7v@P|L=7Qg*G5PO^+T|Sak?8RZ-S878_RiyHUoez8`F!JuklF zhe&-M(8lzQ^Ec~XhSQYj&2N#qZ%8z4oo@LRH4Nl5c&Hm%Uvh9mdH?aIGsYz`f*~vd0w;k3-g*pKvkvWx{t8AARryp8ZI`2Il(Bx^D6R0XhUH A#sB~S literal 0 HcmV?d00001 diff --git a/website/favicon.png b/website/favicon.png index 6eb787ba056cf6316baa0c750563c1336d07220c..743e383b53ed8bdd2b2b6ae99125054c8cc40694 100644 GIT binary patch delta 1228 zcmV;-1T*{o2;d2jB!8z#L_t(|Ue%gANNqs~w9(!oAU?3s z#zauCF#$oa5LCpNh=N#%HWrGFg^7qDSolCptOQ94A4LKt3h{;SmHGG8lRdM}-uuiw zo_)PPd?3z0Gi&x^X3gv)#OvsDNrU7k$U{@2B0}U3z+YBD*dwE@)+Cg<4x%DKRmT)%5_eg#0++g*AHS6A}_= zaBz_B@9&kMopf??LQPFgtQ`*!ljn<#>C0%gNl8hejg1XG#*j2VK2A|lQLIfDFgv+U zv6$!eN{+ETN_nXRasP5SJTkY5PzMWo#|E@7#LvfdVqBzsM3Yu zA~iBHq6Bkwbw!Phjm-B#YHBJiEiEZ^@UCExy4M9PcE|>pu$1d&M~aGylxP0&@zJ`{ zx=$x2CWhA5)@(x{+S%D*J`a8nnvhHx6BEqiL~d>_d*RE<%9zguJSm?D zn~+uNCVxlpDBRuM1v*DCm_l`*8?&>sw(yCDhliQR17xuQ8KuN6EiFpt%gf8m<3(Lv zoze!@4&CFyhIke>BTqpLj?B%?DV=w8bTE$>>FMc88#gyM6dN1Md@dkn#BS}R^g>q- z4-b{j4WHitNHgq2M@KV{2iVzJ+d#d*5v;nHaewSePEKY%pFr&5mmmd>UCdP<0IBIYP67H#k32FobK@v zYkwg#N+pob>!~oZQ{Cqih}}Gy+uz?;22fd9$vmMDW-b&+<{+bVdU|?V89;Y;H}iOr zk&&UaaeaMl-Cf=10%8uxXhYM`(4cgVjlJ&iqQ1U9+%^z%Kt@~2q@*M|KR*w2j*WR? zVIlLmF+V?V3!kW`r-yl5K&Zc13(u=XNG3y|=xw)CTy1Hm_anaiR*nfq` zsHUcdwdn$4b3Iywj1G4(^-WDpDS?F|oZ?|N)7x_aF(I~)WPH4iX%SaG6yX>qKR=(f z;eyfe`iqP|aNus#*4EPGB!5LoL_t(|oYb1XOKV9K$G_hEc;dqsi>IREFR+Oq{y?xuqbrDt zd6kt`f`7njAqWy|lKrMm;?}xy*^I6Wc2Kw(0Ebq_eX# zGNQx7L#nN<6>-9o?G-yC0`GJ>>FMdo5PV90zn|LM+eMt1c@MruWRY?>9Q6GB%)o7K zZc=x5H`#19vREusU0qEhBO`Qja>85}3Wcb#v60t-$A9-$?C-qrB_${?q}c^&wf zxdEKug*ThcbaQi~L->5Y%Kh&+XfbO(O$HqhJK%Ro#|PaC#X6omqT zfNrb4Vt)l3_>qFI7ci#9#YM(}mX;PS`}DbxNFgwv!f8XEV!{hOA z+0W0jt=*=$f0MXx_RJjez!sz#OKE3cLM1k#mAB!6T=@#w4Sz~_A3U4lL<`6kF!inci_ zR6QzM#*9nxc$}%5OeUF7JPIjVx{phlZ=KT8QkhUZ`b*Jrm0XHOqX+~7dcCTuN;a5L zdCgj)m0Lca4;2*^$=^*)P2BcnWo60rBqen*jKyNS&HM?`&D_$`60@1J+wENT>+9=` zeSdj*xzJ`#(Nf%QUe{eN7gHY?7~ryZI2`)#^Ye2AgF#*dcY1oBJD^b`t6(sw_u%R2 zX>y-$#I~cOgX#U%)m4$+X960bkaBi*mI0ZZoHS&&zrWAewY9bJ!oLYAArjQ9L5Sb) z*Fj!hUTA1&=wEFX78V%z-Q8W0-hUI+Lw_`_(%08Vu~>|8VtIL)nwy)GsYUe~tJRv! z$Q>LUFz}&Jh#DFic;Vkot3WidH99&<(P)%16^TUX?(R-cF{Vomh-4?WkV|S&?cvMI z%Qv9^q@$xFs;jFLfzO&+L@vqQ;^JZ&A0H=|%SGXEn1Q~&zNU?h4eIaj*M}Bo31Vw( zh9o7uu1<1wfl?jIu`RCjdP)U-z>)4m!5%TC^evBveBW|~PpP1fSyL+LgYI+{?575q v`d@tPQ6$NkY@gda0SJD?=Qe)_00960Dxv2Vmw@t(00000NkvXXu0mjfK07(O From 46752eeed63b77527e0abbf3c0a20ba36de4f2e7 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 16:01:09 -0800 Subject: [PATCH 30/56] Change manifest passing to drop the flag outside explorer (#5025) --- explorer/file_test.cpp | 7 +++++++ testing/file_test/BUILD | 3 +++ testing/file_test/file_test_base.cpp | 8 ++------ testing/file_test/file_test_base.h | 5 +++++ testing/file_test/file_test_manifest.cpp | 13 +++++++++++++ testing/file_test/rules.bzl | 11 +++++++++-- 6 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 testing/file_test/file_test_manifest.cpp diff --git a/explorer/file_test.cpp b/explorer/file_test.cpp index a255d26b85f7d..22a28f3ffd3b6 100644 --- a/explorer/file_test.cpp +++ b/explorer/file_test.cpp @@ -12,6 +12,8 @@ ABSL_FLAG(bool, trace, false, "Set to true to run tests with tracing enabled, even if they don't " "otherwise specify it. This does not result in checking trace output " "contents; it essentially only verifies there's not a crash bug."); +ABSL_FLAG(std::string, explorer_test_targets_file, "", + "A path to a file containing repo-relative names of test files."); namespace Carbon::Testing { namespace { @@ -112,6 +114,11 @@ class ExplorerFileTest : public FileTestBase { } // namespace +// Explorer uses a non-standard approach to getting the manifest path. +auto GetFileTestManifestPath() -> std::filesystem::path { + return absl::GetFlag(FLAGS_explorer_test_targets_file); +} + CARBON_FILE_TEST_FACTORY(ExplorerFileTest) } // namespace Carbon::Testing diff --git a/testing/file_test/BUILD b/testing/file_test/BUILD index db3e9d72d3586..63e61ec29b93c 100644 --- a/testing/file_test/BUILD +++ b/testing/file_test/BUILD @@ -7,6 +7,9 @@ load("rules.bzl", "file_test") package(default_visibility = ["//visibility:public"]) +# Used to access a `#define` with the manifest file, produced by rules.bzl. +exports_files(["file_test_manifest.cpp"]) + cc_library( name = "autoupdate", testonly = 1, diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index a8ad338b930b7..6a2c325c3fd3b 100644 --- a/testing/file_test/file_test_base.cpp +++ b/testing/file_test/file_test_base.cpp @@ -51,8 +51,6 @@ ABSL_FLAG(std::vector, file_tests, {}, "A comma-separated list of repo-relative names of test files. " "Similar to and overrides `--gtest_filter`, but doesn't require the " "test class name to be known."); -ABSL_FLAG(std::string, test_targets_file, "", - "A path to a file containing repo-relative names of test files."); ABSL_FLAG(bool, autoupdate, false, "Instead of verifying files match test output, autoupdate files " "based on test output."); @@ -300,11 +298,9 @@ static auto RegisterTests(FileTestFactory* test_factory, llvm::StringRef exe_path, llvm::SmallVectorImpl& tests) -> ErrorOr { - if (absl::GetFlag(FLAGS_test_targets_file).empty()) { - return Error("Missing --test_targets_file."); - } + GetFileTestManifestPath(); CARBON_ASSIGN_OR_RETURN(auto test_manifest, - ReadFile(absl::GetFlag(FLAGS_test_targets_file))); + ReadFile(GetFileTestManifestPath())); // Prepare the vector first, so that the location of entries won't change. for (const auto& test_name : diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index 390452ab0f690..6c7433685eb5c 100644 --- a/testing/file_test/file_test_base.h +++ b/testing/file_test/file_test_base.h @@ -133,6 +133,11 @@ struct FileTestFactory { // to implement this function. extern auto GetFileTestFactory() -> FileTestFactory; +// Returns the manifest path, which is provided by rules.bzl and +// file_test_manifest.cpp. This is exposed so that the explorer sharding +// approach can use a different implementation. +auto GetFileTestManifestPath() -> std::filesystem::path; + // Provides a standard GetFileTestFactory implementation. #define CARBON_FILE_TEST_FACTORY(Name) \ auto GetFileTestFactory() -> FileTestFactory { \ diff --git a/testing/file_test/file_test_manifest.cpp b/testing/file_test/file_test_manifest.cpp new file mode 100644 index 0000000000000..9467c93e1e891 --- /dev/null +++ b/testing/file_test/file_test_manifest.cpp @@ -0,0 +1,13 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "testing/file_test/file_test_base.h" + +namespace Carbon::Testing { + +auto GetFileTestManifestPath() -> std::filesystem::path { + return CARBON_FILE_TEST_MANIFEST; +} + +} // namespace Carbon::Testing diff --git a/testing/file_test/rules.bzl b/testing/file_test/rules.bzl index 5bdc721bcabef..d97f9b1072494 100644 --- a/testing/file_test/rules.bzl +++ b/testing/file_test/rules.bzl @@ -15,6 +15,7 @@ load("//bazel/manifest:defs.bzl", "manifest") def file_test( name, tests, + srcs = [], data = [], args = [], prebuilt_binary = None, @@ -28,6 +29,7 @@ def file_test( Args: name: The base name of the tests. tests: The list of test files to use as data, typically a glob. + srcs: Passed to cc_test. data: Passed to cc_test. args: Passed to cc_test. prebuilt_binary: If set, specifies a prebuilt test binary to use instead @@ -42,13 +44,16 @@ def file_test( srcs = tests, testonly = 1, ) - args = ["--test_targets_file=$(rootpath :{0})".format(tests_file)] + args data = [":" + tests_file] + tests + data if prebuilt_binary: + # TODO: The prebuilt_binary support is only used by explorer. We should + # remove this once explorer is removed, and think about better factoring + # approaches if we need it later for toolchain. + args = ["--explorer_test_targets_file=$(rootpath :{0})".format(tests_file)] + args native.sh_test( name = name, - srcs = [prebuilt_binary], + srcs = srcs + [prebuilt_binary], data = data, args = args, env = cc_env(), @@ -57,8 +62,10 @@ def file_test( else: cc_test( name = name, + srcs = srcs + ["//testing/file_test:file_test_manifest.cpp"], data = data, args = args, env = cc_env(), + local_defines = ["CARBON_FILE_TEST_MANIFEST='\"$(rootpath :{0})\"'".format(tests_file)], **kwargs ) From c4c3381b184105daf41a7126f5e47bd533b68ca0 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 26 Feb 2025 16:21:01 -0800 Subject: [PATCH 31/56] Add `TypeId::is_symbolic` and `is_concrete`. (#5024) These just forward to the corresponding members of `TypeId`. --- toolchain/check/deduce.cpp | 5 ++--- toolchain/check/facet_type.cpp | 2 +- toolchain/check/handle_where.cpp | 2 +- toolchain/check/type_completion.cpp | 2 +- toolchain/sem_ir/ids.h | 5 +++++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index e2cca8db8d5fa..8036a7b71138b 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -323,7 +323,7 @@ auto DeductionContext::Deduce() -> bool { auto param_type_id = context().insts().Get(param_id).type_id(); // If the parameter has a symbolic type, deduce against that. - if (param_type_id.AsConstantId().is_symbolic()) { + if (param_type_id.is_symbolic()) { Add(context().types().GetInstId(param_type_id), context().types().GetInstId(context().insts().Get(arg_id).type_id()), needs_substitution); @@ -567,8 +567,7 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool { // that incorrectly. auto arg_type_id = context().insts().Get(deduced_arg_id).type_id(); auto binding_type_id = context().insts().Get(binding_id).type_id(); - if (!arg_type_id.AsConstantId().is_symbolic() && - binding_type_id.AsConstantId().is_symbolic()) { + if (arg_type_id.is_concrete() && binding_type_id.is_symbolic()) { auto param_type_const_id = SubstConstant( context(), binding_type_id.AsConstantId(), substitutions_); CARBON_CHECK(param_type_const_id.has_value()); diff --git a/toolchain/check/facet_type.cpp b/toolchain/check/facet_type.cpp index d50d58bac602c..df1ad02488c58 100644 --- a/toolchain/check/facet_type.cpp +++ b/toolchain/check/facet_type.cpp @@ -134,7 +134,7 @@ auto ResolveFacetTypeImplWitness( // If the associated constant has a symbolic type, convert the rewrite // value to that type now we know the value of `Self`. SemIR::TypeId assoc_const_type_id = decl->type_id; - if (context.types().GetConstantId(assoc_const_type_id).is_symbolic()) { + if (assoc_const_type_id.is_symbolic()) { // Get the type of the associated constant in this interface with this // value for `Self`. assoc_const_type_id = GetTypeForSpecificAssociatedEntity( diff --git a/toolchain/check/handle_where.cpp b/toolchain/check/handle_where.cpp index ed07db95e2645..ae3331c0e1edf 100644 --- a/toolchain/check/handle_where.cpp +++ b/toolchain/check/handle_where.cpp @@ -62,7 +62,7 @@ auto HandleParseNode(Context& context, Parse::RequirementEqualId node_id) // Convert rhs to type of lhs. auto lhs_type_id = context.insts().Get(lhs).type_id(); - if (context.types().GetConstantId(lhs_type_id).is_symbolic()) { + if (lhs_type_id.is_symbolic()) { // If the type of the associated constant is symbolic, we defer conversion // until the constraint is resolved, in case it depends on `Self` (which // will now be a reference to `.Self`). diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 0cc7697cf76a9..77d0d6f456735 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -557,7 +557,7 @@ auto RequireCompleteType(Context& context, SemIR::TypeId type_id, // For a symbolic type, create an instruction to require the corresponding // specific type to be complete. - if (type_id.AsConstantId().is_symbolic()) { + if (type_id.is_symbolic()) { // TODO: Deduplicate these. AddInstInNoBlock( context, diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index b4e0a9b6667cf..0d0a16a4caecf 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -735,6 +735,11 @@ struct TypeId : public IdBase { // Returns the constant ID that defines the type. auto AsConstantId() const -> ConstantId { return ConstantId(index); } + // Returns whether this represents a symbolic type. Requires has_value. + auto is_symbolic() const -> bool { return AsConstantId().is_symbolic(); } + // Returns whether this represents a concrete type. Requires has_value. + auto is_concrete() const -> bool { return AsConstantId().is_concrete(); } + auto Print(llvm::raw_ostream& out) const -> void; }; From 90b6f5a22c0359852ef05d5ecf2c2618becad9dc Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 17:00:10 -0800 Subject: [PATCH 32/56] Refactor NodeCategory for X-macros (#5029) Taking an approach similar to NameId in #5018 --- toolchain/parse/BUILD | 11 ++++ toolchain/parse/node_category.cpp | 37 +++++++++++ toolchain/parse/node_category.h | 91 ++++++++++++++++++++++++++++ toolchain/parse/node_kind.cpp | 31 ---------- toolchain/parse/node_kind.h | 54 +---------------- toolchain/parse/typed_nodes_test.cpp | 2 +- 6 files changed, 141 insertions(+), 85 deletions(-) create mode 100644 toolchain/parse/node_category.cpp create mode 100644 toolchain/parse/node_category.h diff --git a/toolchain/parse/BUILD b/toolchain/parse/BUILD index 8a8cb9dcf3a66..6f6e1cd3a1006 100644 --- a/toolchain/parse/BUILD +++ b/toolchain/parse/BUILD @@ -18,6 +18,16 @@ manifest( srcs = [":testdata"], ) +cc_library( + name = "node_category", + srcs = ["node_category.cpp"], + hdrs = ["node_category.h"], + deps = [ + "//common:ostream", + "@llvm-project//llvm:Support", + ], +) + cc_library( name = "node_kind", srcs = ["node_kind.cpp"], @@ -28,6 +38,7 @@ cc_library( ], textual_hdrs = ["node_kind.def"], deps = [ + ":node_category", "//common:check", "//common:enum_base", "//common:ostream", diff --git a/toolchain/parse/node_category.cpp b/toolchain/parse/node_category.cpp new file mode 100644 index 0000000000000..ecf0c833f731f --- /dev/null +++ b/toolchain/parse/node_category.cpp @@ -0,0 +1,37 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/parse/node_category.h" + +#include "llvm/ADT/StringExtras.h" + +namespace Carbon::Parse { + +// Returns a string form of the node category for printing. +static auto NodeCategoryToString(NodeCategory::RawEnumType category) + -> llvm::StringLiteral { +#define CARBON_NODE_CATEGORY_TO_STRING(Name) \ + case NodeCategory::Name: \ + return #Name; + + switch (category) { + CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_TO_STRING) + CARBON_NODE_CATEGORY_TO_STRING(None) + } + +#undef CARBON_NODE_CATEGORY_TO_STRING +} + +auto NodeCategory::Print(llvm::raw_ostream& out) const -> void { + llvm::ListSeparator sep("|"); + auto value = value_; + do { + // The lowest set bit in the value, or 0 (`None`) if no bits are set. + auto lowest_bit = static_cast(value & -value); + out << sep << NodeCategoryToString(lowest_bit); + value &= ~lowest_bit; + } while (value); +} + +} // namespace Carbon::Parse diff --git a/toolchain/parse/node_category.h b/toolchain/parse/node_category.h new file mode 100644 index 0000000000000..fb67a4691cefd --- /dev/null +++ b/toolchain/parse/node_category.h @@ -0,0 +1,91 @@ +// 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_PARSE_NODE_CATEGORY_H_ +#define CARBON_TOOLCHAIN_PARSE_NODE_CATEGORY_H_ + +#include "common/ostream.h" +#include "llvm/ADT/BitmaskEnum.h" + +namespace Carbon::Parse { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +// An X-macro for node categories. Uses should look like: +// +// #define CARBON_NODE_CATEGORY_FOR_XYZ(Name) ... +// CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_XYZ) +// #undef CARBON_NODE_CATEGORY_FOR_XYZ +#define CARBON_NODE_CATEGORY(X) \ + X(Decl) \ + X(Expr) \ + X(ImplAs) \ + X(IntConst) \ + X(MemberExpr) \ + X(MemberName) \ + X(Modifier) \ + X(NonExprIdentifierName) \ + X(PackageName) \ + X(Pattern) \ + X(Requirement) \ + X(Statement) + +// Represents a set of keyword modifiers, using a separate bit per modifier. +class NodeCategory : public Printable { + private: + // Use an enum to get incremental bit shifts. + enum class BitShift : uint8_t { +#define CARBON_NODE_CATEGORY_FOR_BIT_SHIFT(Name) Name, + CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_BIT_SHIFT) +#undef CARBON_NODE_CATEGORY_FOR_BIT_SHIFT + + // For `LLVM_MARK_AS_BITMASK_ENUM`. + LargestValueMarker, + }; + + public: + // Provide values as an enum. This doesn't expose these as NodeCategory + // instances just due to the duplication of declarations that would cause. + // + // We expect this to grow, so are using a bigger size than needed. + // NOLINTNEXTLINE(performance-enum-size) + enum RawEnumType : uint32_t { +#define CARBON_NODE_CATEGORY_FOR_BIT_MASK(Name) \ + Name = 1 << static_cast(BitShift::Name), + CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_BIT_MASK) +#undef CARBON_NODE_CATEGORY_FOR_BIT_MASK + // If you add a new category here, also add it to the Print function. + None = 0, + + LLVM_MARK_AS_BITMASK_ENUM( + /*LargestValue=*/1 + << (static_cast(BitShift::LargestValueMarker) - 1)) + }; + + // Support implicit conversion so that the difference with the member enum is + // opaque. + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr NodeCategory(RawEnumType value) : value_(value) {} + + // Returns true if there's a non-empty set intersection. + constexpr auto HasAnyOf(NodeCategory other) const -> bool { + return value_ & other.value_; + } + + // Returns the set inverse. + constexpr auto operator~() const -> NodeCategory { return ~value_; } + + friend auto operator==(NodeCategory lhs, NodeCategory rhs) -> bool { + return lhs.value_ == rhs.value_; + } + + auto Print(llvm::raw_ostream& out) const -> void; + + private: + RawEnumType value_; +}; + +} // namespace Carbon::Parse + +#endif // CARBON_TOOLCHAIN_PARSE_NODE_CATEGORY_H_ diff --git a/toolchain/parse/node_kind.cpp b/toolchain/parse/node_kind.cpp index 9dd8e037dcd20..e60a28aef80ac 100644 --- a/toolchain/parse/node_kind.cpp +++ b/toolchain/parse/node_kind.cpp @@ -9,37 +9,6 @@ namespace Carbon::Parse { -auto NodeCategory::Print(llvm::raw_ostream& out) const -> void { - llvm::ListSeparator sep("|"); - auto value = value_; - do { - // The lowest set bit in the value, or 0 (`None`) if no bits are set. - auto lowest_bit = static_cast(value & -value); - switch (lowest_bit) { -#define CARBON_NODE_CATEGORY(Name) \ - case NodeCategory::Name: { \ - out << sep << #Name; \ - break; \ - } - CARBON_NODE_CATEGORY(Decl); - CARBON_NODE_CATEGORY(Expr); - CARBON_NODE_CATEGORY(ImplAs); - CARBON_NODE_CATEGORY(MemberExpr); - CARBON_NODE_CATEGORY(MemberName); - CARBON_NODE_CATEGORY(Modifier); - CARBON_NODE_CATEGORY(Pattern); - CARBON_NODE_CATEGORY(Statement); - CARBON_NODE_CATEGORY(IntConst); - CARBON_NODE_CATEGORY(Requirement); - CARBON_NODE_CATEGORY(NonExprIdentifierName); - CARBON_NODE_CATEGORY(PackageName); - CARBON_NODE_CATEGORY(None); -#undef CARBON_NODE_CATEGORY - } - value &= ~lowest_bit; - } while (value); -} - CARBON_DEFINE_ENUM_CLASS_NAMES(NodeKind) = { #define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CLASS_NAME_STRING(Name) #include "toolchain/parse/node_kind.def" diff --git a/toolchain/parse/node_kind.h b/toolchain/parse/node_kind.h index 1ad2abbe056d5..cee4259f98916 100644 --- a/toolchain/parse/node_kind.h +++ b/toolchain/parse/node_kind.h @@ -9,63 +9,11 @@ #include "common/enum_base.h" #include "common/ostream.h" -#include "llvm/ADT/BitmaskEnum.h" #include "toolchain/lex/token_kind.h" +#include "toolchain/parse/node_category.h" namespace Carbon::Parse { -LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); - -// Represents a set of keyword modifiers, using a separate bit per modifier. -class NodeCategory : public Printable { - public: - // Provide values as an enum. This doesn't expose these as NodeCategory - // instances just due to the duplication of declarations that would cause. - // - // We expect this to grow, so are using a bigger size than needed. - // NOLINTNEXTLINE(performance-enum-size) - enum RawEnumType : uint32_t { - Decl = 1 << 0, - Expr = 1 << 1, - ImplAs = 1 << 2, - MemberExpr = 1 << 3, - MemberName = 1 << 4, - Modifier = 1 << 5, - Pattern = 1 << 6, - Statement = 1 << 7, - IntConst = 1 << 8, - Requirement = 1 << 9, - NonExprIdentifierName = 1 << 10, - PackageName = 1 << 11, - // If you add a new category here, also add it to the Print function. - None = 0, - - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/PackageName) - }; - - // Support implicit conversion so that the difference with the member enum is - // opaque. - // NOLINTNEXTLINE(google-explicit-constructor) - constexpr NodeCategory(RawEnumType value) : value_(value) {} - - // Returns true if there's a non-empty set intersection. - constexpr auto HasAnyOf(NodeCategory other) const -> bool { - return value_ & other.value_; - } - - // Returns the set inverse. - constexpr auto operator~() const -> NodeCategory { return ~value_; } - - friend auto operator==(NodeCategory lhs, NodeCategory rhs) -> bool { - return lhs.value_ == rhs.value_; - } - - auto Print(llvm::raw_ostream& out) const -> void; - - private: - RawEnumType value_; -}; - CARBON_DEFINE_RAW_ENUM_CLASS(NodeKind, uint8_t) { #define CARBON_PARSE_NODE_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name) #include "toolchain/parse/node_kind.def" diff --git a/toolchain/parse/typed_nodes_test.cpp b/toolchain/parse/typed_nodes_test.cpp index 06a9401b336da..daf7570401cb6 100644 --- a/toolchain/parse/typed_nodes_test.cpp +++ b/toolchain/parse/typed_nodes_test.cpp @@ -262,7 +262,7 @@ Aggregate [^:]*: success // Use Regex matching to avoid hard-coding the result of `typeinfo(T).name()`. EXPECT_THAT(err2.message(), testing::MatchesRegex( R"Trace(Aggregate [^:]*: begin -NodeIdInCategory MemberExpr\|MemberName\|IntConst: kind IdentifierNameNotBeforeParams consumed +NodeIdInCategory IntConst\|MemberExpr\|MemberName: kind IdentifierNameNotBeforeParams consumed NodeIdInCategory Expr: kind PointerMemberAccessExpr consumed Aggregate [^:]*: success )Trace")); From 0d2f364f39b408be6c7295eb068731dd34c9e3a4 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 26 Feb 2025 17:31:26 -0800 Subject: [PATCH 33/56] Split evaluation up into one function per instruction kind (#5008) Replace the large and growing `TryEvalInstInContext` function with one function per kind. While we still have special-case handling for a small number of instruction kinds, most instructions are now handled either fully automatically or use a common codepath that evaluates the instruction operands and then performs an eval-context-independent evaluation of the instruction. To support this, `InstConstantKind` is expanded to describe more fine-grained details about how each kind of instruction interacts with constant evaluation. Also, the operand kinds of instructions become slightly more fine-grained: we now distinguish between operands that describe the destination of an initializing expression (`DestInstId`) from other `InstId` operands, because `DestInstId` operands need different treatment during constant evaluation. In particular, an initializing expression can have a constant value even if its destination is non-constant or has not yet been set, because evaluation of an initializing expression doesn't include the store to the destination. Some minor test changes: - We now more consistently propagate errors into the results of constant evaluation, so more instructions that depend on errors have a constant value of ``. - Diagnostic location for invalid array types now point at the whole array type rather than the array index expression, because `EvalConstantinst` doesn't have access to the original expression. - Diagnostic for failed `RequireCompleteType` doesn't print the original type any more because `EvalConstantInst` doesn't have access to the original expression. As a follow-up, some of this -- in particular, the `EvalConstantInst` overloads -- will be moved to a separate file, in an effort to split the overall constant evaluation machinery apart from the logic to evaluate each individual kind of instruction. --- toolchain/check/eval.cpp | 1449 +++++++++-------- .../testdata/array/fail_bound_negative.carbon | 4 +- .../testdata/array/fail_bound_overflow.carbon | 4 +- .../array/fail_incomplete_element.carbon | 2 +- .../fail_out_of_bound_non_literal.carbon | 2 +- ..._facet_value_to_narrowed_facet_type.carbon | 6 +- .../value_with_type_through_access.carbon | 4 +- .../check/testdata/choice/fail_invalid.carbon | 4 +- .../testdata/class/fail_generic_method.carbon | 4 +- .../check/testdata/class/fail_init.carbon | 12 +- .../testdata/class/fail_self_param.carbon | 2 +- .../class/no_prelude/import_access.carbon | 4 +- .../class/no_prelude/name_poisoning.carbon | 4 +- .../check/testdata/deduce/int_float.carbon | 2 +- .../declaration/fail_param_in_type.carbon | 2 +- .../fail_decl_param_mismatch.carbon | 2 +- .../testdata/generic/complete_type.carbon | 4 +- .../testdata/impl/assoc_const_self.carbon | 7 +- .../testdata/impl/fail_call_invalid.carbon | 2 +- .../impl/fail_self_type_mismatch.carbon | 2 +- .../impl/fail_todo_use_assoc_const.carbon | 2 +- .../impl/no_prelude/name_poisoning.carbon | 6 +- .../index/fail_array_large_index.carbon | 4 +- .../index/fail_array_non_int_indexing.carbon | 2 +- .../fail_array_out_of_bound_access.carbon | 2 +- .../index/fail_negative_indexing.carbon | 2 +- .../fail_assoc_const_not_constant.carbon | 4 +- .../interface/no_prelude/import_access.carbon | 14 +- .../check/testdata/let/generic_import.carbon | 4 +- .../builtin/fail_assignment_to_error.carbon | 2 +- .../packages/fail_import_type_error.carbon | 8 +- .../no_prelude/core_name_poisoning.carbon | 2 +- .../testdata/pointer/fail_deref_error.carbon | 4 +- .../pointer/fail_deref_function.carbon | 4 +- .../pointer/fail_deref_namespace.carbon | 4 +- .../pointer/fail_deref_not_pointer.carbon | 12 +- .../testdata/pointer/fail_deref_type.carbon | 4 +- .../no_prelude/fail_nested_incomplete.carbon | 2 +- .../tuple/fail_nested_incomplete.carbon | 2 +- .../testdata/where_expr/designator.carbon | 2 +- .../testdata/where_expr/equal_rewrite.carbon | 2 +- .../testdata/where_expr/fail_not_facet.carbon | 4 +- toolchain/lower/constant.cpp | 2 + toolchain/lower/function_context.cpp | 4 +- toolchain/sem_ir/formatter.cpp | 4 + toolchain/sem_ir/id_kind.h | 2 +- toolchain/sem_ir/ids.h | 28 +- toolchain/sem_ir/inst.h | 3 +- toolchain/sem_ir/inst_kind.h | 64 +- toolchain/sem_ir/typed_insts.h | 230 +-- 50 files changed, 1036 insertions(+), 915 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 5747dcbb9e7f0..29ac9e51c8fc9 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -16,6 +16,7 @@ #include "toolchain/sem_ir/builtin_function_kind.h" #include "toolchain/sem_ir/function.h" #include "toolchain/sem_ir/generic.h" +#include "toolchain/sem_ir/id_kind.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst_kind.h" #include "toolchain/sem_ir/typed_insts.h" @@ -223,15 +224,20 @@ enum class Phase : uint8_t { }; } // namespace +// Returns whether the specified phase is a constant phase. +static auto IsConstant(Phase phase) -> bool { + return phase < Phase::UnknownDueToError; +} + // Gets the phase in which the value of a constant will become available. -static auto GetPhase(EvalContext& eval_context, SemIR::ConstantId constant_id) - -> Phase { +static auto GetPhase(const SemIR::ConstantValueStore& constant_values, + SemIR::ConstantId constant_id) -> Phase { if (!constant_id.is_constant()) { return Phase::Runtime; } else if (constant_id == SemIR::ErrorInst::SingletonConstantId) { return Phase::UnknownDueToError; } - switch (eval_context.constant_values().GetDependence(constant_id)) { + switch (constant_values.GetDependence(constant_id)) { case SemIR::ConstantDependence::None: return Phase::Concrete; case SemIR::ConstantDependence::PeriodSelf: @@ -256,7 +262,7 @@ static auto LatestPhase(Phase a, Phase b) -> Phase { static auto UpdatePhaseIgnorePeriodSelf(EvalContext& eval_context, SemIR::ConstantId constant_id, Phase* phase) { - Phase constant_phase = GetPhase(eval_context, constant_id); + Phase constant_phase = GetPhase(eval_context.constant_values(), constant_id); // Since LatestPhase(x, Phase::Concrete) == x, this is equivalent to replacing // Phase::PeriodSelfSymbolic with Phase::Concrete. if (constant_phase != Phase::PeriodSelfSymbolic) { @@ -333,16 +339,26 @@ static auto MakeFloatResult(Context& context, SemIR::TypeId type_id, static auto GetConstantValue(EvalContext& eval_context, SemIR::InstId inst_id, Phase* phase) -> SemIR::InstId { auto const_id = eval_context.GetConstantValue(inst_id); - *phase = LatestPhase(*phase, GetPhase(eval_context, const_id)); + *phase = + LatestPhase(*phase, GetPhase(eval_context.constant_values(), const_id)); return eval_context.constant_values().GetInstId(const_id); } +// Explicitly discard a `DestInstId`, because we should not be using the +// destination as part of evaluation. +static auto GetConstantValue(EvalContext& /*eval_context*/, + SemIR::DestInstId /*inst_id*/, Phase* /*phase*/) + -> SemIR::DestInstId { + return SemIR::InstId::None; +} + // Given a type which may refer to a generic parameter, returns the // corresponding type in the evaluation context. static auto GetConstantValue(EvalContext& eval_context, SemIR::TypeId type_id, Phase* phase) -> SemIR::TypeId { auto const_id = eval_context.GetConstantValue(type_id); - *phase = LatestPhase(*phase, GetPhase(eval_context, const_id)); + *phase = + LatestPhase(*phase, GetPhase(eval_context.constant_values(), const_id)); return eval_context.context().types().GetTypeIdForTypeConstantId(const_id); } @@ -505,6 +521,16 @@ static auto GetConstantFacetTypeInfo(EvalContext& eval_context, return info; } +static auto GetConstantValue(EvalContext& eval_context, + SemIR::FacetTypeId facet_type_id, Phase* phase) + -> SemIR::FacetTypeId { + SemIR::FacetTypeInfo info = + GetConstantFacetTypeInfo(eval_context, facet_type_id, phase); + info.Canonicalize(); + // TODO: Return `facet_type_id` if we can detect nothing has changed. + return eval_context.facet_types().Add(info); +} + // Replaces the specified field of the given typed instruction with its constant // value, if it has constant phase. Returns true on success, false if the value // has runtime phase. @@ -520,112 +546,81 @@ static auto ReplaceFieldWithConstantValue(EvalContext& eval_context, return true; } -// If the specified fields of the given typed instruction have constant values, -// replaces the fields with their constant values and builds a corresponding -// constant value. Otherwise returns `ConstantId::NotConstant`. Returns -// `ErrorInst::SingletonConstantId` if any subexpression is an error. -// -// The constant value is then checked by calling `validate_fn(typed_inst)`, -// which should return a `bool` indicating whether the new constant is valid. If -// validation passes, `transform_fn(typed_inst)` is called to produce the final -// constant instruction, and a corresponding ConstantId for the new constant is -// returned. If validation fails, it should produce a suitable error message. -// `ErrorInst::SingletonConstantId` is returned. -template -static auto RebuildIfFieldsAreConstantImpl( - EvalContext& eval_context, SemIR::Inst inst, ValidateFn validate_fn, - TransformFn transform_fn, EachFieldIdT InstT::*... each_field_id) - -> SemIR::ConstantId { - // Build a constant instruction by replacing each non-constant operand with - // its constant value. - auto typed_inst = inst.As(); - Phase phase = Phase::Concrete; - if ((ReplaceFieldWithConstantValue(eval_context, &typed_inst, each_field_id, - &phase) && - ...)) { - if (phase == Phase::UnknownDueToError || !validate_fn(typed_inst)) { - return SemIR::ErrorInst::SingletonConstantId; - } - return MakeConstantResult(eval_context.context(), transform_fn(typed_inst), - phase); - } - return MakeNonConstantResult(phase); -} - -// Same as above but with an identity transform function. -template -static auto RebuildAndValidateIfFieldsAreConstant( - EvalContext& eval_context, SemIR::Inst inst, ValidateFn validate_fn, - EachFieldIdT InstT::*... each_field_id) -> SemIR::ConstantId { - return RebuildIfFieldsAreConstantImpl(eval_context, inst, validate_fn, - std::identity{}, each_field_id...); -} +// Function template that can be called with an argument of type `T`. Used below +// to detect which overloads of `GetConstantValue` exist. +template +static void Accept(T /*arg*/) {} + +// Determines whether a `GetConstantValue` overload exists for a given ID type. +// Note that we do not check whether `GetConstantValue` is *callable* with a +// given ID type, because that would use the `InstId` overload for +// `AbsoluteInstId` and similar wrapper types, which should be left alone. +template +static constexpr bool HasGetConstantValueOverload = requires { + AcceptIdT>(GetConstantValue); +}; -// Same as above but with no validation step. -template -static auto TransformIfFieldsAreConstant(EvalContext& eval_context, - SemIR::Inst inst, - TransformFn transform_fn, - EachFieldIdT InstT::*... each_field_id) - -> SemIR::ConstantId { - return RebuildIfFieldsAreConstantImpl( - eval_context, inst, [](...) { return true; }, transform_fn, - each_field_id...); +// Given the stored value `arg` of an instruction field and its corresponding +// kind `kind`, returns the constant value to use for that field, if it has a +// constant phase. `*phase` is updated to include the new constant value. If +// the resulting phase is not constant, the returned value is not useful and +// will typically be `NoneIndex`. +template +static auto GetConstantValueForArg(EvalContext& eval_context, + SemIR::TypeEnum kind, int32_t arg, + Phase* phase) -> int32_t { + using Handler = auto(EvalContext&, int32_t arg, Phase * phase)->int32_t; + static constexpr Handler* Handlers[] = { + [](EvalContext& eval_context, int32_t arg, Phase* phase) -> int32_t { + auto id = SemIR::Inst::FromRaw(arg); + if constexpr (HasGetConstantValueOverload) { + // If we have a custom `GetConstantValue` overload, call it. + return SemIR::Inst::ToRaw(GetConstantValue(eval_context, id, phase)); + } else { + // Otherwise, we assume the value is already constant. + return arg; + } + }..., + [](EvalContext&, int32_t, Phase*) -> int32_t { + // Handler for IdKind::Invalid is next. + CARBON_FATAL("Instruction has argument with invalid IdKind"); + }, + [](EvalContext&, int32_t arg, Phase*) -> int32_t { + // Handler for IdKind::None is last. + return arg; + }}; + return Handlers[kind.ToIndex()](eval_context, arg, phase); } -// Same as above but with no validation or transform step. -template -static auto RebuildIfFieldsAreConstant(EvalContext& eval_context, - SemIR::Inst inst, - EachFieldIdT InstT::*... each_field_id) - -> SemIR::ConstantId { - return RebuildIfFieldsAreConstantImpl( - eval_context, inst, [](...) { return true; }, std::identity{}, - each_field_id...); -} +// Given an instruction, replaces its type and operands with their constant +// values from the specified evaluation context. `*phase` is updated to describe +// the constant phase of the result. Returns whether `*phase` is a constant +// phase; if not, `inst` may not be fully updated and should not be used. +static auto ReplaceAllFieldsWithConstantValues(EvalContext& eval_context, + SemIR::Inst* inst, Phase* phase) + -> bool { + auto type_id = SemIR::TypeId( + GetConstantValueForArg(eval_context, SemIR::IdKind::For, + inst->type_id().index, phase)); + inst->SetType(type_id); + if (!IsConstant(*phase)) { + return false; + } -// Rebuilds the given aggregate initialization instruction as a corresponding -// constant aggregate value, if its elements are all constants. -static auto RebuildInitAsValue(EvalContext& eval_context, SemIR::Inst inst, - SemIR::InstKind value_kind) - -> SemIR::ConstantId { - return TransformIfFieldsAreConstant( - eval_context, inst, - [&](SemIR::AnyAggregateInit result) { - return SemIR::AnyAggregateValue{.kind = value_kind, - .type_id = result.type_id, - .elements_id = result.elements_id}; - }, - &SemIR::AnyAggregateInit::type_id, &SemIR::AnyAggregateInit::elements_id); -} + auto kinds = inst->ArgKinds(); + auto arg0 = + GetConstantValueForArg(eval_context, kinds.first, inst->arg0(), phase); + if (!IsConstant(*phase)) { + return false; + } -// Performs an access into an aggregate, retrieving the specified element. -static auto PerformAggregateAccess(EvalContext& eval_context, SemIR::Inst inst) - -> SemIR::ConstantId { - auto access_inst = inst.As(); - Phase phase = Phase::Concrete; - if (ReplaceFieldWithConstantValue(eval_context, &access_inst, - &SemIR::AnyAggregateAccess::aggregate_id, - &phase)) { - if (auto aggregate = - eval_context.insts().TryGetAs( - access_inst.aggregate_id)) { - auto elements = eval_context.inst_blocks().Get(aggregate->elements_id); - auto index = static_cast(access_inst.index.index); - CARBON_CHECK(index < elements.size(), "Access out of bounds."); - // `Phase` is not used here. If this element is a concrete constant, then - // so is the result of indexing, even if the aggregate also contains a - // symbolic context. - return eval_context.GetConstantValue(elements[index]); - } else { - CARBON_CHECK(phase != Phase::Concrete, - "Failed to evaluate template constant {0} arg0: {1}", inst, - eval_context.insts().Get(access_inst.aggregate_id)); - } - return MakeConstantResult(eval_context.context(), access_inst, phase); + auto arg1 = + GetConstantValueForArg(eval_context, kinds.second, inst->arg1(), phase); + if (!IsConstant(*phase)) { + return false; } - return MakeNonConstantResult(phase); + inst->SetArgs(arg0, arg1); + return true; } // Performs an index into a homogeneous aggregate, retrieving the specified @@ -1549,641 +1544,675 @@ static auto MakeFacetTypeResult(Context& context, phase); } -// Implementation for `TryEvalInst`, wrapping `Context` with `EvalContext`. +// The result of constant evaluation of an instruction. +class ConstantEvalResult { + public: + // Produce a new constant as the result of an evaluation. The phase of the + // produced constant must be the same as the greatest phase of the operands in + // the evaluation. This will typically be the case if the evaluation uses all + // of its operands. + static auto New(SemIR::Inst inst) -> ConstantEvalResult { + return ConstantEvalResult(inst); + } + + // Produce an existing constant as the result of an evaluation. + static constexpr auto Existing(SemIR::ConstantId existing_id) + -> ConstantEvalResult { + CARBON_CHECK(existing_id.is_constant()); + return ConstantEvalResult(existing_id); + } + + // Indicates that an error was produced by evaluation. + static const ConstantEvalResult Error; + + // Indicates that we encountered an instruction whose evaluation is + // non-constant despite having constant operands. This should be rare; + // usually we want to produce an error in this case. + static const ConstantEvalResult NotConstant; + + // Indicates that we encountered an instruction for which we've not + // implemented constant evaluation yet. Instruction is treated as not + // constant. + static const ConstantEvalResult TODO; + + // Returns whether the result of evaluation is that we should produce a new + // constant described by `new_inst()` rather than an existing `ConstantId` + // described by `existing()`. + auto is_new() const -> bool { return !result_id_.has_value(); } + + // Returns the existing constant that this the instruction evaluates to, or + // `None` if this is evaluation produces a new constant. + auto existing() const -> SemIR::ConstantId { return result_id_; } + + // Returns the new constant instruction that is the result of evaluation. + auto new_inst() const -> SemIR::Inst { + CARBON_CHECK(is_new()); + return new_inst_; + } + + private: + constexpr explicit ConstantEvalResult(SemIR::ConstantId raw_id) + : result_id_(raw_id) {} + + explicit ConstantEvalResult(SemIR::Inst inst) + : result_id_(SemIR::ConstantId::None), new_inst_(inst) {} + + SemIR::ConstantId result_id_; + union { + SemIR::Inst new_inst_; + }; +}; + +constexpr ConstantEvalResult ConstantEvalResult::Error = + Existing(SemIR::ErrorInst::SingletonConstantId); + +constexpr ConstantEvalResult ConstantEvalResult::NotConstant = + ConstantEvalResult(SemIR::ConstantId::NotConstant); + +constexpr ConstantEvalResult ConstantEvalResult::TODO = NotConstant; + +// `EvalConstantInst` evaluates an instruction whose operands are all constant, +// in a context unrelated to the enclosing evaluation. The function is given the +// instruction after its operands, including its type, are replaced by their +// evaluated value, and returns a `ConstantEvalResult` describing the result of +// evaluating the instruction. // -// Tail call should not be diagnosed as recursion. -// https://github.com/llvm/llvm-project/issues/125724 -// NOLINTNEXTLINE(misc-no-recursion): Tail call. -static auto TryEvalInstInContext(EvalContext& eval_context, - SemIR::InstId inst_id, SemIR::Inst inst) - -> SemIR::ConstantId { - // TODO: Ensure we have test coverage for each of these cases that can result - // in a constant, once those situations are all reachable. - CARBON_KIND_SWITCH(inst) { - // These cases are constants if their operands are. - case SemIR::AddrOf::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::AddrOf::type_id, - &SemIR::AddrOf::lvalue_id); - case CARBON_KIND(SemIR::ArrayType array_type): { - return RebuildAndValidateIfFieldsAreConstant( - eval_context, inst, - [&](SemIR::ArrayType result) { - auto bound_id = array_type.bound_id; - auto bound_inst = eval_context.insts().Get(result.bound_id); - auto int_bound = bound_inst.TryAs(); - if (!int_bound) { - CARBON_CHECK(eval_context.constant_values() - .Get(result.bound_id) - .is_symbolic(), - "Unexpected inst {0} for template constant int", - bound_inst); - return true; - } - // TODO: We should check that the size of the resulting array type - // fits in 64 bits, not just that the bound does. Should we use a - // 32-bit limit for 32-bit targets? - const auto& bound_val = eval_context.ints().Get(int_bound->int_id); - if (eval_context.types().IsSignedInt(int_bound->type_id) && - bound_val.isNegative()) { - CARBON_DIAGNOSTIC(ArrayBoundNegative, Error, - "array bound of {0} is negative", TypedInt); - eval_context.emitter().Emit( - eval_context.GetDiagnosticLoc(bound_id), ArrayBoundNegative, - {.type = int_bound->type_id, .value = bound_val}); - return false; - } - if (bound_val.getActiveBits() > 64) { - CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error, - "array bound of {0} is too large", TypedInt); - eval_context.emitter().Emit( - eval_context.GetDiagnosticLoc(bound_id), ArrayBoundTooLarge, - {.type = int_bound->type_id, .value = bound_val}); - return false; - } - return true; - }, - &SemIR::ArrayType::bound_id, &SemIR::ArrayType::element_type_id); - } - case SemIR::AssociatedEntity::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::AssociatedEntity::type_id); - case SemIR::AssociatedEntityType::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, &SemIR::AssociatedEntityType::interface_type_id); - case SemIR::BoundMethod::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::BoundMethod::type_id, - &SemIR::BoundMethod::object_id, - &SemIR::BoundMethod::function_decl_id); - case SemIR::ClassType::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::ClassType::specific_id); - case SemIR::CompleteTypeWitness::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, &SemIR::CompleteTypeWitness::object_repr_id); - case SemIR::FacetValue::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::FacetValue::type_id, - &SemIR::FacetValue::type_inst_id, - &SemIR::FacetValue::witness_inst_id); - case SemIR::FunctionType::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::FunctionType::specific_id); - case SemIR::FunctionTypeWithSelfType::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, - &SemIR::FunctionTypeWithSelfType::interface_function_type_id, - &SemIR::FunctionTypeWithSelfType::self_id); - case SemIR::GenericClassType::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, &SemIR::GenericClassType::enclosing_specific_id); - case SemIR::GenericInterfaceType::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, - &SemIR::GenericInterfaceType::enclosing_specific_id); - case SemIR::ImplWitness::Kind: - // We intentionally don't replace the `elements_id` field here. We want to - // track that specific InstBlock in particular, not coalesce blocks with - // the same members. That block may get updated, and we want to pick up - // those changes. - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::ImplWitness::specific_id); - case CARBON_KIND(SemIR::IntType int_type): { - return RebuildAndValidateIfFieldsAreConstant( - eval_context, inst, - [&](SemIR::IntType result) { - return ValidateIntType( - eval_context.context(), - eval_context.GetDiagnosticLoc({inst_id, int_type.bit_width_id}), - result); - }, - &SemIR::IntType::bit_width_id); - } - case SemIR::PointerType::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::PointerType::pointee_id); - case CARBON_KIND(SemIR::FloatType float_type): { - return RebuildAndValidateIfFieldsAreConstant( - eval_context, inst, - [&](SemIR::FloatType result) { - return ValidateFloatType(eval_context.context(), - eval_context.GetDiagnosticLoc( - {inst_id, float_type.bit_width_id}), - result); - }, - &SemIR::FloatType::bit_width_id); - } - case SemIR::SpecificFunction::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::SpecificFunction::callee_id, - &SemIR::SpecificFunction::specific_id); - case SemIR::StructType::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::StructType::fields_id); - case SemIR::StructValue::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::StructValue::type_id, - &SemIR::StructValue::elements_id); - case SemIR::TupleType::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::TupleType::elements_id); - case SemIR::TupleValue::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::TupleValue::type_id, - &SemIR::TupleValue::elements_id); - case SemIR::UnboundElementType::Kind: - return RebuildIfFieldsAreConstant( - eval_context, inst, &SemIR::UnboundElementType::class_type_id, - &SemIR::UnboundElementType::element_type_id); - - // Initializers evaluate to a value of the object representation. - case SemIR::ArrayInit::Kind: - // TODO: Add an `ArrayValue` to represent a constant array object - // representation instead of using a `TupleValue`. - return RebuildInitAsValue(eval_context, inst, SemIR::TupleValue::Kind); - case SemIR::ClassInit::Kind: - // TODO: Add a `ClassValue` to represent a constant class object - // representation instead of using a `StructValue`. - return RebuildInitAsValue(eval_context, inst, SemIR::StructValue::Kind); - case SemIR::StructInit::Kind: - return RebuildInitAsValue(eval_context, inst, SemIR::StructValue::Kind); - case SemIR::TupleInit::Kind: - return RebuildInitAsValue(eval_context, inst, SemIR::TupleValue::Kind); - - case SemIR::Vtable::Kind: - return RebuildIfFieldsAreConstant(eval_context, inst, - &SemIR::Vtable::virtual_functions_id); - case SemIR::AutoType::Kind: - case SemIR::BoolType::Kind: - case SemIR::BoundMethodType::Kind: - case SemIR::ErrorInst::Kind: - case SemIR::IntLiteralType::Kind: - case SemIR::LegacyFloatType::Kind: - case SemIR::NamespaceType::Kind: - case SemIR::SpecificFunctionType::Kind: - case SemIR::StringType::Kind: - case SemIR::TypeType::Kind: - case SemIR::VtableType::Kind: - case SemIR::WitnessType::Kind: - // Builtins are always concrete constants. - return MakeConstantResult(eval_context.context(), inst, Phase::Concrete); - - case CARBON_KIND(SemIR::FunctionDecl fn_decl): { - return TransformIfFieldsAreConstant( - eval_context, fn_decl, - [&](SemIR::FunctionDecl result) { - return SemIR::StructValue{.type_id = result.type_id, - .elements_id = SemIR::InstBlockId::Empty}; - }, - &SemIR::FunctionDecl::type_id); - } +// An overload is provided for each type whose constant kind is one of the +// following: +// +// - InstConstantKind::Indirect +// - InstConstantKind::SymbolicOnly +// - InstConstantKind::Conditional +// +// ... except for cases where the result of evaluation depends on the evaluation +// context itself. Those cases are handled by explicit specialization of +// `TryEvalTypedInst`. + +static auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::ArrayType inst) -> ConstantEvalResult { + auto bound_inst = context.insts().Get(inst.bound_id); + auto int_bound = bound_inst.TryAs(); + if (!int_bound) { + CARBON_CHECK(context.constant_values().Get(inst.bound_id).is_symbolic(), + "Unexpected inst {0} for template constant int", bound_inst); + return ConstantEvalResult::New(inst); + } + // TODO: We should check that the size of the resulting array type + // fits in 64 bits, not just that the bound does. Should we use a + // 32-bit limit for 32-bit targets? + const auto& bound_val = context.ints().Get(int_bound->int_id); + if (context.types().IsSignedInt(int_bound->type_id) && + bound_val.isNegative()) { + CARBON_DIAGNOSTIC(ArrayBoundNegative, Error, + "array bound of {0} is negative", TypedInt); + context.emitter().Emit(loc, ArrayBoundNegative, + {.type = int_bound->type_id, .value = bound_val}); + return ConstantEvalResult::Error; + } + if (bound_val.getActiveBits() > 64) { + CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error, + "array bound of {0} is too large", TypedInt); + context.emitter().Emit(loc, ArrayBoundTooLarge, + {.type = int_bound->type_id, .value = bound_val}); + return ConstantEvalResult::Error; + } + return ConstantEvalResult::New(inst); +} - case CARBON_KIND(SemIR::ClassDecl class_decl): { - // If the class has generic parameters, we don't produce a class type, but - // a callable whose return value is a class type. - if (eval_context.classes().Get(class_decl.class_id).has_parameters()) { - return TransformIfFieldsAreConstant( - eval_context, class_decl, - [&](SemIR::ClassDecl result) { - return SemIR::StructValue{ - .type_id = result.type_id, - .elements_id = SemIR::InstBlockId::Empty}; - }, - &SemIR::ClassDecl::type_id); - } - // A non-generic class declaration evaluates to the class type. - return MakeConstantResult( - eval_context.context(), - SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, - .class_id = class_decl.class_id, - .specific_id = SemIR::SpecificId::None}, - Phase::Concrete); - } +static auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::IntType inst) -> ConstantEvalResult { + return ValidateIntType(context, loc, inst) ? ConstantEvalResult::New(inst) + : ConstantEvalResult::Error; +} - case CARBON_KIND(SemIR::FacetType facet_type): { - Phase phase = Phase::Concrete; - SemIR::FacetTypeInfo info = GetConstantFacetTypeInfo( - eval_context, facet_type.facet_type_id, &phase); - info.Canonicalize(); - // TODO: Reuse `inst` if we can detect that nothing has changed. - return MakeFacetTypeResult(eval_context.context(), info, phase); - } +static auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::FloatType inst) -> ConstantEvalResult { + return ValidateFloatType(context, loc, inst) ? ConstantEvalResult::New(inst) + : ConstantEvalResult::Error; +} - case CARBON_KIND(SemIR::InterfaceDecl interface_decl): { - // If the interface has generic parameters, we don't produce an interface - // type, but a callable whose return value is an interface type. - if (eval_context.interfaces() - .Get(interface_decl.interface_id) - .has_parameters()) { - return TransformIfFieldsAreConstant( - eval_context, interface_decl, - [&](SemIR::InterfaceDecl result) { - return SemIR::StructValue{ - .type_id = result.type_id, - .elements_id = SemIR::InstBlockId::Empty}; - }, - &SemIR::InterfaceDecl::type_id); - } - // A non-generic interface declaration evaluates to a facet type. - return MakeConstantResult( - eval_context.context(), - FacetTypeFromInterface(eval_context.context(), - interface_decl.interface_id, - SemIR::SpecificId::None), - Phase::Concrete); - } +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ArrayInit init) -> ConstantEvalResult { + // TODO: Add an `ArrayValue` to represent a constant array object + // representation instead of using a `TupleValue`. + return ConstantEvalResult::New( + SemIR::TupleValue{.type_id = init.type_id, .elements_id = init.inits_id}); +} - case CARBON_KIND(SemIR::SpecificConstant specific): { - // Pull the constant value out of the specific. - return SemIR::GetConstantValueInSpecific( - eval_context.sem_ir(), specific.specific_id, specific.inst_id); - } +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ClassInit init) -> ConstantEvalResult { + // TODO: Add a `ClassValue` to represent a constant class object + // representation instead of using a `StructValue`. + return ConstantEvalResult::New(SemIR::StructValue{ + .type_id = init.type_id, .elements_id = init.elements_id}); +} - // These cases are treated as being the unique canonical definition of the - // corresponding constant value. - // TODO: This doesn't properly handle redeclarations. Consider adding a - // corresponding `Value` inst for each of these cases, or returning the - // first declaration. - case SemIR::AdaptDecl::Kind: - case SemIR::AssociatedConstantDecl::Kind: - case SemIR::BaseDecl::Kind: - case SemIR::FieldDecl::Kind: - case SemIR::ImplDecl::Kind: - case SemIR::Namespace::Kind: - return SemIR::ConstantId::ForConcreteConstant(inst_id); - - case SemIR::BoolLiteral::Kind: - case SemIR::FloatLiteral::Kind: - case SemIR::IntValue::Kind: - case SemIR::StringLiteral::Kind: - // Promote literals to the constant block. - // TODO: Convert literals into a canonical form. Currently we can form two - // different `i32` constants with the same value if they are represented - // by `APInt`s with different bit widths. - // TODO: Can the type of an IntValue or FloatLiteral be symbolic? If so, - // we may need to rebuild. - return MakeConstantResult(eval_context.context(), inst, Phase::Concrete); - - // The elements of a constant aggregate can be accessed. - case SemIR::ClassElementAccess::Kind: - case SemIR::StructAccess::Kind: - case SemIR::TupleAccess::Kind: - return PerformAggregateAccess(eval_context, inst); - - case CARBON_KIND(SemIR::ImplWitnessAccess access_inst): { - // This is PerformAggregateAccess followed by GetConstantInSpecific. - Phase phase = Phase::Concrete; - if (ReplaceFieldWithConstantValue(eval_context, &access_inst, - &SemIR::ImplWitnessAccess::witness_id, - &phase)) { - if (auto witness = eval_context.insts().TryGetAs( - access_inst.witness_id)) { - auto elements = eval_context.inst_blocks().Get(witness->elements_id); - auto index = static_cast(access_inst.index.index); - CARBON_CHECK(index < elements.size(), "Access out of bounds."); - // `Phase` is not used here. If this element is a concrete constant, - // then so is the result of indexing, even if the aggregate also - // contains a symbolic context. - - auto element = elements[index]; - if (!element.has_value()) { - // TODO: Perhaps this should be a `{}` value with incomplete type? - CARBON_DIAGNOSTIC(ImplAccessMemberBeforeComplete, Error, - "accessing member from impl before the end of " - "its definition"); - // TODO: Add note pointing to the impl declaration. - eval_context.emitter().Emit(eval_context.GetDiagnosticLoc(inst_id), - ImplAccessMemberBeforeComplete); - return SemIR::ErrorInst::SingletonConstantId; - } - LoadImportRef(eval_context.context(), element); - return GetConstantValueInSpecific(eval_context.sem_ir(), - witness->specific_id, element); - } else { - CARBON_CHECK(phase != Phase::Concrete, - "Failed to evaluate template constant {0} arg0: {1}", - inst, eval_context.insts().Get(access_inst.witness_id)); - } - return MakeConstantResult(eval_context.context(), access_inst, phase); - } - return MakeNonConstantResult(phase); - } - case CARBON_KIND(SemIR::ArrayIndex index): { - return PerformArrayIndex(eval_context, index); - } +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::StructInit init) -> ConstantEvalResult { + return ConstantEvalResult::New(SemIR::StructValue{ + .type_id = init.type_id, .elements_id = init.elements_id}); +} - case CARBON_KIND(SemIR::Call call): { - return MakeConstantForCall(eval_context, - eval_context.GetDiagnosticLoc(inst_id), call); - } +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::TupleInit init) -> ConstantEvalResult { + return ConstantEvalResult::New(SemIR::TupleValue{ + .type_id = init.type_id, .elements_id = init.elements_id}); +} - // TODO: These need special handling. - case SemIR::BindValue::Kind: - case SemIR::Deref::Kind: - case SemIR::ImportRefLoaded::Kind: - case SemIR::ReturnSlot::Kind: - case SemIR::Temporary::Kind: - case SemIR::TemporaryStorage::Kind: - case SemIR::ValueAsRef::Kind: - case SemIR::VtablePtr::Kind: - break; +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::FunctionDecl inst) -> ConstantEvalResult { + return ConstantEvalResult::New(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); +} - case CARBON_KIND(SemIR::SymbolicBindingPattern bind): { - // TODO: Disable constant evaluation of SymbolicBindingPattern once - // DeduceGenericCallArguments no longer needs implicit params to have - // constant values. - const auto& bind_name = - eval_context.entity_names().Get(bind.entity_name_id); - - // If we know which specific we're evaluating within and this is an - // argument of that specific, its constant value is the corresponding - // argument value. - if (auto value = - eval_context.GetCompileTimeBindValue(bind_name.bind_index()); - value.has_value()) { - return value; - } +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ClassDecl inst) -> ConstantEvalResult { + // If the class has generic parameters, we don't produce a class type, but a + // callable whose return value is a class type. + if (context.classes().Get(inst.class_id).has_parameters()) { + return ConstantEvalResult::New(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); + } - // The constant form of a symbolic binding is an idealized form of the - // original, with no equivalent value. - bind.entity_name_id = - eval_context.entity_names().MakeCanonical(bind.entity_name_id); - return MakeConstantResult(eval_context.context(), bind, - bind_name.is_template ? Phase::TemplateSymbolic - : Phase::CheckedSymbolic); - } - case CARBON_KIND(SemIR::BindSymbolicName bind): { - const auto& bind_name = - eval_context.entity_names().Get(bind.entity_name_id); + // A non-generic class declaration evaluates to the class type. + return ConstantEvalResult::New( + SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = inst.class_id, + .specific_id = SemIR::SpecificId::None}); +} - Phase phase; - if (bind_name.name_id == SemIR::NameId::PeriodSelf) { - phase = Phase::PeriodSelfSymbolic; - } else { - // If we know which specific we're evaluating within and this is an - // argument of that specific, its constant value is the corresponding - // argument value. - if (auto value = - eval_context.GetCompileTimeBindValue(bind_name.bind_index()); - value.has_value()) { - return value; - } - phase = bind_name.is_template ? Phase::TemplateSymbolic - : Phase::CheckedSymbolic; - } - // The constant form of a symbolic binding is an idealized form of the - // original, with no equivalent value. - bind.entity_name_id = - eval_context.entity_names().MakeCanonical(bind.entity_name_id); - bind.value_id = SemIR::InstId::None; - if (!ReplaceFieldWithConstantValue( - eval_context, &bind, &SemIR::BindSymbolicName::type_id, &phase)) { - return MakeNonConstantResult(phase); - } - return MakeConstantResult(eval_context.context(), bind, phase); - } +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::InterfaceDecl inst) -> ConstantEvalResult { + // If the interface has generic parameters, we don't produce an interface + // type, but a callable whose return value is an interface type. + if (context.interfaces().Get(inst.interface_id).has_parameters()) { + return ConstantEvalResult::New(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); + } - // AsCompatible changes the type of the source instruction; its constant - // value, if there is one, needs to be modified to be of the same type. - case CARBON_KIND(SemIR::AsCompatible inst): { - auto value = eval_context.GetConstantValue(inst.source_id); - if (!value.is_constant()) { - return value; - } + // A non-generic interface declaration evaluates to a facet type. + return ConstantEvalResult::New(FacetTypeFromInterface( + context, inst.interface_id, SemIR::SpecificId::None)); +} - auto from_phase = Phase::Concrete; - auto value_inst_id = - GetConstantValue(eval_context, inst.source_id, &from_phase); +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::SpecificConstant inst) + -> ConstantEvalResult { + // Pull the constant value out of the specific. + return ConstantEvalResult::Existing(SemIR::GetConstantValueInSpecific( + context.sem_ir(), inst.specific_id, inst.inst_id)); +} - auto to_phase = Phase::Concrete; - auto type_id = GetConstantValue(eval_context, inst.type_id, &to_phase); +// Performs an access into an aggregate, retrieving the specified element. +static auto PerformAggregateAccess(Context& context, SemIR::Inst inst) + -> ConstantEvalResult { + auto access_inst = inst.As(); + if (auto aggregate = context.insts().TryGetAs( + access_inst.aggregate_id)) { + auto elements = context.inst_blocks().Get(aggregate->elements_id); + auto index = static_cast(access_inst.index.index); + CARBON_CHECK(index < elements.size(), "Access out of bounds."); + // `Phase` is not used here. If this element is a concrete constant, then + // so is the result of indexing, even if the aggregate also contains a + // symbolic context. + return ConstantEvalResult::Existing( + context.constant_values().Get(elements[index])); + } + + return ConstantEvalResult::New(inst); +} - auto value_inst = eval_context.insts().Get(value_inst_id); - value_inst.SetType(type_id); +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ClassElementAccess inst) + -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} - if (to_phase >= from_phase) { - // If moving from a concrete constant value to a symbolic type, the new - // constant value takes on the phase of the new type. We're adding the - // symbolic bit to the new constant value due to the presence of a - // symbolic type. - return MakeConstantResult(eval_context.context(), value_inst, to_phase); - } else { - // If moving from a symbolic constant value to a concrete type, the new - // constant value has a phase that depends on what is in the value. If - // there is anything symbolic within the value, then it's symbolic. We - // can't easily determine that here without evaluating a new constant - // value. See - // https://github.com/carbon-language/carbon-lang/pull/4881#discussion_r1939961372 - [[clang::musttail]] return TryEvalInstInContext( - eval_context, SemIR::InstId::None, value_inst); - } - } +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::StructAccess inst) -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} - // These semantic wrappers don't change the constant value. - case CARBON_KIND(SemIR::BindAlias typed_inst): { - return eval_context.GetConstantValue(typed_inst.value_id); - } - case CARBON_KIND(SemIR::ExportDecl typed_inst): { - return eval_context.GetConstantValue(typed_inst.value_id); - } - case CARBON_KIND(SemIR::NameRef typed_inst): { - return eval_context.GetConstantValue(typed_inst.value_id); - } - case CARBON_KIND(SemIR::ValueParamPattern param_pattern): { - // TODO: Treat this as a non-expression (here and in GetExprCategory) - // once generic deduction doesn't need patterns to have constant values. - return eval_context.GetConstantValue(param_pattern.subpattern_id); - } - case CARBON_KIND(SemIR::Converted typed_inst): { - return eval_context.GetConstantValue(typed_inst.result_id); - } - case CARBON_KIND(SemIR::InitializeFrom typed_inst): { - return eval_context.GetConstantValue(typed_inst.src_id); - } - case CARBON_KIND(SemIR::SpliceBlock typed_inst): { - return eval_context.GetConstantValue(typed_inst.result_id); - } - case CARBON_KIND(SemIR::ValueOfInitializer typed_inst): { - return eval_context.GetConstantValue(typed_inst.init_id); +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::TupleAccess inst) -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} + +static auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::ImplWitnessAccess inst) + -> ConstantEvalResult { + // This is PerformAggregateAccess followed by GetConstantInSpecific. + if (auto witness = + context.insts().TryGetAs(inst.witness_id)) { + auto elements = context.inst_blocks().Get(witness->elements_id); + auto index = static_cast(inst.index.index); + CARBON_CHECK(index < elements.size(), "Access out of bounds."); + auto element = elements[index]; + if (!element.has_value()) { + // TODO: Perhaps this should be a `{}` value with incomplete type? + CARBON_DIAGNOSTIC(ImplAccessMemberBeforeComplete, Error, + "accessing member from impl before the end of " + "its definition"); + // TODO: Add note pointing to the impl declaration. + context.emitter().Emit(loc, ImplAccessMemberBeforeComplete); + return ConstantEvalResult::Error; } - case CARBON_KIND(SemIR::FacetAccessType typed_inst): { - Phase phase = Phase::Concrete; - if (ReplaceFieldWithConstantValue( - eval_context, &typed_inst, - &SemIR::FacetAccessType::facet_value_inst_id, &phase)) { - if (auto facet_value = eval_context.insts().TryGetAs( - typed_inst.facet_value_inst_id)) { - return eval_context.constant_values().Get(facet_value->type_inst_id); - } - return MakeConstantResult(eval_context.context(), typed_inst, phase); - } else { - return MakeNonConstantResult(phase); - } + + LoadImportRef(context, element); + return ConstantEvalResult::Existing(GetConstantValueInSpecific( + context.sem_ir(), witness->specific_id, element)); + } + + return ConstantEvalResult::New(inst); +} + +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::BindValue /*inst*/) -> ConstantEvalResult { + // TODO: Handle this once we've decided how to represent constant values of + // reference expressions. + return ConstantEvalResult::TODO; +} + +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::Deref /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. + return ConstantEvalResult::TODO; +} + +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::Temporary /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. Can we just return the value of `init_id`? + return ConstantEvalResult::TODO; +} + +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::VtablePtr /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. + return ConstantEvalResult::TODO; +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::AsCompatible inst) -> ConstantEvalResult { + // AsCompatible changes the type of the source instruction; its constant + // value, if there is one, needs to be modified to be of the same type. + auto value_id = context.constant_values().Get(inst.source_id); + CARBON_CHECK(value_id.is_constant()); + + auto value_inst = + context.insts().Get(context.constant_values().GetInstId(value_id)); + auto phase = GetPhase(context.constant_values(), + context.types().GetConstantId(inst.type_id)); + value_inst.SetType(inst.type_id); + + // Finish computing the new phase by incorporating the phases of the + // arguments. + EvalContext eval_context(context, SemIR::InstId::None); + auto kinds = value_inst.ArgKinds(); + GetConstantValueForArg(eval_context, kinds.first, value_inst.arg0(), &phase); + GetConstantValueForArg(eval_context, kinds.second, value_inst.arg1(), &phase); + CARBON_CHECK(IsConstant(phase)); + + // We can't use `ConstantEvalResult::New` because it would use the wrong + // phase, so manually build a new constant. + return ConstantEvalResult::Existing( + MakeConstantResult(context, value_inst, phase)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::BindAlias inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ExportDecl inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::NameRef inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ValueParamPattern inst) + -> ConstantEvalResult { + // TODO: Treat this as a non-expression (here and in GetExprCategory) + // once generic deduction doesn't need patterns to have constant values. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.subpattern_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::Converted inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.result_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::InitializeFrom inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.src_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::SpliceBlock inst) -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.result_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ValueOfInitializer inst) + -> ConstantEvalResult { + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.init_id)); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::FacetAccessType inst) + -> ConstantEvalResult { + if (auto facet_value = context.insts().TryGetAs( + inst.facet_value_inst_id)) { + return ConstantEvalResult::Existing( + context.constant_values().Get(facet_value->type_inst_id)); + } + return ConstantEvalResult::New(inst); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::FacetAccessWitness inst) + -> ConstantEvalResult { + if (auto facet_value = context.insts().TryGetAs( + inst.facet_value_inst_id)) { + return ConstantEvalResult::Existing( + context.constant_values().Get(facet_value->witness_inst_id)); + } + return ConstantEvalResult::New(inst); +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::UnaryOperatorNot inst) + -> ConstantEvalResult { + // `not true` -> `false`, `not false` -> `true`. + // All other uses of unary `not` are non-constant. + auto const_id = context.constant_values().Get(inst.operand_id); + if (const_id.is_concrete()) { + auto value = context.insts().GetAs( + context.constant_values().GetInstId(const_id)); + value.value = SemIR::BoolValue::From(!value.value.ToBool()); + return ConstantEvalResult::New(value); + } + return ConstantEvalResult::NotConstant; +} + +static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ConstType inst) -> ConstantEvalResult { + // `const (const T)` evaluates to `const T`. + if (context.types().Is(inst.inner_id)) { + return ConstantEvalResult::Existing( + context.types().GetConstantId(inst.inner_id)); + } + // Otherwise, `const T` evaluates to itself. + return ConstantEvalResult::New(inst); +} + +static auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::RequireCompleteType inst) + -> ConstantEvalResult { + auto witness_type_id = + GetSingletonType(context, SemIR::WitnessType::SingletonInstId); + + // If the type is a concrete constant, require it to be complete now. + auto complete_type_id = inst.complete_type_id; + if (context.types().GetConstantId(complete_type_id).is_concrete()) { + if (!TryToCompleteType(context, complete_type_id, loc, [&] { + // TODO: It'd be nice to report the original type prior to + // evaluation here. + CARBON_DIAGNOSTIC(IncompleteTypeInMonomorphization, Error, + "type {0} is incomplete", SemIR::TypeId); + return context.emitter().Build(loc, IncompleteTypeInMonomorphization, + complete_type_id); + })) { + return ConstantEvalResult::Error; } - case CARBON_KIND(SemIR::FacetAccessWitness typed_inst): { - Phase phase = Phase::Concrete; - if (ReplaceFieldWithConstantValue( - eval_context, &typed_inst, - &SemIR::FacetAccessWitness::facet_value_inst_id, &phase)) { - if (auto facet_value = eval_context.insts().TryGetAs( - typed_inst.facet_value_inst_id)) { - return eval_context.constant_values().Get( - facet_value->witness_inst_id); - } - return MakeConstantResult(eval_context.context(), typed_inst, phase); - } else { - return MakeNonConstantResult(phase); + return ConstantEvalResult::New(SemIR::CompleteTypeWitness{ + .type_id = witness_type_id, + .object_repr_id = context.types().GetObjectRepr(complete_type_id)}); + } + + // If it's not a concrete constant, require it to be complete once it + // becomes one. + return ConstantEvalResult::New(inst); +} + +static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ImportRefUnloaded inst) + -> ConstantEvalResult { + CARBON_FATAL("ImportRefUnloaded should be loaded before TryEvalInst: {0}", + inst); +} + +// Evaluates an instruction of a known type in an evaluation context. The +// default behavior of this function depends on the constant kind of the +// instruction: +// +// - InstConstantKind::Never: returns ConstantId::NotConstant. +// - InstConstantKind::Indirect, SymbolicOnly, Conditional: evaluates all the +// operands of the instruction, and calls `EvalConstantInst` to evaluate the +// resulting constant instruction. +// - InstConstantKind::WheneverPossible, Always: evaluates all the operands of +// the instruction, and produces the resulting constant instruction as the +// result. +// - InstConstantKind::Unique: returns the `inst_id` as the resulting +// constant. +// +// Returns an error constant ID if any of the nested evaluations fail, and +// returns NotConstant if any of the nested evaluations is non-constant. +// +// This template is explicitly specialized for instructions that need special +// handling. +template +static auto TryEvalTypedInst(EvalContext& eval_context, SemIR::InstId inst_id, + SemIR::Inst inst) -> SemIR::ConstantId { + constexpr auto ConstantKind = InstT::Kind.constant_kind(); + if constexpr (ConstantKind == SemIR::InstConstantKind::Never) { + return SemIR::ConstantId::NotConstant; + } else if constexpr (ConstantKind == SemIR::InstConstantKind::Unique) { + CARBON_CHECK(inst_id.has_value()); + return SemIR::ConstantId::ForConcreteConstant(inst_id); + } else { + // Build a constant instruction by replacing each non-constant operand with + // its constant value. + Phase phase = Phase::Concrete; + if (!ReplaceAllFieldsWithConstantValues(eval_context, &inst, &phase)) { + if constexpr (ConstantKind == SemIR::InstConstantKind::Always) { + CARBON_CHECK(phase == Phase::UnknownDueToError, + "{0} should always be constant", InstT::Kind); } + return MakeNonConstantResult(phase); } - case CARBON_KIND(SemIR::WhereExpr typed_inst): { - Phase phase = Phase::Concrete; - SemIR::TypeId base_facet_type_id = - eval_context.insts().Get(typed_inst.period_self_id).type_id(); - SemIR::Inst base_facet_inst = - eval_context.GetConstantValueAsInst(base_facet_type_id); - SemIR::FacetTypeInfo info = {.other_requirements = false}; - // `where` provides that the base facet is an error, `type`, or a facet - // type. - if (auto facet_type = base_facet_inst.TryAs()) { - info = GetConstantFacetTypeInfo(eval_context, facet_type->facet_type_id, - &phase); - } else if (base_facet_type_id == SemIR::ErrorInst::SingletonTypeId) { - return SemIR::ErrorInst::SingletonConstantId; - } else { - CARBON_CHECK(base_facet_type_id == SemIR::TypeType::SingletonTypeId, - "Unexpected type_id: {0}, inst: {1}", base_facet_type_id, - base_facet_inst); - } - if (typed_inst.requirements_id.has_value()) { - auto insts = eval_context.inst_blocks().Get(typed_inst.requirements_id); - for (auto inst_id : insts) { - if (auto rewrite = - eval_context.insts().TryGetAs( - inst_id)) { - SemIR::ConstantId lhs = - eval_context.GetConstantValue(rewrite->lhs_id); - SemIR::ConstantId rhs = - eval_context.GetConstantValue(rewrite->rhs_id); - // `where` requirements using `.Self` should not be considered - // symbolic - UpdatePhaseIgnorePeriodSelf(eval_context, lhs, &phase); - UpdatePhaseIgnorePeriodSelf(eval_context, rhs, &phase); - info.rewrite_constraints.push_back( - {.lhs_const_id = lhs, .rhs_const_id = rhs}); - } else { - // TODO: Handle other requirements - info.other_requirements = true; - } - } + if constexpr (ConstantKind == SemIR::InstConstantKind::Always || + ConstantKind == SemIR::InstConstantKind::WheneverPossible) { + return MakeConstantResult(eval_context.context(), inst, phase); + } else { + ConstantEvalResult result = EvalConstantInst( + eval_context.context(), eval_context.GetDiagnosticLoc({inst_id}), + inst.As()); + if (result.is_new()) { + return MakeConstantResult(eval_context.context(), result.new_inst(), + phase); } - info.Canonicalize(); - return MakeFacetTypeResult(eval_context.context(), info, phase); + return result.existing(); } + } +} - // `not true` -> `false`, `not false` -> `true`. - // All other uses of unary `not` are non-constant. - case CARBON_KIND(SemIR::UnaryOperatorNot typed_inst): { - auto const_id = eval_context.GetConstantValue(typed_inst.operand_id); - auto phase = GetPhase(eval_context, const_id); - if (phase == Phase::Concrete) { - auto value = eval_context.insts().GetAs( - eval_context.constant_values().GetInstId(const_id)); - return MakeBoolResult(eval_context.context(), value.type_id, - !value.value.ToBool()); - } - if (phase == Phase::UnknownDueToError) { - return SemIR::ErrorInst::SingletonConstantId; - } - break; - } +// Specialize evaluation for array indexing because we want to check the index +// expression even if the array expression is non-constant. +template <> +auto TryEvalTypedInst(EvalContext& eval_context, + SemIR::InstId /*inst_id*/, + SemIR::Inst inst) + -> SemIR::ConstantId { + return PerformArrayIndex(eval_context, inst.As()); +} - // `const (const T)` evaluates to `const T`. Otherwise, `const T` evaluates - // to itself. - case CARBON_KIND(SemIR::ConstType typed_inst): { - auto phase = Phase::Concrete; - auto inner_id = - GetConstantValue(eval_context, typed_inst.inner_id, &phase); - if (eval_context.context().types().Is(inner_id)) { - return eval_context.context().types().GetConstantId(inner_id); - } - typed_inst.inner_id = inner_id; - return MakeConstantResult(eval_context.context(), typed_inst, phase); - } +// Specialize evaluation for function calls because we want to check the callee +// expression even if an argument expression is non-constant, and because we +// will eventually want to perform control flow handling here. +template <> +auto TryEvalTypedInst(EvalContext& eval_context, + SemIR::InstId inst_id, SemIR::Inst inst) + -> SemIR::ConstantId { + return MakeConstantForCall(eval_context, + eval_context.GetDiagnosticLoc(inst_id), + inst.As()); +} - case CARBON_KIND(SemIR::RequireCompleteType require_complete): { - auto phase = Phase::Concrete; - auto witness_type_id = GetSingletonType( - eval_context.context(), SemIR::WitnessType::SingletonInstId); - auto complete_type_id = GetConstantValue( - eval_context, require_complete.complete_type_id, &phase); - - // If the type is a concrete constant, require it to be complete now. - if (phase == Phase::Concrete) { - if (!TryToCompleteType( - eval_context.context(), complete_type_id, - eval_context.GetDiagnosticLoc(inst_id), [&] { - CARBON_DIAGNOSTIC(IncompleteTypeInMonomorphization, Error, - "{0} evaluates to incomplete type {1}", - SemIR::TypeId, SemIR::TypeId); - return eval_context.emitter().Build( - eval_context.GetDiagnosticLoc(inst_id), - IncompleteTypeInMonomorphization, - require_complete.complete_type_id, complete_type_id); - })) { - return SemIR::ErrorInst::SingletonConstantId; - } - return MakeConstantResult( - eval_context.context(), - SemIR::CompleteTypeWitness{ - .type_id = witness_type_id, - .object_repr_id = - eval_context.types().GetObjectRepr(complete_type_id)}, - phase); - } +// ImportRefLoaded can have a constant value, but it's owned and maintained by +// `import_ref.cpp`, not by us. +// TODO: Rearrange how `ImportRefLoaded` instructions are created so we never +// call this. +template <> +auto TryEvalTypedInst(EvalContext& /*eval_context*/, + SemIR::InstId /*inst_id*/, + SemIR::Inst /*inst*/) + -> SemIR::ConstantId { + return SemIR::ConstantId::NotConstant; +} + +// TODO: Disable constant evaluation of SymbolicBindingPattern once +// DeduceGenericCallArguments no longer needs implicit params to have constant +// values. +template <> +auto TryEvalTypedInst(EvalContext& eval_context, + SemIR::InstId /*inst_id*/, + SemIR::Inst inst) + -> SemIR::ConstantId { + auto bind = inst.As(); + + const auto& bind_name = eval_context.entity_names().Get(bind.entity_name_id); + + // If we know which specific we're evaluating within and this is an + // argument of that specific, its constant value is the corresponding + // argument value. + if (auto value = eval_context.GetCompileTimeBindValue(bind_name.bind_index()); + value.has_value()) { + return value; + } - // If it's not a concrete constant, require it to be complete once it - // becomes one. - return MakeConstantResult( - eval_context.context(), - SemIR::RequireCompleteType{.type_id = witness_type_id, - .complete_type_id = complete_type_id}, - phase); + // The constant form of a symbolic binding is an idealized form of the + // original, with no equivalent value. + bind.entity_name_id = + eval_context.entity_names().MakeCanonical(bind.entity_name_id); + return MakeConstantResult( + eval_context.context(), bind, + bind_name.is_template ? Phase::TemplateSymbolic : Phase::CheckedSymbolic); +} + +// Symbolic bindings are a special case because they can reach into the eval +// context and produce a context-specific value. +template <> +auto TryEvalTypedInst(EvalContext& eval_context, + SemIR::InstId /*inst_id*/, + SemIR::Inst inst) + -> SemIR::ConstantId { + auto bind = inst.As(); + + const auto& bind_name = eval_context.entity_names().Get(bind.entity_name_id); + + Phase phase; + if (bind_name.name_id == SemIR::NameId::PeriodSelf) { + phase = Phase::PeriodSelfSymbolic; + } else { + // If we know which specific we're evaluating within and this is an + // argument of that specific, its constant value is the corresponding + // argument value. + if (auto value = + eval_context.GetCompileTimeBindValue(bind_name.bind_index()); + value.has_value()) { + return value; } + phase = bind_name.is_template ? Phase::TemplateSymbolic + : Phase::CheckedSymbolic; + } + // The constant form of a symbolic binding is an idealized form of the + // original, with no equivalent value. + bind.entity_name_id = + eval_context.entity_names().MakeCanonical(bind.entity_name_id); + bind.value_id = SemIR::InstId::None; + if (!ReplaceFieldWithConstantValue( + eval_context, &bind, &SemIR::BindSymbolicName::type_id, &phase)) { + return MakeNonConstantResult(phase); + } + return MakeConstantResult(eval_context.context(), bind, phase); +} - // These cases are either not expressions or not constant. - case SemIR::AddrPattern::Kind: - case SemIR::Assign::Kind: - case SemIR::BindName::Kind: - case SemIR::BindingPattern::Kind: - case SemIR::BlockArg::Kind: - case SemIR::Branch::Kind: - case SemIR::BranchIf::Kind: - case SemIR::BranchWithArg::Kind: - case SemIR::ImportCppDecl::Kind: - case SemIR::ImportDecl::Kind: - case SemIR::NameBindingDecl::Kind: - case SemIR::OutParam::Kind: - case SemIR::OutParamPattern::Kind: - case SemIR::RequirementEquivalent::Kind: - case SemIR::RequirementImpls::Kind: - case SemIR::RequirementRewrite::Kind: - case SemIR::Return::Kind: - case SemIR::ReturnExpr::Kind: - case SemIR::ReturnSlotPattern::Kind: - case SemIR::StructLiteral::Kind: - case SemIR::TupleLiteral::Kind: - case SemIR::TuplePattern::Kind: - case SemIR::ValueParam::Kind: - case SemIR::VarPattern::Kind: - case SemIR::VarStorage::Kind: - break; +// TODO: Convert this to an EvalConstantInst instruction. This will require +// providing a `GetConstantValue` overload for a requirement block. +template <> +auto TryEvalTypedInst(EvalContext& eval_context, + SemIR::InstId /*inst_id*/, + SemIR::Inst inst) -> SemIR::ConstantId { + auto typed_inst = inst.As(); - case SemIR::ImportRefUnloaded::Kind: - CARBON_FATAL("ImportRefUnloaded should be loaded before TryEvalInst: {0}", - inst); + Phase phase = Phase::Concrete; + SemIR::TypeId base_facet_type_id = + eval_context.insts().Get(typed_inst.period_self_id).type_id(); + SemIR::Inst base_facet_inst = + eval_context.GetConstantValueAsInst(base_facet_type_id); + SemIR::FacetTypeInfo info = {.other_requirements = false}; + // `where` provides that the base facet is an error, `type`, or a facet + // type. + if (auto facet_type = base_facet_inst.TryAs()) { + info = GetConstantFacetTypeInfo(eval_context, facet_type->facet_type_id, + &phase); + } else if (base_facet_type_id == SemIR::ErrorInst::SingletonTypeId) { + return SemIR::ErrorInst::SingletonConstantId; + } else { + CARBON_CHECK(base_facet_type_id == SemIR::TypeType::SingletonTypeId, + "Unexpected type_id: {0}, inst: {1}", base_facet_type_id, + base_facet_inst); + } + if (typed_inst.requirements_id.has_value()) { + auto insts = eval_context.inst_blocks().Get(typed_inst.requirements_id); + for (auto inst_id : insts) { + if (auto rewrite = + eval_context.insts().TryGetAs( + inst_id)) { + SemIR::ConstantId lhs = eval_context.GetConstantValue(rewrite->lhs_id); + SemIR::ConstantId rhs = eval_context.GetConstantValue(rewrite->rhs_id); + // `where` requirements using `.Self` should not be considered + // symbolic + UpdatePhaseIgnorePeriodSelf(eval_context, lhs, &phase); + UpdatePhaseIgnorePeriodSelf(eval_context, rhs, &phase); + info.rewrite_constraints.push_back( + {.lhs_const_id = lhs, .rhs_const_id = rhs}); + } else { + // TODO: Handle other requirements + info.other_requirements = true; + } + } } - return SemIR::ConstantId::NotConstant; + info.Canonicalize(); + return MakeFacetTypeResult(eval_context.context(), info, phase); +} + +// Implementation for `TryEvalInst`, wrapping `Context` with `EvalContext`. +static auto TryEvalInstInContext(EvalContext& eval_context, + SemIR::InstId inst_id, SemIR::Inst inst) + -> SemIR::ConstantId { + using EvalInstFn = + auto(EvalContext & eval_context, SemIR::InstId inst_id, SemIR::Inst inst) + ->SemIR::ConstantId; + static constexpr EvalInstFn* EvalInstFns[] = { +#define CARBON_SEM_IR_INST_KIND(Kind) &TryEvalTypedInst, +#include "toolchain/sem_ir/inst_kind.def" + }; + [[clang::musttail]] return EvalInstFns[inst.kind().AsInt()](eval_context, + inst_id, inst); } auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst) diff --git a/toolchain/check/testdata/array/fail_bound_negative.carbon b/toolchain/check/testdata/array/fail_bound_negative.carbon index 579066cb95689..c33143622b503 100644 --- a/toolchain/check/testdata/array/fail_bound_negative.carbon +++ b/toolchain/check/testdata/array/fail_bound_negative.carbon @@ -10,9 +10,9 @@ fn Negate(n: i32) -> i32 = "int.snegate"; -// CHECK:STDERR: fail_bound_negative.carbon:[[@LINE+4]]:19: error: array bound of -1 is negative [ArrayBoundNegative] +// CHECK:STDERR: fail_bound_negative.carbon:[[@LINE+4]]:8: error: array bound of -1 is negative [ArrayBoundNegative] // CHECK:STDERR: var a: array(i32, Negate(1)); -// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: var a: array(i32, Negate(1)); diff --git a/toolchain/check/testdata/array/fail_bound_overflow.carbon b/toolchain/check/testdata/array/fail_bound_overflow.carbon index d13f939b2798c..502963fc72511 100644 --- a/toolchain/check/testdata/array/fail_bound_overflow.carbon +++ b/toolchain/check/testdata/array/fail_bound_overflow.carbon @@ -8,9 +8,9 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/array/fail_bound_overflow.carbon -// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:19: error: array bound of 39999999999999999993 is too large [ArrayBoundTooLarge] +// CHECK:STDERR: fail_bound_overflow.carbon:[[@LINE+4]]:8: error: array bound of 39999999999999999993 is too large [ArrayBoundTooLarge] // CHECK:STDERR: var a: array(i32, 39999999999999999993); -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: var a: array(i32, 39999999999999999993); diff --git a/toolchain/check/testdata/array/fail_incomplete_element.carbon b/toolchain/check/testdata/array/fail_incomplete_element.carbon index 012834259a82f..ae2a36b2cf9b0 100644 --- a/toolchain/check/testdata/array/fail_incomplete_element.carbon +++ b/toolchain/check/testdata/array/fail_incomplete_element.carbon @@ -74,7 +74,7 @@ var p: Incomplete* = &a[0]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a.ref: = name_ref a, file.%a +// CHECK:STDOUT: %a.ref: = name_ref a, file.%a [concrete = ] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] // CHECK:STDOUT: %addr: = addr_of [concrete = ] // CHECK:STDOUT: assign file.%p.var, diff --git a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon index 62331a2fe71eb..6e346d737bbd0 100644 --- a/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon +++ b/toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon @@ -135,7 +135,7 @@ var b: i32 = a[{.index = 3}.index]; // CHECK:STDOUT: %.loc16_28.2: %i32 = value_of_initializer %int.convert_checked.loc16 [concrete = constants.%int_3.822] // CHECK:STDOUT: %.loc16_28.3: %i32 = converted %.loc16_28.1, %.loc16_28.2 [concrete = constants.%int_3.822] // CHECK:STDOUT: %.loc16_34.1: ref %i32 = array_index %a.ref, %.loc16_28.3 [concrete = ] -// CHECK:STDOUT: %.loc16_34.2: %i32 = bind_value %.loc16_34.1 +// CHECK:STDOUT: %.loc16_34.2: %i32 = bind_value %.loc16_34.1 [concrete = ] // CHECK:STDOUT: assign file.%b.var, %.loc16_34.2 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_to_narrowed_facet_type.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_to_narrowed_facet_type.carbon index 86a17654876fd..35471add57d31 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_to_narrowed_facet_type.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/fail_todo_convert_facet_value_to_narrowed_facet_type.carbon @@ -184,9 +184,9 @@ fn HandleAnimal[T:! Animal & Eats](a: T) { Feed(a); } // CHECK:STDOUT: } // CHECK:STDOUT: %HandleAnimal.decl: %HandleAnimal.type = fn_decl @HandleAnimal [concrete = constants.%HandleAnimal] { // CHECK:STDOUT: %T.patt.loc15_17.1: = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_17.2 (constants.%T.patt.e01)] -// CHECK:STDOUT: %T.param_patt: = value_param_pattern %T.patt.loc15_17.1, runtime_param [symbolic = %T.patt.loc15_17.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %T.param_patt: = value_param_pattern %T.patt.loc15_17.1, runtime_param [concrete = ] // CHECK:STDOUT: %a.patt: = binding_pattern a -// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: = value_param runtime_param // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -238,7 +238,7 @@ fn HandleAnimal[T:! Animal & Eats](a: T) { Feed(a); } // CHECK:STDOUT: fn[%T.param_patt: ](%a.param_patt: ) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Feed.ref: %Feed.type = name_ref Feed, file.%Feed.decl [concrete = constants.%Feed] -// CHECK:STDOUT: %a.ref: = name_ref a, %a +// CHECK:STDOUT: %a.ref: = name_ref a, %a [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon index 98e2c218939dc..864e599315129 100644 --- a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon @@ -524,7 +524,7 @@ fn G() { // CHECK:STDOUT: %x.patt: @F.%HoldsType.loc21_31.2 (%HoldsType.f95cf2.1) = binding_pattern x // CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc21_31.2 (%HoldsType.f95cf2.1) = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: %a.patt: = binding_pattern a -// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 +// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: %Class = value_param runtime_param // CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] @@ -723,7 +723,7 @@ fn G() { // CHECK:STDOUT: %x.patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = binding_pattern x // CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: %a.patt: = binding_pattern a -// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 +// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: %array_type = value_param runtime_param // CHECK:STDOUT: %.loc12_23: type = splice_block %array_type [concrete = constants.%array_type] { diff --git a/toolchain/check/testdata/choice/fail_invalid.carbon b/toolchain/check/testdata/choice/fail_invalid.carbon index 4bc692bd3e26e..3f843eb74c349 100644 --- a/toolchain/check/testdata/choice/fail_invalid.carbon +++ b/toolchain/check/testdata/choice/fail_invalid.carbon @@ -68,8 +68,8 @@ fn F() { // CHECK:STDOUT: %.loc11_23.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %Never.ref: type = name_ref Never, file.%Never.decl [concrete = constants.%Never] // CHECK:STDOUT: %.loc11_23.2: ref %Never = temporary_storage -// CHECK:STDOUT: %.loc11_23.3: ref %Never = temporary %.loc11_23.2, -// CHECK:STDOUT: %.loc11_23.4: ref %Never = converted %.loc11_23.1, %.loc11_23.3 +// CHECK:STDOUT: %.loc11_23.3: ref %Never = temporary %.loc11_23.2, [concrete = ] +// CHECK:STDOUT: %.loc11_23.4: ref %Never = converted %.loc11_23.1, %.loc11_23.3 [concrete = ] // CHECK:STDOUT: %never: ref %Never = bind_name never, %.loc11_23.4 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/fail_generic_method.carbon b/toolchain/check/testdata/class/fail_generic_method.carbon index 76dbb80f285a6..7b42c53f53b28 100644 --- a/toolchain/check/testdata/class/fail_generic_method.carbon +++ b/toolchain/check/testdata/class/fail_generic_method.carbon @@ -78,9 +78,9 @@ fn Class(N:! i32).F[self: Self](n: T) {} // CHECK:STDOUT: } // CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [concrete = constants.%.d85] { // CHECK:STDOUT: %self.patt: = binding_pattern self -// CHECK:STDOUT: %self.param_patt: = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %self.param_patt: = value_param_pattern %self.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: %n.patt: = binding_pattern n -// CHECK:STDOUT: %n.param_patt: = value_param_pattern %n.patt, runtime_param1 +// CHECK:STDOUT: %n.param_patt: = value_param_pattern %n.patt, runtime_param1 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %N.param: %i32 = value_param runtime_param // CHECK:STDOUT: %.loc33: type = splice_block %i32 [concrete = constants.%i32] { diff --git a/toolchain/check/testdata/class/fail_init.carbon b/toolchain/check/testdata/class/fail_init.carbon index 3db86a91287ed..c9608c3df1553 100644 --- a/toolchain/check/testdata/class/fail_init.carbon +++ b/toolchain/check/testdata/class/fail_init.carbon @@ -106,8 +106,8 @@ fn F() { // CHECK:STDOUT: %.loc21_10.1: %struct_type.a = struct_literal (%int_1.loc21) // CHECK:STDOUT: %Class.ref.loc21: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] // CHECK:STDOUT: %.loc21_10.2: ref %Class = temporary_storage -// CHECK:STDOUT: %.loc21_10.3: ref %Class = temporary %.loc21_10.2, -// CHECK:STDOUT: %.loc21_12: ref %Class = converted %.loc21_10.1, %.loc21_10.3 +// CHECK:STDOUT: %.loc21_10.3: ref %Class = temporary %.loc21_10.2, [concrete = ] +// CHECK:STDOUT: %.loc21_12: ref %Class = converted %.loc21_10.1, %.loc21_10.3 [concrete = ] // CHECK:STDOUT: %int_1.loc26: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2.loc26: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] // CHECK:STDOUT: %.loc26_18.1: %struct_type.a.c = struct_literal (%int_1.loc26, %int_2.loc26) @@ -120,16 +120,16 @@ fn F() { // CHECK:STDOUT: %.loc26_18.3: ref %Class = temporary_storage // CHECK:STDOUT: %.loc26_18.4: ref %i32 = class_element_access %.loc26_18.3, element0 // CHECK:STDOUT: %.loc26_18.5: init %i32 = initialize_from %.loc26_18.2 to %.loc26_18.4 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc26_18.6: ref %Class = temporary %.loc26_18.3, -// CHECK:STDOUT: %.loc26_20: ref %Class = converted %.loc26_18.1, %.loc26_18.6 +// CHECK:STDOUT: %.loc26_18.6: ref %Class = temporary %.loc26_18.3, [concrete = ] +// CHECK:STDOUT: %.loc26_20: ref %Class = converted %.loc26_18.1, %.loc26_18.6 [concrete = ] // CHECK:STDOUT: %int_1.loc31: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2.loc31: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] // CHECK:STDOUT: %.loc31_26.1: %struct_type.a.b.c = struct_literal (%int_1.loc31, %int_2.loc31, %int_3) // CHECK:STDOUT: %Class.ref.loc31: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] // CHECK:STDOUT: %.loc31_26.2: ref %Class = temporary_storage -// CHECK:STDOUT: %.loc31_26.3: ref %Class = temporary %.loc31_26.2, -// CHECK:STDOUT: %.loc31_28: ref %Class = converted %.loc31_26.1, %.loc31_26.3 +// CHECK:STDOUT: %.loc31_26.3: ref %Class = temporary %.loc31_26.2, [concrete = ] +// CHECK:STDOUT: %.loc31_28: ref %Class = converted %.loc31_26.1, %.loc31_26.3 [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_self_param.carbon b/toolchain/check/testdata/class/fail_self_param.carbon index 8bd2fb9056a1d..deee11cda40e7 100644 --- a/toolchain/check/testdata/class/fail_self_param.carbon +++ b/toolchain/check/testdata/class/fail_self_param.carbon @@ -42,7 +42,7 @@ var v: C(0); // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { // CHECK:STDOUT: %x.patt.loc15_22.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc15_22.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc15_22.1, runtime_param [symbolic = %x.patt.loc15_22.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc15_22.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param // CHECK:STDOUT: %self.ref: = name_ref self, [concrete = ] diff --git a/toolchain/check/testdata/class/no_prelude/import_access.carbon b/toolchain/check/testdata/class/no_prelude/import_access.carbon index 0881d3b02f890..5dca8b54768a1 100644 --- a/toolchain/check/testdata/class/no_prelude/import_access.carbon +++ b/toolchain/check/testdata/class/no_prelude/import_access.carbon @@ -488,7 +488,7 @@ private class Redecl {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %c.patt: = binding_pattern c -// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 +// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %c.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc10: type = splice_block %ptr [concrete = ] { @@ -526,7 +526,7 @@ private class Redecl {} // CHECK:STDOUT: %Test.import = import Test // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %c.patt: = binding_pattern c -// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 +// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %c.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc10: type = splice_block %ptr [concrete = ] { diff --git a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon index ea59e93894b13..2a75c4fd5421e 100644 --- a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon @@ -481,7 +481,7 @@ class C { // CHECK:STDOUT: %C.decl.loc18: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} // CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { // CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param0 // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -680,7 +680,7 @@ class C { // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param0 // CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] diff --git a/toolchain/check/testdata/deduce/int_float.carbon b/toolchain/check/testdata/deduce/int_float.carbon index bc10213db7e76..53999784cb346 100644 --- a/toolchain/check/testdata/deduce/int_float.carbon +++ b/toolchain/check/testdata/deduce/int_float.carbon @@ -211,7 +211,7 @@ fn G(a: f64) -> Core.IntLiteral() { // CHECK:STDOUT: %N.patt.loc9_6.1: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc9_6.2 (constants.%N.patt)] // CHECK:STDOUT: %N.param_patt: Core.IntLiteral = value_param_pattern %N.patt.loc9_6.1, runtime_param [symbolic = %N.patt.loc9_6.2 (constants.%N.patt)] // CHECK:STDOUT: %n.patt: = binding_pattern n -// CHECK:STDOUT: %n.param_patt: = value_param_pattern %n.patt, runtime_param0 +// CHECK:STDOUT: %n.param_patt: = value_param_pattern %n.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: %return.patt: Core.IntLiteral = return_slot_pattern // CHECK:STDOUT: %return.param_patt: Core.IntLiteral = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { diff --git a/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon b/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon index 9e27d38b916ab..bb11f13e53310 100644 --- a/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon +++ b/toolchain/check/testdata/function/declaration/fail_param_in_type.carbon @@ -41,7 +41,7 @@ fn F(n: i32, a: array(i32, n)*); // CHECK:STDOUT: %n.patt: %i32 = binding_pattern n // CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0 // CHECK:STDOUT: %a.patt: = binding_pattern a -// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 +// CHECK:STDOUT: %a.param_patt: = value_param_pattern %a.patt, runtime_param1 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %n.param: %i32 = value_param runtime_param0 // CHECK:STDOUT: %.loc15_9: type = splice_block %i32.loc15_9 [concrete = constants.%i32] { diff --git a/toolchain/check/testdata/function/definition/no_prelude/fail_decl_param_mismatch.carbon b/toolchain/check/testdata/function/definition/no_prelude/fail_decl_param_mismatch.carbon index 1d0b963910fc8..547190bdae6d4 100644 --- a/toolchain/check/testdata/function/definition/no_prelude/fail_decl_param_mismatch.carbon +++ b/toolchain/check/testdata/function/definition/no_prelude/fail_decl_param_mismatch.carbon @@ -144,7 +144,7 @@ fn K() -> {} { return {}; } // CHECK:STDOUT: } // CHECK:STDOUT: %.decl.loc36: %.type.b6a92a.3 = fn_decl @.3 [concrete = constants.%.d852be.3] { // CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param0 // CHECK:STDOUT: %x: = bind_name x, %x.param diff --git a/toolchain/check/testdata/generic/complete_type.carbon b/toolchain/check/testdata/generic/complete_type.carbon index 0cd27c5437228..aedf9ec9c8d84 100644 --- a/toolchain/check/testdata/generic/complete_type.carbon +++ b/toolchain/check/testdata/generic/complete_type.carbon @@ -15,7 +15,7 @@ library "[[@TEST_NAME]]"; class B; class A(T:! type) { - // CHECK:STDERR: fail_incomplete_in_class.carbon:[[@LINE+6]]:10: error: `T` evaluates to incomplete type `B` [IncompleteTypeInMonomorphization] + // CHECK:STDERR: fail_incomplete_in_class.carbon:[[@LINE+6]]:10: error: type `B` is incomplete [IncompleteTypeInMonomorphization] // CHECK:STDERR: var v: T; // CHECK:STDERR: ^ // CHECK:STDERR: fail_incomplete_in_class.carbon:[[@LINE-6]]:1: note: class was forward declared here [ClassForwardDeclaredHere] @@ -61,7 +61,7 @@ library "[[@TEST_NAME]]"; class B; fn F(T:! type) { - // CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE+6]]:10: error: `T` evaluates to incomplete type `B` [IncompleteTypeInMonomorphization] + // CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE+6]]:10: error: type `B` is incomplete [IncompleteTypeInMonomorphization] // CHECK:STDERR: var v: T; // CHECK:STDERR: ^ // CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE-6]]:1: note: class was forward declared here [ClassForwardDeclaredHere] diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index 0a8d37ec5fcb8..d8237d03c07f5 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -62,9 +62,9 @@ impl C as I where .V = () {} library "[[@TEST_NAME]]"; interface I(N:! Core.IntLiteral()) { - // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+3]]:17: error: array bound of -1 is negative [ArrayBoundNegative] + // CHECK:STDERR: fail_monomorphization_failure.carbon:[[@LINE+3]]:11: error: array bound of -1 is negative [ArrayBoundNegative] // CHECK:STDERR: let V:! array(Self, N); - // CHECK:STDERR: ^~~~ + // CHECK:STDERR: ^~~~~~~~~~~~~~ let V:! array(Self, N); } @@ -563,7 +563,6 @@ fn CallF() { // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self [symbolic_self] // CHECK:STDOUT: %I.facet: %I.type.057 = facet_value %.Self.as_type, %.Self.as_wit [symbolic_self] -// CHECK:STDOUT: %impl.elem0: = impl_witness_access %.Self.as_wit, element0 [symbolic_self] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -614,7 +613,7 @@ fn CallF() { // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc15_24.2: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic_self = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc15_24: = impl_witness_access %.Self.as_wit, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %impl.elem0.loc15_24: = impl_witness_access %.Self.as_wit, element0 [concrete = ] // CHECK:STDOUT: %.loc15_30: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc15_18: type = where_expr %.Self [concrete = ] { // CHECK:STDOUT: requirement_rewrite %impl.elem0.loc15_24, diff --git a/toolchain/check/testdata/impl/fail_call_invalid.carbon b/toolchain/check/testdata/impl/fail_call_invalid.carbon index 8686608e0eaa0..23564caf7b646 100644 --- a/toolchain/check/testdata/impl/fail_call_invalid.carbon +++ b/toolchain/check/testdata/impl/fail_call_invalid.carbon @@ -106,7 +106,7 @@ fn InstanceCall(n: i32) { // CHECK:STDOUT: impl @impl.006: %i32 as %Simple.ref { // CHECK:STDOUT: %G.decl: %G.type.c98 = fn_decl @G.2 [concrete = constants.%G.e73] { // CHECK:STDOUT: %self.patt: = binding_pattern self -// CHECK:STDOUT: %self.param_patt: = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %self.param_patt: = value_param_pattern %self.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: = value_param runtime_param0 // CHECK:STDOUT: %Undeclared.ref: = name_ref Undeclared, [concrete = ] diff --git a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon index 43b6cd0271cfd..26c87c2ee345f 100644 --- a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon +++ b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon @@ -100,7 +100,7 @@ impl i32 as I { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %F.decl: %F.type.cf0 = fn_decl @F.1 [concrete = constants.%F.bc6] { // CHECK:STDOUT: %c.patt: = binding_pattern c -// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 +// CHECK:STDOUT: %c.param_patt: = value_param_pattern %c.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %c.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc29: type = splice_block %C [concrete = ] { diff --git a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon index cb1f72386fb8d..effa4190de375 100644 --- a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon @@ -177,7 +177,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %self.patt: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = binding_pattern self // CHECK:STDOUT: %self.param_patt: @F.1.%Self.as_type.loc19_14.1 (%Self.as_type.3df) = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %u.patt: = binding_pattern u -// CHECK:STDOUT: %u.param_patt: = value_param_pattern %u.patt, runtime_param1 +// CHECK:STDOUT: %u.param_patt: = value_param_pattern %u.patt, runtime_param1 [concrete = ] // CHECK:STDOUT: %return.patt: = return_slot_pattern // CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, runtime_param2 // CHECK:STDOUT: } { diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon index 7b234a90ad251..15e56a682d709 100644 --- a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -472,7 +472,7 @@ class N.C { // CHECK:STDOUT: } // CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { // CHECK:STDOUT: %x.patt.loc14_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -544,7 +544,7 @@ class N.C { // CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} // CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { // CHECK:STDOUT: %x.patt.loc23_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -811,7 +811,7 @@ class N.C { // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %x.patt.loc13_8.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param // CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] diff --git a/toolchain/check/testdata/index/fail_array_large_index.carbon b/toolchain/check/testdata/index/fail_array_large_index.carbon index f566be1ce638c..0c3dd9d7013b2 100644 --- a/toolchain/check/testdata/index/fail_array_large_index.carbon +++ b/toolchain/check/testdata/index/fail_array_large_index.carbon @@ -129,7 +129,7 @@ var c: i32 = a[0x7FFF_FFFF]; // CHECK:STDOUT: %.loc17_16.1: %i32 = value_of_initializer %int.convert_checked.loc17 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %.loc17_16.2: %i32 = converted %int_1, %.loc17_16.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %.loc17_17.1: ref %i32 = array_index %a.ref.loc17, %.loc17_16.2 [concrete = ] -// CHECK:STDOUT: %.loc17_17.2: %i32 = bind_value %.loc17_17.1 +// CHECK:STDOUT: %.loc17_17.2: %i32 = bind_value %.loc17_17.1 [concrete = ] // CHECK:STDOUT: assign file.%b.var, %.loc17_17.2 // CHECK:STDOUT: %a.ref.loc23: ref %array_type = name_ref a, file.%a // CHECK:STDOUT: %int_2147483647: Core.IntLiteral = int_value 2147483647 [concrete = constants.%int_2147483647.d89] @@ -142,7 +142,7 @@ var c: i32 = a[0x7FFF_FFFF]; // CHECK:STDOUT: %.loc23_16.1: %i32 = value_of_initializer %int.convert_checked.loc23 [concrete = constants.%int_2147483647.a74] // CHECK:STDOUT: %.loc23_16.2: %i32 = converted %int_2147483647, %.loc23_16.1 [concrete = constants.%int_2147483647.a74] // CHECK:STDOUT: %.loc23_27.1: ref %i32 = array_index %a.ref.loc23, %.loc23_16.2 [concrete = ] -// CHECK:STDOUT: %.loc23_27.2: %i32 = bind_value %.loc23_27.1 +// CHECK:STDOUT: %.loc23_27.2: %i32 = bind_value %.loc23_27.1 [concrete = ] // CHECK:STDOUT: assign file.%c.var, %.loc23_27.2 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon index ec1b314bd05eb..68240846b0d13 100644 --- a/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon +++ b/toolchain/check/testdata/index/fail_array_non_int_indexing.carbon @@ -103,7 +103,7 @@ var b: i32 = a[2.6]; // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc19_16: %i32 = converted %float, [concrete = ] // CHECK:STDOUT: %.loc19_19.1: ref %i32 = array_index %a.ref, [concrete = ] -// CHECK:STDOUT: %.loc19_19.2: %i32 = bind_value %.loc19_19.1 +// CHECK:STDOUT: %.loc19_19.2: %i32 = bind_value %.loc19_19.1 [concrete = ] // CHECK:STDOUT: assign file.%b.var, %.loc19_19.2 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon index c8eb8000e8fbb..bffad62875a23 100644 --- a/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon +++ b/toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon @@ -107,7 +107,7 @@ var b: i32 = a[1]; // CHECK:STDOUT: %.loc16_16.1: %i32 = value_of_initializer %int.convert_checked.loc16 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %.loc16_16.2: %i32 = converted %int_1, %.loc16_16.1 [concrete = constants.%int_1.5d2] // CHECK:STDOUT: %.loc16_17.1: ref %i32 = array_index %a.ref, %.loc16_16.2 [concrete = ] -// CHECK:STDOUT: %.loc16_17.2: %i32 = bind_value %.loc16_17.1 +// CHECK:STDOUT: %.loc16_17.2: %i32 = bind_value %.loc16_17.1 [concrete = ] // CHECK:STDOUT: assign file.%b.var, %.loc16_17.2 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/index/fail_negative_indexing.carbon b/toolchain/check/testdata/index/fail_negative_indexing.carbon index a67dcad948b66..9314c80a8c80c 100644 --- a/toolchain/check/testdata/index/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/index/fail_negative_indexing.carbon @@ -134,7 +134,7 @@ var d: i32 = c[-10]; // CHECK:STDOUT: %.loc16_16.3: %i32 = value_of_initializer %int.convert_checked.loc16 [concrete = constants.%int_-10.c17] // CHECK:STDOUT: %.loc16_16.4: %i32 = converted %int.snegate, %.loc16_16.3 [concrete = constants.%int_-10.c17] // CHECK:STDOUT: %.loc16_19.1: ref %i32 = array_index %c.ref, %.loc16_16.4 [concrete = ] -// CHECK:STDOUT: %.loc16_19.2: %i32 = bind_value %.loc16_19.1 +// CHECK:STDOUT: %.loc16_19.2: %i32 = bind_value %.loc16_19.1 [concrete = ] // CHECK:STDOUT: assign file.%d.var, %.loc16_19.2 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_constant.carbon b/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_constant.carbon index 3fabe3691503d..eee7fecfa9834 100644 --- a/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_constant.carbon +++ b/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_constant.carbon @@ -41,8 +41,8 @@ alias UseOther = I.other; // CHECK:STDOUT: } // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: %I.ref.loc24: type = name_ref I, %I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %a.ref: = name_ref a, .inst19.loc20_7 -// CHECK:STDOUT: %UseA: = bind_alias UseA, .inst19.loc20_7 +// CHECK:STDOUT: %a.ref: = name_ref a, .inst19.loc20_7 [concrete = ] +// CHECK:STDOUT: %UseA: = bind_alias UseA, .inst19.loc20_7 [concrete = ] // CHECK:STDOUT: %I.ref.loc27: type = name_ref I, %I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %other.ref: = name_ref other, [concrete = ] // CHECK:STDOUT: %UseOther: = bind_alias UseOther, [concrete = ] diff --git a/toolchain/check/testdata/interface/no_prelude/import_access.carbon b/toolchain/check/testdata/interface/no_prelude/import_access.carbon index 844acd6d6ecc7..a231e67fb9309 100644 --- a/toolchain/check/testdata/interface/no_prelude/import_access.carbon +++ b/toolchain/check/testdata/interface/no_prelude/import_access.carbon @@ -255,7 +255,7 @@ private interface Redecl {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %Def.ref: = name_ref Def, [concrete = ] @@ -290,7 +290,7 @@ private interface Redecl {} // CHECK:STDOUT: %Test.import = import Test // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -362,7 +362,7 @@ private interface Redecl {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %ForwardWithDef.ref: = name_ref ForwardWithDef, [concrete = ] @@ -397,7 +397,7 @@ private interface Redecl {} // CHECK:STDOUT: %Test.import = import Test // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %.1: = splice_block [concrete = ] { @@ -431,7 +431,7 @@ private interface Redecl {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc11: type = splice_block %ptr [concrete = ] { @@ -471,7 +471,7 @@ private interface Redecl {} // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc10: type = splice_block %ptr [concrete = ] { @@ -509,7 +509,7 @@ private interface Redecl {} // CHECK:STDOUT: %Test.import = import Test // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %i.patt: = binding_pattern i -// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 +// CHECK:STDOUT: %i.param_patt: = value_param_pattern %i.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %i.param: = value_param runtime_param0 // CHECK:STDOUT: %.loc10: type = splice_block %ptr [concrete = ] { diff --git a/toolchain/check/testdata/let/generic_import.carbon b/toolchain/check/testdata/let/generic_import.carbon index 777ece5d2dd9e..293eae70508b6 100644 --- a/toolchain/check/testdata/let/generic_import.carbon +++ b/toolchain/check/testdata/let/generic_import.carbon @@ -108,8 +108,8 @@ var b: T = *a; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a.ref: = name_ref a, file.%a -// CHECK:STDOUT: %.loc13: ref = deref +// CHECK:STDOUT: %a.ref: = name_ref a, file.%a [concrete = ] +// CHECK:STDOUT: %.loc13: ref = deref [concrete = ] // CHECK:STDOUT: assign file.%b.var, // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/builtin/fail_assignment_to_error.carbon b/toolchain/check/testdata/operators/builtin/fail_assignment_to_error.carbon index 119045502bf7d..6fd6dda0b95f3 100644 --- a/toolchain/check/testdata/operators/builtin/fail_assignment_to_error.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_assignment_to_error.carbon @@ -53,7 +53,7 @@ fn Main() { // CHECK:STDOUT: %int_42.loc16: Core.IntLiteral = int_value 42 [concrete = constants.%int_42] // CHECK:STDOUT: assign %undeclared.ref, // CHECK:STDOUT: %also_undeclared.ref: = name_ref also_undeclared, [concrete = ] -// CHECK:STDOUT: %.loc21: ref = deref +// CHECK:STDOUT: %.loc21: ref = deref [concrete = ] // CHECK:STDOUT: %int_42.loc21: Core.IntLiteral = int_value 42 [concrete = constants.%int_42] // CHECK:STDOUT: assign %.loc21, // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/packages/fail_import_type_error.carbon b/toolchain/check/testdata/packages/fail_import_type_error.carbon index 35dcd0384d53d..03badbee8f5bb 100644 --- a/toolchain/check/testdata/packages/fail_import_type_error.carbon +++ b/toolchain/check/testdata/packages/fail_import_type_error.carbon @@ -180,13 +180,13 @@ var d: i32 = d_ref; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a_ref.ref: = name_ref a_ref, imports.%Implicit.a_ref +// CHECK:STDOUT: %a_ref.ref: = name_ref a_ref, imports.%Implicit.a_ref [concrete = ] // CHECK:STDOUT: assign file.%a.var, -// CHECK:STDOUT: %b_ref.ref: = name_ref b_ref, imports.%Implicit.b_ref +// CHECK:STDOUT: %b_ref.ref: = name_ref b_ref, imports.%Implicit.b_ref [concrete = ] // CHECK:STDOUT: assign file.%b.var, -// CHECK:STDOUT: %c_ref.ref: = name_ref c_ref, imports.%Implicit.c_ref +// CHECK:STDOUT: %c_ref.ref: = name_ref c_ref, imports.%Implicit.c_ref [concrete = ] // CHECK:STDOUT: assign file.%c.var, -// CHECK:STDOUT: %d_ref.ref: = name_ref d_ref, imports.%Implicit.d_ref +// CHECK:STDOUT: %d_ref.ref: = name_ref d_ref, imports.%Implicit.d_ref [concrete = ] // CHECK:STDOUT: assign file.%d.var, // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon index 8043d2096b215..f5d455834c4a6 100644 --- a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon +++ b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon @@ -35,7 +35,7 @@ class r#Core {} // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %x.param: = value_param runtime_param0 // CHECK:STDOUT: %x: = bind_name x, %x.param diff --git a/toolchain/check/testdata/pointer/fail_deref_error.carbon b/toolchain/check/testdata/pointer/fail_deref_error.carbon index 9f7ba435971f3..14bfce43ef263 100644 --- a/toolchain/check/testdata/pointer/fail_deref_error.carbon +++ b/toolchain/check/testdata/pointer/fail_deref_error.carbon @@ -63,9 +63,9 @@ let n2: i32 = undeclared->foo; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %undeclared.ref.loc15: = name_ref undeclared, [concrete = ] -// CHECK:STDOUT: %.loc15: ref = deref +// CHECK:STDOUT: %.loc15: ref = deref [concrete = ] // CHECK:STDOUT: %undeclared.ref.loc20: = name_ref undeclared, [concrete = ] -// CHECK:STDOUT: %.loc20: ref = deref +// CHECK:STDOUT: %.loc20: ref = deref [concrete = ] // CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/pointer/fail_deref_function.carbon b/toolchain/check/testdata/pointer/fail_deref_function.carbon index fb905879cd513..fb734e44a1a54 100644 --- a/toolchain/check/testdata/pointer/fail_deref_function.carbon +++ b/toolchain/check/testdata/pointer/fail_deref_function.carbon @@ -47,9 +47,9 @@ fn A() { // CHECK:STDOUT: fn @A() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref.loc16: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] -// CHECK:STDOUT: %.loc16: ref = deref +// CHECK:STDOUT: %.loc16: ref = deref [concrete = ] // CHECK:STDOUT: %A.ref.loc21: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] -// CHECK:STDOUT: %.loc21: ref = deref +// CHECK:STDOUT: %.loc21: ref = deref [concrete = ] // CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/pointer/fail_deref_namespace.carbon b/toolchain/check/testdata/pointer/fail_deref_namespace.carbon index 84d93e3d56f76..664ab76ce6c08 100644 --- a/toolchain/check/testdata/pointer/fail_deref_namespace.carbon +++ b/toolchain/check/testdata/pointer/fail_deref_namespace.carbon @@ -51,9 +51,9 @@ fn F() { // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref.loc18: = name_ref A, file.%A [concrete = file.%A] -// CHECK:STDOUT: %.loc18: ref = deref +// CHECK:STDOUT: %.loc18: ref = deref [concrete = ] // CHECK:STDOUT: %A.ref.loc23: = name_ref A, file.%A [concrete = file.%A] -// CHECK:STDOUT: %.loc23: ref = deref +// CHECK:STDOUT: %.loc23: ref = deref [concrete = ] // CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/pointer/fail_deref_not_pointer.carbon b/toolchain/check/testdata/pointer/fail_deref_not_pointer.carbon index bdc8983eb9be0..e25edda350ace 100644 --- a/toolchain/check/testdata/pointer/fail_deref_not_pointer.carbon +++ b/toolchain/check/testdata/pointer/fail_deref_not_pointer.carbon @@ -84,27 +84,27 @@ fn Deref(n: i32) { // CHECK:STDOUT: fn @Deref(%n.param_patt: %i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %n.ref.loc16: %i32 = name_ref n, %n -// CHECK:STDOUT: %.loc16: ref = deref %n.ref.loc16 +// CHECK:STDOUT: %.loc16: ref = deref %n.ref.loc16 [concrete = ] // CHECK:STDOUT: %n.ref.loc21: %i32 = name_ref n, %n -// CHECK:STDOUT: %.loc21: ref = deref %n.ref.loc21 +// CHECK:STDOUT: %.loc21: ref = deref %n.ref.loc21 [concrete = ] // CHECK:STDOUT: %foo.ref.loc21: = name_ref foo, [concrete = ] // CHECK:STDOUT: %.loc26_5.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %empty_tuple.loc26: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] // CHECK:STDOUT: %.loc26_5.2: %empty_tuple.type = converted %.loc26_5.1, %empty_tuple.loc26 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc26_3: ref = deref %.loc26_5.2 +// CHECK:STDOUT: %.loc26_3: ref = deref %.loc26_5.2 [concrete = ] // CHECK:STDOUT: %.loc31_4.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %empty_tuple.loc31: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] // CHECK:STDOUT: %.loc31_4.2: %empty_tuple.type = converted %.loc31_4.1, %empty_tuple.loc31 [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc31_5: ref = deref %.loc31_4.2 +// CHECK:STDOUT: %.loc31_5: ref = deref %.loc31_4.2 [concrete = ] // CHECK:STDOUT: %foo.ref.loc31: = name_ref foo, [concrete = ] // CHECK:STDOUT: %.loc36_5.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %empty_struct.loc36: %empty_struct_type = struct_value () [concrete = constants.%empty_struct] // CHECK:STDOUT: %.loc36_5.2: %empty_struct_type = converted %.loc36_5.1, %empty_struct.loc36 [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc36_3: ref = deref %.loc36_5.2 +// CHECK:STDOUT: %.loc36_3: ref = deref %.loc36_5.2 [concrete = ] // CHECK:STDOUT: %.loc41_4.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %empty_struct.loc41: %empty_struct_type = struct_value () [concrete = constants.%empty_struct] // CHECK:STDOUT: %.loc41_4.2: %empty_struct_type = converted %.loc41_4.1, %empty_struct.loc41 [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc41_5: ref = deref %.loc41_4.2 +// CHECK:STDOUT: %.loc41_5: ref = deref %.loc41_4.2 [concrete = ] // CHECK:STDOUT: %foo.ref.loc41: = name_ref foo, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/pointer/fail_deref_type.carbon b/toolchain/check/testdata/pointer/fail_deref_type.carbon index cd548f2de7a64..237ce6a1da394 100644 --- a/toolchain/check/testdata/pointer/fail_deref_type.carbon +++ b/toolchain/check/testdata/pointer/fail_deref_type.carbon @@ -52,7 +52,7 @@ var p2: i32->foo; // CHECK:STDOUT: %.1: = splice_block [concrete = ] { // CHECK:STDOUT: %int_32.loc18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %.loc18_8: ref = deref %i32.loc18 +// CHECK:STDOUT: %.loc18_8: ref = deref %i32.loc18 [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %p: = bind_name p, // CHECK:STDOUT: name_binding_decl { @@ -63,7 +63,7 @@ var p2: i32->foo; // CHECK:STDOUT: %.2: = splice_block [concrete = ] { // CHECK:STDOUT: %int_32.loc23: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %.loc23_12: ref = deref %i32.loc23 +// CHECK:STDOUT: %.loc23_12: ref = deref %i32.loc23 [concrete = ] // CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %p2: = bind_name p2, diff --git a/toolchain/check/testdata/struct/no_prelude/fail_nested_incomplete.carbon b/toolchain/check/testdata/struct/no_prelude/fail_nested_incomplete.carbon index 444313e31695e..be26739ac23fb 100644 --- a/toolchain/check/testdata/struct/no_prelude/fail_nested_incomplete.carbon +++ b/toolchain/check/testdata/struct/no_prelude/fail_nested_incomplete.carbon @@ -62,7 +62,7 @@ var p: Incomplete* = &s.a; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %s.ref: = name_ref s, file.%s +// CHECK:STDOUT: %s.ref: = name_ref s, file.%s [concrete = ] // CHECK:STDOUT: %a.ref: = name_ref a, [concrete = ] // CHECK:STDOUT: %addr: = addr_of %a.ref [concrete = ] // CHECK:STDOUT: assign file.%p.var, diff --git a/toolchain/check/testdata/tuple/fail_nested_incomplete.carbon b/toolchain/check/testdata/tuple/fail_nested_incomplete.carbon index 6756fde7dd514..16e376eb28f4a 100644 --- a/toolchain/check/testdata/tuple/fail_nested_incomplete.carbon +++ b/toolchain/check/testdata/tuple/fail_nested_incomplete.carbon @@ -79,7 +79,7 @@ var p: Incomplete* = &t[1]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %t.ref: = name_ref t, file.%t +// CHECK:STDOUT: %t.ref: = name_ref t, file.%t [concrete = ] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %addr: = addr_of [concrete = ] // CHECK:STDOUT: assign file.%p.var, diff --git a/toolchain/check/testdata/where_expr/designator.carbon b/toolchain/check/testdata/where_expr/designator.carbon index bd4a41158f7cf..bd55ce4f3913c 100644 --- a/toolchain/check/testdata/where_expr/designator.carbon +++ b/toolchain/check/testdata/where_expr/designator.carbon @@ -275,7 +275,7 @@ class D { // CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} // CHECK:STDOUT: %PeriodMismatch.decl: %PeriodMismatch.type = fn_decl @PeriodMismatch [concrete = constants.%PeriodMismatch] { // CHECK:STDOUT: %W.patt.loc12_19.1: = symbolic_binding_pattern W, 0 [symbolic = %W.patt.loc12_19.2 (constants.%W.patt)] -// CHECK:STDOUT: %W.param_patt: = value_param_pattern %W.patt.loc12_19.1, runtime_param [symbolic = %W.patt.loc12_19.2 (constants.%W.patt)] +// CHECK:STDOUT: %W.param_patt: = value_param_pattern %W.patt.loc12_19.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %W.param: = value_param runtime_param // CHECK:STDOUT: %.loc12_25.1: type = splice_block %.loc12_25.2 [concrete = ] { diff --git a/toolchain/check/testdata/where_expr/equal_rewrite.carbon b/toolchain/check/testdata/where_expr/equal_rewrite.carbon index b80237072d58e..8f205a5450820 100644 --- a/toolchain/check/testdata/where_expr/equal_rewrite.carbon +++ b/toolchain/check/testdata/where_expr/equal_rewrite.carbon @@ -1335,7 +1335,7 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: %RewriteTypeMismatch.decl: %RewriteTypeMismatch.type = fn_decl @RewriteTypeMismatch [concrete = constants.%RewriteTypeMismatch] { // CHECK:STDOUT: %X.patt.loc16_24.1: = symbolic_binding_pattern X, 0 [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)] -// CHECK:STDOUT: %X.param_patt: = value_param_pattern %X.patt.loc16_24.1, runtime_param [symbolic = %X.patt.loc16_24.2 (constants.%X.patt)] +// CHECK:STDOUT: %X.param_patt: = value_param_pattern %X.patt.loc16_24.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %X.param: = value_param runtime_param // CHECK:STDOUT: %.loc16_30.1: type = splice_block %.loc16_30.2 [concrete = ] { diff --git a/toolchain/check/testdata/where_expr/fail_not_facet.carbon b/toolchain/check/testdata/where_expr/fail_not_facet.carbon index 552e0d4d3cee5..c295827b1a634 100644 --- a/toolchain/check/testdata/where_expr/fail_not_facet.carbon +++ b/toolchain/check/testdata/where_expr/fail_not_facet.carbon @@ -67,7 +67,7 @@ var v: e where .x = 3; // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc8_6.1: = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: = value_param_pattern %T.patt.loc8_6.1, runtime_param [symbolic = %T.patt.loc8_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: = value_param_pattern %T.patt.loc8_6.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: = value_param runtime_param // CHECK:STDOUT: %.loc8_14.1: type = splice_block %.loc8_14.2 [concrete = ] { @@ -121,7 +121,7 @@ var v: e where .x = 3; // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { // CHECK:STDOUT: %U.patt.loc8_6.1: = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc8_6.2 (constants.%U.patt)] -// CHECK:STDOUT: %U.param_patt: = value_param_pattern %U.patt.loc8_6.1, runtime_param [symbolic = %U.patt.loc8_6.2 (constants.%U.patt)] +// CHECK:STDOUT: %U.param_patt: = value_param_pattern %U.patt.loc8_6.1, runtime_param [concrete = ] // CHECK:STDOUT: } { // CHECK:STDOUT: %U.param: = value_param runtime_param // CHECK:STDOUT: %.loc8_23.1: type = splice_block %.loc8_23.2 [concrete = ] { diff --git a/toolchain/lower/constant.cpp b/toolchain/lower/constant.cpp index 8d81bcc82de1a..3047b714ab498 100644 --- a/toolchain/lower/constant.cpp +++ b/toolchain/lower/constant.cpp @@ -226,6 +226,8 @@ template static auto MaybeEmitAsConstant(ConstantContext& context, InstT inst) -> llvm::Constant* { if constexpr (InstT::Kind.constant_kind() == SemIR::InstConstantKind::Never || + InstT::Kind.constant_kind() == + SemIR::InstConstantKind::Indirect || InstT::Kind.constant_kind() == SemIR::InstConstantKind::SymbolicOnly) { CARBON_FATAL("Unexpected constant instruction kind {0}", inst); diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index 64d6c79dad441..2ae307314e806 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -72,7 +72,9 @@ static auto LowerInstHelper(FunctionContext& context, SemIR::InstId inst_id, "instruction in lowered contexts. Instruction: {0}", inst); } else if constexpr (InstT::Kind.constant_kind() == - SemIR::InstConstantKind::Always) { + SemIR::InstConstantKind::Always || + InstT::Kind.constant_kind() == + SemIR::InstConstantKind::Unique) { CARBON_FATAL("Missing constant value for constant instruction {0}", inst); } else if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Always) { // For instructions that are always of type `type`, produce the trivial diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 47fb2201786a0..7c25a7e9dd10c 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -1349,6 +1349,10 @@ class FormatterImpl { FormatName(static_cast(id)); } + auto FormatName(DestInstId id) -> void { + FormatName(static_cast(id)); + } + auto FormatName(SpecificId id) -> void { const auto& specific = sem_ir_->specifics().Get(id); FormatName(specific.generic_id); diff --git a/toolchain/sem_ir/id_kind.h b/toolchain/sem_ir/id_kind.h index 603338c353454..a19642f24e9a0 100644 --- a/toolchain/sem_ir/id_kind.h +++ b/toolchain/sem_ir/id_kind.h @@ -139,7 +139,7 @@ using IdKind = TypeEnum< // From base/value_store.h. IntId, RealId, FloatId, StringLiteralValueId, // From sem_ir/ids.h. - InstId, AbsoluteInstId, AnyRawId, ConstantId, EntityNameId, + InstId, AbsoluteInstId, DestInstId, AnyRawId, ConstantId, EntityNameId, CompileTimeBindIndex, RuntimeParamIndex, FacetTypeId, FunctionId, ClassId, InterfaceId, AssociatedConstantId, ImplId, GenericId, SpecificId, ImportIRId, ImportIRInstId, LocId, BoolValue, IntKind, NameId, NameScopeId, diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 0d0a16a4caecf..b1a949d2c8b6c 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -74,6 +74,28 @@ class AbsoluteInstId : public InstId { using InstId::InstId; }; +// An ID of an instruction that is used as the destination of an initializing +// expression. This should only be used as the type of a field within a typed +// instruction class. +// +// This behaves in most respects like an InstId field, but constant evaluation +// of an instruction with a destination field will not evaluate this field, and +// substitution will not substitute into it. +// +// TODO: Decide on how substitution should handle this. Multiple instructions +// can refer to the same destination, so these don't have the tree structure +// that substitution expects, but we might need to substitute into the result of +// an instruction. +class DestInstId : public InstId { + public: + // Support implicit conversion from InstId so that InstId and DestInstId + // have the same interface. + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr DestInstId(InstId inst_id) : InstId(inst_id) {} + + using InstId::InstId; +}; + // The ID of a constant value of an expression. An expression is either: // // - a concrete constant, whose value does not depend on any generic parameters, @@ -110,17 +132,17 @@ struct ConstantId : public IdBase { using IdBase::IdBase; // Returns whether this represents a constant. Requires has_value. - auto is_constant() const -> bool { + constexpr auto is_constant() const -> bool { CARBON_DCHECK(has_value()); return *this != ConstantId::NotConstant; } // Returns whether this represents a symbolic constant. Requires has_value. - auto is_symbolic() const -> bool { + constexpr auto is_symbolic() const -> bool { CARBON_DCHECK(has_value()); return index <= FirstSymbolicIndex; } // Returns whether this represents a concrete constant. Requires has_value. - auto is_concrete() const -> bool { + constexpr auto is_concrete() const -> bool { CARBON_DCHECK(has_value()); return index >= 0; } diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 2393263ab1653..abd90cb7befb7 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -286,7 +286,8 @@ class Inst : public Printable { // Raw constructor, used for testing. explicit Inst(InstKind kind, TypeId type_id, int32_t arg0, int32_t arg1) : Inst(kind.AsInt(), type_id, arg0, arg1) {} - explicit Inst(int32_t kind, TypeId type_id, int32_t arg0, int32_t arg1) + explicit constexpr Inst(int32_t kind, TypeId type_id, int32_t arg0, + int32_t arg1) : kind_(kind), type_id_(type_id), arg0_(arg0), arg1_(arg1) {} int32_t kind_; diff --git a/toolchain/sem_ir/inst_kind.h b/toolchain/sem_ir/inst_kind.h index 79a416a74a213..d85ee87b6989f 100644 --- a/toolchain/sem_ir/inst_kind.h +++ b/toolchain/sem_ir/inst_kind.h @@ -7,10 +7,7 @@ #include -#include "common/check.h" #include "common/enum_base.h" -#include "llvm/ADT/FoldingSet.h" - namespace Carbon::SemIR { // Whether an instruction defines a type. @@ -35,28 +32,51 @@ enum class InstValueKind : int8_t { Typed, }; -// Whether an instruction can be used to define a constant value. This specifies -// whether the instruction can be added to the `constants()` list. Note that -// even instructions that cannot define a constant value can still have an -// associated `constant_value()`, but the constant value will be a different -// kind of instruction. +// Whether an instruction can have a constant value, and whether it can be used +// to define a constant value. +// +// This specifies whether an instruction of this kind can have a corresponding +// constant value in the `constant_values()` list, and whether an instruction of +// this kind can be added to the `constants()` list. enum class InstConstantKind : int8_t { - // This instruction never defines a constant value. For example, - // `UnaryOperatorNot` never defines a constant value; if its operand is a - // concrete constant, its constant value will instead be a `BoolLiteral`. This - // is also used for instructions that don't produce a value at all. + // This instruction is never constant. Its constant value is always + // `NotConstant`. This is also used for instructions that don't produce a + // value at all and aren't used as constants. Never, - // This instruction may be a symbolic constant, depending on its operands, but - // is never a concrete constant. For example, a `Call` instruction can be a - // symbolic constant but never a concrete constant. + // This instruction never defines a constant value, but can evaluate to a + // constant value of a different kind. For example, `UnaryOperatorNot` never + // defines a constant value; if its operand is a concrete constant, its + // constant value will instead be a `BoolLiteral`, and if its operand is not a + // concrete constant, the result is non-constant. This is the default. + Indirect, + // This instruction may define a symbolic constant, depending on its operands, + // but never a concrete constant. For example, a `Call` instruction can define + // a symbolic constant but never a concrete constant. The instruction may have + // a concrete constant value of a different kind. SymbolicOnly, // This instruction can define a symbolic or concrete constant, but might not - // have a constant value, depending on its operands. For example, a - // `TupleValue` can define a constant if its operands are constants. + // have a constant value, might have a constant value that is not defined by + // itself, or might result in a compile-time error, depending on its operands. + // For example, `ArrayType` is a compile-time constant if its operands are + // constant and its array bound is within a valid range. Conditional, - // This instruction always has a constant value of the same kind. For example, - // `IntValue`. + // This instruction defines a symbolic or concrete constant whenever its + // operands are constant. Otherwise, it is non-constant. For example, a + // `TupleValue` defines a constant if and only if its operands are constants. + // Constant evaluation support for types with this constant kind is provided + // automatically. + WheneverPossible, + // This instruction always has a constant value of the same kind. This is the + // same as `WheneverPossible`, except that the operands are known in advance + // to always be constant. For example, `IntValue`. Always, + // This instruction is itself a unique constant. This is used for declarations + // whose constant identity is simply themselves. The `ConstantId` for this + // instruction will always be a concrete constant whose `InstId` refers + // directly back to the instruction, rather than to a separate instrinction in + // the constants block. + // TODO: Decide if this is the model we want for these cases. + Unique, }; // Whether an instruction is a terminator or part of the terminator sequence. @@ -91,7 +111,7 @@ class InstKind : public CARBON_ENUM_BASE(InstKind) { struct DefinitionInfo { llvm::StringLiteral ir_name; InstIsType is_type = InstIsType::Never; - InstConstantKind constant_kind = InstConstantKind::Never; + InstConstantKind constant_kind = InstConstantKind::Indirect; TerminatorKind terminator_kind = TerminatorKind::NotTerminator; bool is_lowered = true; bool deduce_through = false; @@ -143,10 +163,6 @@ class InstKind : public CARBON_ENUM_BASE(InstKind) { return definition_info(*this).deduce_through; } - // Compute a fingerprint for this instruction kind, allowing its use as part - // of the key in a `FoldingSet`. - auto Profile(llvm::FoldingSetNodeID& id) -> void { id.AddInteger(AsInt()); } - private: // Returns the DefinitionInfo for the kind. static auto definition_info(InstKind kind) -> const DefinitionInfo&; diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 186bc24e9b657..1d61789350940 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -48,32 +48,6 @@ namespace Carbon::SemIR { -// Used for the type of patterns that do not match a fixed type. -struct AutoType { - static constexpr auto Kind = InstKind::AutoType.Define( - {.ir_name = "auto", - .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Always}); - static constexpr auto SingletonInstId = MakeSingletonInstId(); - static constexpr auto SingletonTypeId = - TypeId::ForTypeConstant(ConstantId::ForConcreteConstant(SingletonInstId)); - - TypeId type_id; -}; - -// The type of bool literals and branch conditions, bool. -struct BoolType { - static constexpr auto Kind = InstKind::BoolType.Define( - {.ir_name = "bool", - .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Always}); - // This is a singleton instruction. However, it may still evolve into a more - // standard type and be removed. - static constexpr auto SingletonInstId = MakeSingletonInstId(); - - TypeId type_id; -}; - // Common representation for declarations describing the foundation type of a // class -- either its adapted type or its base class. struct AnyFoundationDecl { @@ -89,7 +63,7 @@ struct AnyFoundationDecl { struct AdaptDecl { static constexpr auto Kind = InstKind::AdaptDecl.Define( {.ir_name = "adapt_decl", - .constant_kind = InstConstantKind::Always, + .constant_kind = InstConstantKind::Unique, .is_lowered = false}); // No type_id; this is not a value. @@ -101,7 +75,8 @@ struct AdaptDecl { struct AddrOf { // Parse node is usually Parse::PrefixOperatorAmpId. static constexpr auto Kind = InstKind::AddrOf.Define( - {.ir_name = "addr_of", .constant_kind = InstConstantKind::Conditional}); + {.ir_name = "addr_of", + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; InstId lvalue_id; @@ -111,7 +86,9 @@ struct AddrOf { // generally be a pattern inst. struct AddrPattern { static constexpr auto Kind = InstKind::AddrPattern.Define( - {.ir_name = "addr_pattern", .is_lowered = false}); + {.ir_name = "addr_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); TypeId type_id; // The `self` binding. @@ -153,7 +130,7 @@ struct AnyAggregateInit { InstKind kind; TypeId type_id; InstBlockId elements_id; - InstId dest_id; + DestInstId dest_id; }; // Common representation for all kinds of aggregate value. @@ -175,7 +152,7 @@ struct ArrayInit { TypeId type_id; InstBlockId inits_id; - InstId dest_id; + DestInstId dest_id; }; // An array of `element_type_id` values, sized to `bound_id`. @@ -205,8 +182,8 @@ struct AsCompatible { // `InitializeFrom`. struct Assign { // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = - InstKind::Assign.Define({.ir_name = "assign"}); + static constexpr auto Kind = InstKind::Assign.Define( + {.ir_name = "assign", .constant_kind = InstConstantKind::Never}); // Assignments are statements, and so have no type. InstId lhs_id; @@ -218,7 +195,9 @@ struct AssociatedConstantDecl { static constexpr auto Kind = InstKind::AssociatedConstantDecl .Define( - {.ir_name = "assoc_const_decl", .is_lowered = false}); + {.ir_name = "assoc_const_decl", + .constant_kind = InstConstantKind::Unique, + .is_lowered = false}); TypeId type_id; AssociatedConstantId assoc_const_id; @@ -246,7 +225,7 @@ struct AssociatedEntityType { InstKind::AssociatedEntityType.Define( {.ir_name = "assoc_entity_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; // The interface in which the entity was declared. @@ -254,12 +233,25 @@ struct AssociatedEntityType { TypeId interface_type_id; }; +// Used for the type of patterns that do not match a fixed type. +struct AutoType { + static constexpr auto Kind = InstKind::AutoType.Define( + {.ir_name = "auto", + .is_type = InstIsType::Always, + .constant_kind = InstConstantKind::Always}); + static constexpr auto SingletonInstId = MakeSingletonInstId(); + static constexpr auto SingletonTypeId = + TypeId::ForTypeConstant(ConstantId::ForConcreteConstant(SingletonInstId)); + + TypeId type_id; +}; + // A base in a class, of the form `base: base_type;`. A base class is an // element of the derived class, and the type of the `BaseDecl` instruction is // an `UnboundElementType`. struct BaseDecl { static constexpr auto Kind = InstKind::BaseDecl.Define( - {.ir_name = "base_decl", .constant_kind = InstConstantKind::Always}); + {.ir_name = "base_decl", .constant_kind = InstConstantKind::Unique}); TypeId type_id; InstId base_type_inst_id; @@ -304,8 +296,8 @@ struct BindAlias { // Binds a name, such as `x` in `var x: i32`. struct BindName { // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = - InstKind::BindName.Define({.ir_name = "bind_name"}); + static constexpr auto Kind = InstKind::BindName.Define( + {.ir_name = "bind_name", .constant_kind = InstConstantKind::Never}); TypeId type_id; EntityNameId entity_name_id; @@ -350,7 +342,9 @@ struct AnyBindingPattern { // Represents a non-symbolic binding pattern. struct BindingPattern { static constexpr auto Kind = InstKind::BindingPattern.Define( - {.ir_name = "binding_pattern", .is_lowered = false}); + {.ir_name = "binding_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); TypeId type_id; EntityNameId entity_name_id; @@ -371,8 +365,8 @@ struct SymbolicBindingPattern { // Reads an argument from `BranchWithArg`. struct BlockArg { - static constexpr auto Kind = - InstKind::BlockArg.Define({.ir_name = "block_arg"}); + static constexpr auto Kind = InstKind::BlockArg.Define( + {.ir_name = "block_arg", .constant_kind = InstConstantKind::Never}); TypeId type_id; LabelId block_id; @@ -388,13 +382,26 @@ struct BoolLiteral { BoolValue value; }; +// The type of bool literals and branch conditions, bool. +struct BoolType { + static constexpr auto Kind = InstKind::BoolType.Define( + {.ir_name = "bool", + .is_type = InstIsType::Always, + .constant_kind = InstConstantKind::Always}); + // This is a singleton instruction. However, it may still evolve into a more + // standard type and be removed. + static constexpr auto SingletonInstId = MakeSingletonInstId(); + + TypeId type_id; +}; + // For member access such as `object.MethodName`, combines a member function // with the value to use for `self`. This is a callable structure; `Call` will // handle the argument assignment. struct BoundMethod { static constexpr auto Kind = InstKind::BoundMethod.Define( {.ir_name = "bound_method", - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; // The object argument in the bound method, which will be used to initialize @@ -435,7 +442,9 @@ struct AnyBranch { struct Branch { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = InstKind::Branch.Define( - {.ir_name = "br", .terminator_kind = TerminatorKind::Terminator}); + {.ir_name = "br", + .constant_kind = InstConstantKind::Never, + .terminator_kind = TerminatorKind::Terminator}); // Branches don't produce a value, so have no type. LabelId target_id; @@ -445,7 +454,9 @@ struct Branch { struct BranchIf { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = InstKind::BranchIf.Define( - {.ir_name = "br", .terminator_kind = TerminatorKind::TerminatorSequence}); + {.ir_name = "br", + .constant_kind = InstConstantKind::Never, + .terminator_kind = TerminatorKind::TerminatorSequence}); // Branches don't produce a value, so have no type. LabelId target_id; @@ -457,7 +468,9 @@ struct BranchIf { struct BranchWithArg { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = InstKind::BranchWithArg.Define( - {.ir_name = "br", .terminator_kind = TerminatorKind::Terminator}); + {.ir_name = "br", + .constant_kind = InstConstantKind::Never, + .terminator_kind = TerminatorKind::Terminator}); // Branches don't produce a value, so have no type. LabelId target_id; @@ -517,7 +530,7 @@ struct ClassInit { TypeId type_id; InstBlockId elements_id; - InstId dest_id; + DestInstId dest_id; }; // The type for a class, either non-generic or specific. @@ -572,7 +585,9 @@ struct Converted { InstKind::Converted.Define({.ir_name = "converted"}); TypeId type_id; - InstId original_id; + // The operand prior to being converted. This is tracked only for tooling + // purposes and has no associated semantics. + AbsoluteInstId original_id; InstId result_id; }; @@ -674,7 +689,7 @@ struct FacetValue { struct FieldDecl { static constexpr auto Kind = InstKind::FieldDecl.Define( - {.ir_name = "field_decl", .constant_kind = InstConstantKind::Always}); + {.ir_name = "field_decl", .constant_kind = InstConstantKind::Unique}); TypeId type_id; NameId name_id; @@ -741,7 +756,7 @@ struct FunctionType { InstKind::FunctionType.Define( {.ir_name = "fn_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; FunctionId function_id; @@ -756,7 +771,7 @@ struct FunctionTypeWithSelfType { InstKind::FunctionTypeWithSelfType.Define( {.ir_name = "fn_type_with_self_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, .is_lowered = false}); TypeId type_id; @@ -776,7 +791,7 @@ struct GenericClassType { InstKind::GenericClassType.Define( {.ir_name = "generic_class_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; ClassId class_id; @@ -791,7 +806,7 @@ struct GenericInterfaceType { InstKind::GenericInterfaceType.Define( {.ir_name = "generic_interface_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; InterfaceId interface_id; @@ -802,7 +817,9 @@ struct GenericInterfaceType { struct ImplDecl { static constexpr auto Kind = InstKind::ImplDecl.Define( {.ir_name = "impl_decl", - .constant_kind = InstConstantKind::Always, + // TODO: Modeling impls as unique doesn't properly handle impl + // redeclarations. + .constant_kind = InstConstantKind::Unique, .is_lowered = false}); // No type: an impl declaration is not a value. @@ -816,7 +833,7 @@ struct ImplDecl { struct ImplWitness { static constexpr auto Kind = InstKind::ImplWitness.Define( {.ir_name = "impl_witness", - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, // TODO: For dynamic dispatch, we might want to lower witness tables as // constants. .is_lowered = false}); @@ -845,14 +862,18 @@ struct ImplWitnessAccess { struct ImportCppDecl { static constexpr auto Kind = InstKind::ImportCppDecl.Define( - {.ir_name = "import_cpp", .is_lowered = false}); + {.ir_name = "import_cpp", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); }; // An `import` declaration. This is mainly for `import` diagnostics, and a 1:1 // correspondence with actual `import`s isn't guaranteed. struct ImportDecl { static constexpr auto Kind = InstKind::ImportDecl.Define( - {.ir_name = "import", .is_lowered = false}); + {.ir_name = "import", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); NameId package_id; }; @@ -901,7 +922,7 @@ struct InitializeFrom { TypeId type_id; InstId src_id; - InstId dest_id; + DestInstId dest_id; }; // An interface declaration. @@ -968,7 +989,8 @@ struct IntType { struct NameBindingDecl { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = InstKind::NameBindingDecl.Define( - {.ir_name = "name_binding_decl"}); + {.ir_name = "name_binding_decl", + .constant_kind = InstConstantKind::Never}); InstBlockId pattern_block_id; }; @@ -989,7 +1011,10 @@ struct NameRef { struct Namespace { static constexpr auto Kind = InstKind::Namespace.Define( - {.ir_name = "namespace", .constant_kind = InstConstantKind::Always}); + {.ir_name = "namespace", + // TODO: Modeling namespaces as unique doesn't properly handle + // namespace redeclarations. + .constant_kind = InstConstantKind::Unique}); // The file's package namespace is a well-known instruction to help `package.` // qualified names. It will always be immediately after singletons. static constexpr InstId PackageInstId = InstId(SingletonInstKinds.size()); @@ -1035,8 +1060,8 @@ struct AnyParam { // An output parameter. See AnyParam for member documentation. struct OutParam { // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = - InstKind::OutParam.Define({.ir_name = "out_param"}); + static constexpr auto Kind = InstKind::OutParam.Define( + {.ir_name = "out_param", .constant_kind = InstConstantKind::Never}); TypeId type_id; RuntimeParamIndex runtime_index; @@ -1046,8 +1071,8 @@ struct OutParam { // A by-value parameter. See AnyParam for member documentation. struct ValueParam { // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = - InstKind::ValueParam.Define({.ir_name = "value_param"}); + static constexpr auto Kind = InstKind::ValueParam.Define( + {.ir_name = "value_param", .constant_kind = InstConstantKind::Never}); TypeId type_id; RuntimeParamIndex runtime_index; @@ -1071,7 +1096,9 @@ struct AnyParamPattern { struct OutParamPattern { static constexpr auto Kind = InstKind::OutParamPattern.Define( - {.ir_name = "out_param_pattern", .is_lowered = false}); + {.ir_name = "out_param_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); TypeId type_id; InstId subpattern_id; @@ -1097,7 +1124,7 @@ struct PointerType { InstKind::PointerType.Define( {.ir_name = "ptr_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, .deduce_through = true}); TypeId type_id; @@ -1126,7 +1153,9 @@ struct Return { static constexpr auto Kind = InstKind::Return.Define>( - {.ir_name = "return", .terminator_kind = TerminatorKind::Terminator}); + {.ir_name = "return", + .constant_kind = InstConstantKind::Never, + .terminator_kind = TerminatorKind::Terminator}); // This is a statement, so has no type. }; @@ -1135,20 +1164,22 @@ struct Return { struct ReturnExpr { static constexpr auto Kind = InstKind::ReturnExpr.Define( - {.ir_name = "return", .terminator_kind = TerminatorKind::Terminator}); + {.ir_name = "return", + .constant_kind = InstConstantKind::Never, + .terminator_kind = TerminatorKind::Terminator}); // This is a statement, so has no type. InstId expr_id; // The return slot, if any. `None` if we're not returning through memory. - InstId dest_id; + DestInstId dest_id; }; // The return slot of a function declaration, as exposed in the function body. // This acts as an output parameter, analogous to `BindName` for input // parameters. struct ReturnSlot { - static constexpr auto Kind = - InstKind::ReturnSlot.Define({.ir_name = "return_slot"}); + static constexpr auto Kind = InstKind::ReturnSlot.Define( + {.ir_name = "return_slot", .constant_kind = InstConstantKind::Never}); // The type of the value that will be stored in this slot (i.e. the return // type of the function). @@ -1169,7 +1200,9 @@ struct ReturnSlot { struct ReturnSlotPattern { static constexpr auto Kind = InstKind::ReturnSlotPattern.Define( - {.ir_name = "return_slot_pattern", .is_lowered = false}); + {.ir_name = "return_slot_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); // The type of the value that will be stored in this slot (i.e. the return // type of the function). @@ -1185,7 +1218,9 @@ struct ReturnSlotPattern { struct RequirementEquivalent { static constexpr auto Kind = InstKind::RequirementEquivalent.Define( - {.ir_name = "requirement_equivalent", .is_lowered = false}); + {.ir_name = "requirement_equivalent", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); // No type since not an expression InstId lhs_id; @@ -1196,7 +1231,9 @@ struct RequirementEquivalent { struct RequirementImpls { static constexpr auto Kind = InstKind::RequirementImpls.Define( - {.ir_name = "requirement_impls", .is_lowered = false}); + {.ir_name = "requirement_impls", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); // No type since not an expression InstId lhs_id; @@ -1207,7 +1244,9 @@ struct RequirementImpls { struct RequirementRewrite { static constexpr auto Kind = InstKind::RequirementRewrite.Define( - {.ir_name = "requirement_rewrite", .is_lowered = false}); + {.ir_name = "requirement_rewrite", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); // No type since not an expression InstId lhs_id; @@ -1241,7 +1280,7 @@ struct SpecificConstant { struct SpecificFunction { static constexpr auto Kind = InstKind::SpecificFunction.Define( {.ir_name = "specific_function", - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); // Always the builtin SpecificFunctionType. TypeId type_id; @@ -1275,7 +1314,7 @@ struct SpliceBlock { InstKind::SpliceBlock.Define({.ir_name = "splice_block"}); TypeId type_id; - InstBlockId block_id; + AbsoluteInstBlockId block_id; InstId result_id; }; @@ -1323,14 +1362,15 @@ struct StructInit { TypeId type_id; InstBlockId elements_id; - InstId dest_id; + DestInstId dest_id; }; // A literal struct value, such as `{.a = 1, .b = 2}`. struct StructLiteral { static constexpr auto Kind = InstKind::StructLiteral.Define( - {.ir_name = "struct_literal"}); + {.ir_name = "struct_literal", + .constant_kind = InstConstantKind::Never}); TypeId type_id; InstBlockId elements_id; @@ -1342,7 +1382,7 @@ struct StructType { InstKind::StructType.Define( {.ir_name = "struct_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, .deduce_through = true}); TypeId type_id; @@ -1353,7 +1393,7 @@ struct StructType { struct StructValue { static constexpr auto Kind = InstKind::StructValue.Define( {.ir_name = "struct_value", - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; InstBlockId elements_id; @@ -1365,7 +1405,7 @@ struct Temporary { InstKind::Temporary.Define({.ir_name = "temporary"}); TypeId type_id; - InstId storage_id; + DestInstId storage_id; InstId init_id; }; @@ -1373,7 +1413,8 @@ struct Temporary { struct TemporaryStorage { // TODO: Make Parse::NodeId more specific. static constexpr auto Kind = InstKind::TemporaryStorage.Define( - {.ir_name = "temporary_storage"}); + {.ir_name = "temporary_storage", + .constant_kind = InstConstantKind::Never}); TypeId type_id; }; @@ -1398,14 +1439,15 @@ struct TupleInit { TypeId type_id; InstBlockId elements_id; - InstId dest_id; + DestInstId dest_id; }; // A literal tuple value. struct TupleLiteral { static constexpr auto Kind = InstKind::TupleLiteral.Define( - {.ir_name = "tuple_literal"}); + {.ir_name = "tuple_literal", + .constant_kind = InstConstantKind::Never}); TypeId type_id; InstBlockId elements_id; @@ -1415,7 +1457,9 @@ struct TupleLiteral { struct TuplePattern { static constexpr auto Kind = InstKind::TuplePattern.Define( - {.ir_name = "tuple_pattern", .is_lowered = false}); + {.ir_name = "tuple_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); TypeId type_id; InstBlockId elements_id; @@ -1426,7 +1470,7 @@ struct TupleType { static constexpr auto Kind = InstKind::TupleType.Define( {.ir_name = "tuple_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, .deduce_through = true}); TypeId type_id; @@ -1437,7 +1481,7 @@ struct TupleType { struct TupleValue { static constexpr auto Kind = InstKind::TupleValue.Define( {.ir_name = "tuple_value", - .constant_kind = InstConstantKind::Conditional, + .constant_kind = InstConstantKind::WheneverPossible, .deduce_through = true}); TypeId type_id; @@ -1476,7 +1520,7 @@ struct UnboundElementType { Parse::NodeIdOneOf>( {.ir_name = "unbound_element_type", .is_type = InstIsType::Always, - .constant_kind = InstConstantKind::Conditional}); + .constant_kind = InstConstantKind::WheneverPossible}); TypeId type_id; // The class that a value of this type is an element of. @@ -1491,7 +1535,7 @@ struct UnboundElementType { // form a reference to the array object. struct ValueAsRef { static constexpr auto Kind = InstKind::ValueAsRef.Define( - {.ir_name = "value_as_ref"}); + {.ir_name = "value_as_ref", .constant_kind = InstConstantKind::Never}); TypeId type_id; InstId value_id; @@ -1514,7 +1558,9 @@ struct ValueOfInitializer { struct VarPattern { static constexpr auto Kind = InstKind::VarPattern.Define( - {.ir_name = "var_pattern", .is_lowered = false}); + {.ir_name = "var_pattern", + .constant_kind = InstConstantKind::Never, + .is_lowered = false}); TypeId type_id; InstId subpattern_id; @@ -1523,8 +1569,8 @@ struct VarPattern { // Tracks storage for a `var` pattern. struct VarStorage { // TODO: Make Parse::NodeId more specific. - static constexpr auto Kind = - InstKind::VarStorage.Define({.ir_name = "var"}); + static constexpr auto Kind = InstKind::VarStorage.Define( + {.ir_name = "var", .constant_kind = InstConstantKind::Never}); TypeId type_id; From 467e510d400ff7fa338e81737831649c400c74be Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 26 Feb 2025 18:13:17 -0800 Subject: [PATCH 34/56] Document abbreviation style things (#4996) We had a long discussion of this, so trying to document what seems to be the conclusion... and also clean up the exceptions that I could find. --------- Co-authored-by: Dana Jansens --- common/hashing_test.cpp | 2 +- common/hashtable_key_context.h | 12 +- common/map_test.cpp | 2 +- common/raw_hashtable_metadata_group.h | 200 +++++++++--------- ...raw_hashtable_metadata_group_benchmark.cpp | 32 +-- common/set_test.cpp | 2 +- docs/project/cpp_style_guide.md | 6 + testing/base/source_gen.cpp | 2 +- testing/base/source_gen.h | 2 +- testing/base/source_gen_main.cpp | 2 +- testing/base/source_gen_test.cpp | 8 +- toolchain/diagnostics/coverage_test.cpp | 4 +- toolchain/diagnostics/diagnostic_kind.def | 4 +- toolchain/docs/adding_features.md | 2 +- toolchain/driver/compile_benchmark.cpp | 10 +- toolchain/lex/lex.cpp | 20 +- toolchain/lex/tokenized_buffer_test.cpp | 10 +- toolchain/parse/tree_test.cpp | 4 +- toolchain/sem_ir/formatter.cpp | 78 +++---- toolchain/sem_ir/yaml_test.cpp | 2 +- 20 files changed, 205 insertions(+), 199 deletions(-) diff --git a/common/hashing_test.cpp b/common/hashing_test.cpp index d33b56ff553af..94f615584d660 100644 --- a/common/hashing_test.cpp +++ b/common/hashing_test.cpp @@ -23,7 +23,7 @@ using ::testing::Eq; using ::testing::Le; using ::testing::Ne; -TEST(HashingTest, HashCodeAPI) { +TEST(HashingTest, HashCodeApi) { // Manually compute a few hash codes where we can exercise the underlying API. HashCode empty = HashValue(""); HashCode a = HashValue("a"); diff --git a/common/hashtable_key_context.h b/common/hashtable_key_context.h index c38ae84af724e..32c57fcd43018 100644 --- a/common/hashtable_key_context.h +++ b/common/hashtable_key_context.h @@ -50,7 +50,7 @@ auto HashtableEq(const LeftT& lhs, const RightT& rhs) -> bool; // properties of hashes produced by the `hashing.h` infrastructure. // // The default for comparison is `operator==`. The `KeyEq` method is always -// called with a key *stored in the hashtable* as the second or "RHS" parameter. +// called with a key *stored in the hashtable* as the second or "Rhs" parameter. // This is to allow simplifying the set of overloads needed for heterogeneous // contexts: only the first, LHS, parameter needs to support different lookup // key types. @@ -217,13 +217,13 @@ auto TranslatingKeyContext::KeyEq(const AnyKeyT& lhs_key, const DerivedT& self = *static_cast(this); // Because we don't want to make no-op calls and potentially struggle with // temporary lifetimes at runtime we have to fully expand the 4 states. - constexpr bool TranslateLHS = requires { self.TranslateKey(lhs_key); }; - constexpr bool TranslateRHS = requires { self.TranslateKey(rhs_key); }; - if constexpr (TranslateLHS && TranslateRHS) { + constexpr bool TranslateLhs = requires { self.TranslateKey(lhs_key); }; + constexpr bool TranslateRhs = requires { self.TranslateKey(rhs_key); }; + if constexpr (TranslateLhs && TranslateRhs) { return HashtableEq(self.TranslateKey(lhs_key), self.TranslateKey(rhs_key)); - } else if constexpr (TranslateLHS) { + } else if constexpr (TranslateLhs) { return HashtableEq(self.TranslateKey(lhs_key), rhs_key); - } else if constexpr (TranslateRHS) { + } else if constexpr (TranslateRhs) { return HashtableEq(lhs_key, self.TranslateKey(rhs_key)); } else { return HashtableEq(lhs_key, rhs_key); diff --git a/common/map_test.cpp b/common/map_test.cpp index b1cc739d3a1be..7b7cf1c9ec2f0 100644 --- a/common/map_test.cpp +++ b/common/map_test.cpp @@ -124,7 +124,7 @@ TYPED_TEST(MapTest, Basic) { m, MakeKeyValues([](int k) { return k * 100 + 1; }, llvm::seq(1, 512))); } -TYPED_TEST(MapTest, FactoryAPI) { +TYPED_TEST(MapTest, FactoryApi) { TypeParam m; EXPECT_TRUE(m.Insert(1, [] { return 100; }).is_inserted()); ASSERT_TRUE(m.Contains(1)); diff --git a/common/raw_hashtable_metadata_group.h b/common/raw_hashtable_metadata_group.h index 4019572b3d706..943a49fa1fe4c 100644 --- a/common/raw_hashtable_metadata_group.h +++ b/common/raw_hashtable_metadata_group.h @@ -303,14 +303,14 @@ class BitIndexRange // auto MetadataGroup::Operation(...) -> ... { // ... portable_result; // ... simd_result; -// if constexpr (!UseSIMD || DebugSIMD) { +// if constexpr (!UseSimd || DebugSimd) { // portable_result = PortableOperation(...); // } -// if (UseSIMD || DebugSIMD) { -// simd_result = SIMDOperation(...) +// if (UseSimd || DebugSimd) { +// simd_result = SimdOperation(...) // CARBON_DCHECK(result == portable_result, "{0}", ...); // } -// return UseSIMD ? simd_result : portable_result; +// return UseSimd ? simd_result : portable_result; // } // ``` class MetadataGroup : public Printable { @@ -344,7 +344,7 @@ class MetadataGroup : public Printable { // Whether to use a SIMD implementation. Even when we *support* a SIMD // implementation, we do not always have to use it in the event that it is // less efficient than the portable version. - static constexpr bool UseSIMD = + static constexpr bool UseSimd = #if CARBON_X86_SIMD_SUPPORT true; #else @@ -375,8 +375,8 @@ class MetadataGroup : public Printable { static constexpr bool FastByteClear = Size == 8; // Most and least significant bits set. - static constexpr uint64_t MSBs = 0x8080'8080'8080'8080ULL; - static constexpr uint64_t LSBs = 0x0101'0101'0101'0101ULL; + static constexpr uint64_t Msbs = 0x8080'8080'8080'8080ULL; + static constexpr uint64_t Lsbs = 0x0101'0101'0101'0101ULL; using MatchIndex = BitIndex, @@ -389,16 +389,16 @@ class MetadataGroup : public Printable { // We use specialized match range types for SIMD implementations to allow // deferring the masking operation where useful. When that optimization // doesn't apply, these will be the same type. - using SIMDMatchRange = - BitIndexRange; - using SIMDMatchPresentRange = BitIndexRange; + using SimdMatchRange = + BitIndexRange; + using SimdMatchPresentRange = BitIndexRange; // The public API range types can be either the portable or SIMD variations, // selected here. using MatchRange = - std::conditional_t; + std::conditional_t; using MatchPresentRange = - std::conditional_t; + std::conditional_t; union { uint8_t metadata_bytes[Size]; @@ -477,13 +477,13 @@ class MetadataGroup : public Printable { // Two classes only defined in the benchmark code are allowed to directly call // the portable and SIMD implementations for benchmarking purposes. friend class BenchmarkPortableMetadataGroup; - friend class BenchmarkSIMDMetadataGroup; + friend class BenchmarkSimdMetadataGroup; // All SIMD variants that we have an implementation for should be enabled for // debugging. This lets us maintain a SIMD implementation even if it is not // used due to performance reasons, and easily re-enable it if the performance // changes. - static constexpr bool DebugSIMD = + static constexpr bool DebugSimd = #if !defined(NDEBUG) && (CARBON_NEON_SIMD_SUPPORT || CARBON_X86_SIMD_SUPPORT) true; #else @@ -553,23 +553,23 @@ class MetadataGroup : public Printable { // // These routines don't directly verify their results as we can build simpler // debug checks by comparing them against the verified portable results. - static auto SIMDLoad(const uint8_t* metadata, ssize_t index) -> MetadataGroup; - auto SIMDStore(uint8_t* metadata, ssize_t index) const -> void; + static auto SimdLoad(const uint8_t* metadata, ssize_t index) -> MetadataGroup; + auto SimdStore(uint8_t* metadata, ssize_t index) const -> void; - auto SIMDClearDeleted() -> void; + auto SimdClearDeleted() -> void; - auto SIMDMatch(uint8_t tag) const -> SIMDMatchRange; - auto SIMDMatchPresent() const -> SIMDMatchPresentRange; + auto SimdMatch(uint8_t tag) const -> SimdMatchRange; + auto SimdMatchPresent() const -> SimdMatchPresentRange; - auto SIMDMatchEmpty() const -> MatchIndex; - auto SIMDMatchDeleted() const -> MatchIndex; + auto SimdMatchEmpty() const -> MatchIndex; + auto SimdMatchDeleted() const -> MatchIndex; - static auto SIMDCompareEqual(MetadataGroup lhs, MetadataGroup rhs) -> bool; + static auto SimdCompareEqual(MetadataGroup lhs, MetadataGroup rhs) -> bool; #if CARBON_X86_SIMD_SUPPORT // A common routine for x86 SIMD matching that can be used for matching // present, empty, and deleted bytes with equal efficiency. - auto X86SIMDMatch(uint8_t match_byte) const -> SIMDMatchRange; + auto X86SimdMatch(uint8_t match_byte) const -> SimdMatchRange; #endif }; @@ -581,23 +581,23 @@ inline constexpr ssize_t GroupMask = MetadataGroup::Mask; inline auto MetadataGroup::Load(const uint8_t* metadata, ssize_t index) -> MetadataGroup { MetadataGroup portable_g; - if constexpr (!UseSIMD || DebugSIMD) { + if constexpr (!UseSimd || DebugSimd) { portable_g = PortableLoad(metadata, index); - if constexpr (!UseSIMD) { + if constexpr (!UseSimd) { return portable_g; } } - MetadataGroup g = SIMDLoad(metadata, index); + MetadataGroup g = SimdLoad(metadata, index); CARBON_DCHECK(g == portable_g); return g; } inline auto MetadataGroup::Store(uint8_t* metadata, ssize_t index) const -> void { - if constexpr (!UseSIMD) { + if constexpr (!UseSimd) { std::memcpy(metadata + index, &metadata_bytes, Size); } else { - SIMDStore(metadata, index); + SimdStore(metadata, index); } CARBON_DCHECK(0 == std::memcmp(metadata + index, &metadata_bytes, Size)); } @@ -615,17 +615,17 @@ inline auto MetadataGroup::ClearByte(ssize_t byte_index) -> void { inline auto MetadataGroup::ClearDeleted() -> void { MetadataGroup portable_g = *this; MetadataGroup simd_g = *this; - if constexpr (!UseSIMD || DebugSIMD) { + if constexpr (!UseSimd || DebugSimd) { portable_g.PortableClearDeleted(); } - if constexpr (UseSIMD || DebugSIMD) { - simd_g.SIMDClearDeleted(); + if constexpr (UseSimd || DebugSimd) { + simd_g.SimdClearDeleted(); CARBON_DCHECK( simd_g == portable_g, "SIMD cleared group '{0}' doesn't match portable cleared group '{1}'", simd_g, portable_g); } - *this = UseSIMD ? simd_g : portable_g; + *this = UseSimd ? simd_g : portable_g; } inline auto MetadataGroup::Match(uint8_t tag) const -> MatchRange { @@ -635,78 +635,78 @@ inline auto MetadataGroup::Match(uint8_t tag) const -> MatchRange { CARBON_DCHECK((tag & PresentMask) == 0, "{0:x}", tag); PortableMatchRange portable_result; - SIMDMatchRange simd_result; - if constexpr (!UseSIMD || DebugSIMD) { + SimdMatchRange simd_result; + if constexpr (!UseSimd || DebugSimd) { portable_result = PortableMatch(tag); } - if constexpr (UseSIMD || DebugSIMD) { - simd_result = SIMDMatch(tag); + if constexpr (UseSimd || DebugSimd) { + simd_result = SimdMatch(tag); CARBON_DCHECK(simd_result == portable_result, "SIMD result '{0}' doesn't match portable result '{1}'", simd_result, portable_result); } // Return whichever result we're using. - return ConstexprTernary(simd_result, portable_result); + return ConstexprTernary(simd_result, portable_result); } inline auto MetadataGroup::MatchPresent() const -> MatchPresentRange { PortableMatchRange portable_result; - SIMDMatchPresentRange simd_result; - if constexpr (!UseSIMD || DebugSIMD) { + SimdMatchPresentRange simd_result; + if constexpr (!UseSimd || DebugSimd) { portable_result = PortableMatchPresent(); } - if constexpr (UseSIMD || DebugSIMD) { - simd_result = SIMDMatchPresent(); + if constexpr (UseSimd || DebugSimd) { + simd_result = SimdMatchPresent(); CARBON_DCHECK(simd_result == portable_result, "SIMD result '{0}' doesn't match portable result '{1}'", simd_result, portable_result); } // Return whichever result we're using. - return ConstexprTernary(simd_result, portable_result); + return ConstexprTernary(simd_result, portable_result); } inline auto MetadataGroup::MatchEmpty() const -> MatchIndex { MatchIndex portable_result; MatchIndex simd_result; - if constexpr (!UseSIMD || DebugSIMD) { + if constexpr (!UseSimd || DebugSimd) { portable_result = PortableMatchEmpty(); } - if constexpr (UseSIMD || DebugSIMD) { - simd_result = SIMDMatchEmpty(); + if constexpr (UseSimd || DebugSimd) { + simd_result = SimdMatchEmpty(); CARBON_DCHECK(simd_result == portable_result, "SIMD result '{0}' doesn't match portable result '{1}'", simd_result, portable_result); } - return UseSIMD ? simd_result : portable_result; + return UseSimd ? simd_result : portable_result; } inline auto MetadataGroup::MatchDeleted() const -> MatchIndex { MatchIndex portable_result; MatchIndex simd_result; - if constexpr (!UseSIMD || DebugSIMD) { + if constexpr (!UseSimd || DebugSimd) { portable_result = PortableMatchDeleted(); } - if constexpr (UseSIMD || DebugSIMD) { - simd_result = SIMDMatchDeleted(); + if constexpr (UseSimd || DebugSimd) { + simd_result = SimdMatchDeleted(); CARBON_DCHECK(simd_result == portable_result, "SIMD result '{0}' doesn't match portable result '{1}'", simd_result, portable_result); } - return UseSIMD ? simd_result : portable_result; + return UseSimd ? simd_result : portable_result; } inline auto MetadataGroup::CompareEqual(MetadataGroup lhs, MetadataGroup rhs) -> bool { bool portable_result; bool simd_result; - if constexpr (!UseSIMD || DebugSIMD) { + if constexpr (!UseSimd || DebugSimd) { portable_result = PortableCompareEqual(lhs, rhs); } - if constexpr (UseSIMD || DebugSIMD) { - simd_result = SIMDCompareEqual(lhs, rhs); + if constexpr (UseSimd || DebugSimd) { + simd_result = SimdCompareEqual(lhs, rhs); CARBON_DCHECK(simd_result == portable_result); } - return UseSIMD ? simd_result : portable_result; + return UseSimd ? simd_result : portable_result; } inline auto MetadataGroup::VerifyIndexBits( @@ -798,10 +798,10 @@ inline auto MetadataGroup::PortableClearDeleted() -> void { // need to preserve are those of present bytes. The most significant bit of // every present byte is set, so we take the most significant bit of each // byte, shift it into the least significant bit position, and bit-or it - // with the compliment of `LSBs`. This will have ones for every bit but the + // with the compliment of `Lsbs`. This will have ones for every bit but the // least significant bits, and ones for the least significant bits of every // present byte. - metadata_int &= (~LSBs | metadata_int >> 7); + metadata_int &= (~Lsbs | metadata_int >> 7); } } @@ -834,13 +834,13 @@ inline auto MetadataGroup::PortableMatch(uint8_t tag) const -> MatchRange { // algorithm has a critical path height of 4 operations, and does 6 // operations total on AArch64. The operation dependency graph is: // - // group | MSBs LSBs * match_byte + MSBs + // group | Msbs Lsbs * match_byte + Msbs // \ / // match_bits ^ broadcast // | - // group & MSBs MSBs - match_bits + // group & Msbs Msbs - match_bits // \ / - // group_MSBs & match_bits + // group_Msbs & match_bits // // This diagram and the operation count are specific to AArch64 where we have // a fused *integer* multiply-add operation. @@ -856,13 +856,13 @@ inline auto MetadataGroup::PortableMatch(uint8_t tag) const -> MatchRange { // and so always has this bit set as well, which means the xor below, in // addition to zeroing the low 7 bits of any byte that matches the tag, also // clears the high bit of every byte. - uint64_t match_bits = metadata_ints[0] | MSBs; + uint64_t match_bits = metadata_ints[0] | Msbs; // Broadcast the match byte to all bytes, and mask in the present bits in the - // MSBs of each byte. We structure this as a multiply and an add because we + // Msbs of each byte. We structure this as a multiply and an add because we // know that the add cannot carry, and this way it can be lowered using // combined multiply-add instructions if available. - uint64_t broadcast = LSBs * tag + MSBs; - CARBON_DCHECK(broadcast == (LSBs * tag | MSBs), + uint64_t broadcast = Lsbs * tag + Msbs; + CARBON_DCHECK(broadcast == (Lsbs * tag | Msbs), "Unexpected carry from addition!"); // Xor the broadcast byte pattern. This makes bytes with matches become 0, and @@ -872,11 +872,11 @@ inline auto MetadataGroup::PortableMatch(uint8_t tag) const -> MatchRange { match_bits = match_bits ^ broadcast; // Subtract each byte of `match_bits` from `0x80` bytes. After this, the high // bit will be set only for those bytes that were zero. - match_bits = MSBs - match_bits; + match_bits = Msbs - match_bits; // Zero everything but the high bits, and also zero the high bits of any bytes // for "not present" slots in the original group. This avoids false positives // for `Empty` and `Deleted` bytes in the metadata. - match_bits &= (metadata_ints[0] & MSBs); + match_bits &= (metadata_ints[0] & Msbs); // At this point, `match_bits` has the high bit set for bytes where the // original group byte equals `tag` plus the high bit. @@ -905,7 +905,7 @@ inline auto MetadataGroup::PortableMatchPresent() const -> MatchRange { // Want to keep the high bit of each byte, which indicates whether that byte // represents a present slot. - uint64_t match_bits = metadata_ints[0] & MSBs; + uint64_t match_bits = metadata_ints[0] & Msbs; CARBON_DCHECK(VerifyPortableRangeBits( match_bits, [&](uint8_t byte) { return (byte & PresentMask) != 0; })); @@ -937,7 +937,7 @@ inline auto MetadataGroup::PortableMatchEmpty() const -> MatchIndex { // cause the high bit to be set. uint64_t match_bits = metadata_ints[0] | (metadata_ints[0] << 7); // This inverts the high bits of the bytes, and clears the remaining bits. - match_bits = ~match_bits & MSBs; + match_bits = ~match_bits & Msbs; // The high bits of the bytes of `match_bits` are set if the corresponding // metadata byte is `Empty`. @@ -971,7 +971,7 @@ inline auto MetadataGroup::PortableMatchDeleted() const -> MatchIndex { // shifting left by 7 will have the high bit set. uint64_t match_bits = metadata_ints[0] | (~metadata_ints[0] << 7); // This inverts the high bits of the bytes, and clears the remaining bits. - match_bits = ~match_bits & MSBs; + match_bits = ~match_bits & Msbs; // The high bits of the bytes of `match_bits` are set if the corresponding // metadata byte is `Deleted`. @@ -985,7 +985,7 @@ inline auto MetadataGroup::PortableCompareEqual(MetadataGroup lhs, return llvm::equal(lhs.metadata_bytes, rhs.metadata_bytes); } -inline auto MetadataGroup::SIMDLoad(const uint8_t* metadata, ssize_t index) +inline auto MetadataGroup::SimdLoad(const uint8_t* metadata, ssize_t index) -> MetadataGroup { MetadataGroup g; #if CARBON_NEON_SIMD_SUPPORT @@ -994,33 +994,33 @@ inline auto MetadataGroup::SIMDLoad(const uint8_t* metadata, ssize_t index) g.metadata_vec = _mm_load_si128(reinterpret_cast(metadata + index)); #else - static_assert(!UseSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd, "Unimplemented SIMD operation"); static_cast(metadata); static_cast(index); #endif return g; } -inline auto MetadataGroup::SIMDStore(uint8_t* metadata, ssize_t index) const +inline auto MetadataGroup::SimdStore(uint8_t* metadata, ssize_t index) const -> void { #if CARBON_NEON_SIMD_SUPPORT vst1_u8(metadata + index, metadata_vec); #elif CARBON_X86_SIMD_SUPPORT _mm_store_si128(reinterpret_cast<__m128i*>(metadata + index), metadata_vec); #else - static_assert(!UseSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd, "Unimplemented SIMD operation"); static_cast(metadata); static_cast(index); #endif } -inline auto MetadataGroup::SIMDClearDeleted() -> void { +inline auto MetadataGroup::SimdClearDeleted() -> void { #if CARBON_NEON_SIMD_SUPPORT // There is no good Neon operation to implement this, so do it using integer // code. This is reasonably fast, but unfortunate because it forces the group // out of a SIMD register and into a general purpose register, which can have // high latency. - metadata_ints[0] &= (~LSBs | metadata_ints[0] >> 7); + metadata_ints[0] &= (~Lsbs | metadata_ints[0] >> 7); #elif CARBON_X86_SIMD_SUPPORT // For each byte, use `metadata_vec` if the byte's high bit is set (indicating // it is present), otherwise (it is empty or deleted) replace it with zero @@ -1028,49 +1028,49 @@ inline auto MetadataGroup::SIMDClearDeleted() -> void { metadata_vec = _mm_blendv_epi8(_mm_setzero_si128(), metadata_vec, metadata_vec); #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); #endif } -inline auto MetadataGroup::SIMDMatch(uint8_t tag) const -> SIMDMatchRange { - SIMDMatchRange result; +inline auto MetadataGroup::SimdMatch(uint8_t tag) const -> SimdMatchRange { + SimdMatchRange result; #if CARBON_NEON_SIMD_SUPPORT // Broadcast byte we want to match to every byte in the vector. auto match_byte_vec = vdup_n_u8(tag | PresentMask); // Result bytes have all bits set for the bytes that match, so we have to - // clear everything but MSBs next. + // clear everything but Msbs next. auto match_byte_cmp_vec = vceq_u8(metadata_vec, match_byte_vec); uint64_t match_bits = vreinterpret_u64_u8(match_byte_cmp_vec)[0]; - // Note that the range will lazily mask to the MSBs as part of incrementing. - result = SIMDMatchRange(match_bits); + // Note that the range will lazily mask to the Msbs as part of incrementing. + result = SimdMatchRange(match_bits); #elif CARBON_X86_SIMD_SUPPORT - result = X86SIMDMatch(tag | PresentMask); + result = X86SimdMatch(tag | PresentMask); #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); static_cast(tag); #endif return result; } -inline auto MetadataGroup::SIMDMatchPresent() const -> SIMDMatchPresentRange { - SIMDMatchPresentRange result; +inline auto MetadataGroup::SimdMatchPresent() const -> SimdMatchPresentRange { + SimdMatchPresentRange result; #if CARBON_NEON_SIMD_SUPPORT // Just extract the metadata directly. uint64_t match_bits = vreinterpret_u64_u8(metadata_vec)[0]; // Even though the Neon SIMD range will do its own masking, we have to mask // here so that `empty` is correct. - result = SIMDMatchPresentRange(match_bits & MSBs); + result = SimdMatchPresentRange(match_bits & Msbs); #elif CARBON_X86_SIMD_SUPPORT // We arranged the byte vector so that present bytes have the high bit set, // which this instruction extracts. - result = SIMDMatchPresentRange(_mm_movemask_epi8(metadata_vec)); + result = SimdMatchPresentRange(_mm_movemask_epi8(metadata_vec)); #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); #endif return result; } -inline auto MetadataGroup::SIMDMatchEmpty() const -> MatchIndex { +inline auto MetadataGroup::SimdMatchEmpty() const -> MatchIndex { MatchIndex result; #if CARBON_NEON_SIMD_SUPPORT // Compare all bytes with zero, as that is the empty byte value. Result will @@ -1079,23 +1079,23 @@ inline auto MetadataGroup::SIMDMatchEmpty() const -> MatchIndex { auto cmp_vec = vceqz_u8(metadata_vec); uint64_t metadata_bits = vreinterpret_u64_u8(cmp_vec)[0]; // The matched range is likely to be tested for zero by the caller, and that - // test can often be folded into masking the bits with `MSBs` when we do that + // test can often be folded into masking the bits with `Msbs` when we do that // mask in the scalar domain rather than the SIMD domain. So we do the mask // here rather than above prior to extracting the match bits. - result = MatchIndex(metadata_bits & MSBs); + result = MatchIndex(metadata_bits & Msbs); #elif CARBON_X86_SIMD_SUPPORT // Even though we only need the first match rather than all matches, we don't // have a more efficient way to compute this on x86 and so we reuse the // general match infrastructure that computes all matches in a bit-encoding. // We then convert it into a `MatchIndex` that just finds the first one. - result = static_cast(X86SIMDMatch(Empty)); + result = static_cast(X86SimdMatch(Empty)); #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); #endif return result; } -inline auto MetadataGroup::SIMDMatchDeleted() const -> MatchIndex { +inline auto MetadataGroup::SimdMatchDeleted() const -> MatchIndex { MatchIndex result; #if CARBON_NEON_SIMD_SUPPORT // Broadcast the `Deleted` byte across the vector and compare the bytes of @@ -1104,23 +1104,23 @@ inline auto MetadataGroup::SIMDMatchDeleted() const -> MatchIndex { auto cmp_vec = vceq_u8(metadata_vec, vdup_n_u8(Deleted)); uint64_t match_bits = vreinterpret_u64_u8(cmp_vec)[0]; // The matched range is likely to be tested for zero by the caller, and that - // test can often be folded into masking the bits with `MSBs` when we do that + // test can often be folded into masking the bits with `Msbs` when we do that // mask in the scalar domain rather than the SIMD domain. So we do the mask // here rather than above prior to extracting the match bits. - result = MatchIndex(match_bits & MSBs); + result = MatchIndex(match_bits & Msbs); #elif CARBON_X86_SIMD_SUPPORT // Even though we only need the first match rather than all matches, we don't // have a more efficient way to compute this on x86 and so we reuse the // general match infrastructure that computes all matches in a bit-encoding. // We then convert it into a `MatchIndex` that just finds the first one. - result = static_cast(X86SIMDMatch(Deleted)); + result = static_cast(X86SimdMatch(Deleted)); #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); #endif return result; } -inline auto MetadataGroup::SIMDCompareEqual(MetadataGroup lhs, +inline auto MetadataGroup::SimdCompareEqual(MetadataGroup lhs, MetadataGroup rhs) -> bool { #if CARBON_NEON_SIMD_SUPPORT return vreinterpret_u64_u8(vceq_u8(lhs.metadata_vec, rhs.metadata_vec))[0] == @@ -1141,7 +1141,7 @@ inline auto MetadataGroup::SIMDCompareEqual(MetadataGroup lhs, rhs.metadata_vec)) == 0x0000'ffffU; #endif #else - static_assert(!UseSIMD && !DebugSIMD, "Unimplemented SIMD operation"); + static_assert(!UseSimd && !DebugSimd, "Unimplemented SIMD operation"); static_cast(lhs); static_cast(rhs); return false; @@ -1149,7 +1149,7 @@ inline auto MetadataGroup::SIMDCompareEqual(MetadataGroup lhs, } #if CARBON_X86_SIMD_SUPPORT -inline auto MetadataGroup::X86SIMDMatch(uint8_t match_byte) const +inline auto MetadataGroup::X86SimdMatch(uint8_t match_byte) const -> MatchRange { // Broadcast the byte we're matching against to all bytes in a vector, and // compare those bytes with the metadata vector bytes. diff --git a/common/raw_hashtable_metadata_group_benchmark.cpp b/common/raw_hashtable_metadata_group_benchmark.cpp index cb0522052941b..a6942992ef1f8 100644 --- a/common/raw_hashtable_metadata_group_benchmark.cpp +++ b/common/raw_hashtable_metadata_group_benchmark.cpp @@ -41,29 +41,29 @@ class BenchmarkPortableMetadataGroup : public MetadataGroup { }; // Override the core API with explicit use of the SIMD API. -class BenchmarkSIMDMetadataGroup : public MetadataGroup { +class BenchmarkSimdMetadataGroup : public MetadataGroup { public: - explicit BenchmarkSIMDMetadataGroup(MetadataGroup g) : MetadataGroup(g) {} + explicit BenchmarkSimdMetadataGroup(MetadataGroup g) : MetadataGroup(g) {} static auto Load(uint8_t* metadata, ssize_t index) - -> BenchmarkSIMDMetadataGroup { - return BenchmarkSIMDMetadataGroup(SIMDLoad(metadata, index)); + -> BenchmarkSimdMetadataGroup { + return BenchmarkSimdMetadataGroup(SimdLoad(metadata, index)); } auto Store(uint8_t* metadata, ssize_t index) const -> void { - SIMDStore(metadata, index); + SimdStore(metadata, index); } - auto ClearDeleted() -> void { SIMDClearDeleted(); } + auto ClearDeleted() -> void { SimdClearDeleted(); } - auto Match(uint8_t present_byte) const -> SIMDMatchRange { - return SIMDMatch(present_byte); + auto Match(uint8_t present_byte) const -> SimdMatchRange { + return SimdMatch(present_byte); } - auto MatchPresent() const -> SIMDMatchPresentRange { - return SIMDMatchPresent(); + auto MatchPresent() const -> SimdMatchPresentRange { + return SimdMatchPresent(); } - auto MatchEmpty() const -> MatchIndex { return SIMDMatchEmpty(); } - auto MatchDeleted() const -> MatchIndex { return SIMDMatchDeleted(); } + auto MatchEmpty() const -> MatchIndex { return SimdMatchEmpty(); } + auto MatchDeleted() const -> MatchIndex { return SimdMatchDeleted(); } }; #endif @@ -75,7 +75,7 @@ constexpr ssize_t BenchSize = 256; #if CARBON_NEON_SIMD_SUPPORT || CARBON_X86_SIMD_SUPPORT using PortableGroup = BenchmarkPortableMetadataGroup; -using SIMDGroup = BenchmarkSIMDMetadataGroup; +using SimdGroup = BenchmarkSimdMetadataGroup; #endif struct BenchMetadata { @@ -251,9 +251,9 @@ BENCHMARK(BM_LoadMatch); BENCHMARK(BM_LoadMatch); BENCHMARK(BM_LoadMatch); BENCHMARK(BM_LoadMatch); -BENCHMARK(BM_LoadMatch); -BENCHMARK(BM_LoadMatch); -BENCHMARK(BM_LoadMatch); +BENCHMARK(BM_LoadMatch); +BENCHMARK(BM_LoadMatch); +BENCHMARK(BM_LoadMatch); #endif // Benchmark that measures the speed of a match that is only found after at diff --git a/common/set_test.cpp b/common/set_test.cpp index 2de94b171ceaf..81ad810427cbb 100644 --- a/common/set_test.cpp +++ b/common/set_test.cpp @@ -95,7 +95,7 @@ TYPED_TEST(SetTest, Basic) { ExpectSetElementsAre(s, MakeElements(llvm::seq(1, 512))); } -TYPED_TEST(SetTest, FactoryAPI) { +TYPED_TEST(SetTest, FactoryApi) { using SetT = TypeParam; SetT s; EXPECT_TRUE(s.Insert(1, [](int k, void* key_storage) { diff --git a/docs/project/cpp_style_guide.md b/docs/project/cpp_style_guide.md index 13268f86c201d..02a9088f223b6 100644 --- a/docs/project/cpp_style_guide.md +++ b/docs/project/cpp_style_guide.md @@ -70,6 +70,12 @@ serves to simplify it. - All other names use `snake_case`, including function parameters, and non-constant local and member variables. - Private member variables should have a trailing `_`. +- For acronyms and initialisms, we generally follow the + [capitalization style](https://google.github.io/styleguide/cppguide.html#General_Naming_Rules) + (`Api` instead of `API`). + - The exceptions are `LLVM` and `IR`, which we capitalize. +- For abbreviations, there is a list of + [common toolchain abbreviations](/toolchain/docs/idioms.md#abbreviations-used-in-the-code-aka-carbon-abbreviation-decoder-ring). ### File names diff --git a/testing/base/source_gen.cpp b/testing/base/source_gen.cpp index 8db91c865f1a2..ba4af1ee820f6 100644 --- a/testing/base/source_gen.cpp +++ b/testing/base/source_gen.cpp @@ -309,7 +309,7 @@ static auto EstimateAvgClassDefLines(SourceGen::ClassParams params) -> double { return avg; } -auto SourceGen::GenAPIFileDenseDecls(int target_lines, +auto SourceGen::GenApiFileDenseDecls(int target_lines, const DenseDeclParams& params) -> std::string { RawStringOstream source; diff --git a/testing/base/source_gen.h b/testing/base/source_gen.h index ccd48693ff169..c7c7301c94e76 100644 --- a/testing/base/source_gen.h +++ b/testing/base/source_gen.h @@ -188,7 +188,7 @@ class SourceGen { // `target_lines`. Long term, the goal is to get as close as we can to any // automatically formatted code while still keeping the stability of // benchmarking. - auto GenAPIFileDenseDecls(int target_lines, const DenseDeclParams& params) + auto GenApiFileDenseDecls(int target_lines, const DenseDeclParams& params) -> std::string; // Get some number of randomly shuffled identifiers. diff --git a/testing/base/source_gen_main.cpp b/testing/base/source_gen_main.cpp index 9d657b3549b40..33b24cda3b8d3 100644 --- a/testing/base/source_gen_main.cpp +++ b/testing/base/source_gen_main.cpp @@ -95,7 +95,7 @@ auto Run(llvm::ArrayRef args) -> bool { } SourceGen gen(language); - *output << gen.GenAPIFileDenseDecls(lines, SourceGen::DenseDeclParams{}); + *output << gen.GenApiFileDenseDecls(lines, SourceGen::DenseDeclParams{}); output->flush(); return true; } diff --git a/testing/base/source_gen_test.cpp b/testing/base/source_gen_test.cpp index 85fda1d51da7c..dec0c2b0f10f6 100644 --- a/testing/base/source_gen_test.cpp +++ b/testing/base/source_gen_test.cpp @@ -157,11 +157,11 @@ auto TestCompile(llvm::StringRef source) -> bool { return driver.RunCommand({"compile", "--phase=check", "test.carbon"}).success; } -TEST(SourceGenTest, GenAPIFileDenseDeclsTest) { +TEST(SourceGenTest, GenApiFileDenseDeclsTest) { SourceGen gen; std::string source = - gen.GenAPIFileDenseDecls(1000, SourceGen::DenseDeclParams{}); + gen.GenApiFileDenseDecls(1000, SourceGen::DenseDeclParams{}); // Should be within 1% of the requested line count. EXPECT_THAT(source, Contains('\n').Times(AllOf(Ge(950), Le(1050)))); @@ -169,13 +169,13 @@ TEST(SourceGenTest, GenAPIFileDenseDeclsTest) { EXPECT_TRUE(TestCompile(source)); } -TEST(SourceGenTest, GenAPIFileDenseDeclsCppTest) { +TEST(SourceGenTest, GenApiFileDenseDeclsCppTest) { SourceGen gen(SourceGen::Language::Cpp); // Generate a 1000-line file which is enough to have a reasonably accurate // line count estimate and have a few classes. std::string source = - gen.GenAPIFileDenseDecls(1000, SourceGen::DenseDeclParams{}); + gen.GenApiFileDenseDecls(1000, SourceGen::DenseDeclParams{}); // Should be within 10% of the requested line count. EXPECT_THAT(source, Contains('\n').Times(AllOf(Ge(900), Le(1100)))); diff --git a/toolchain/diagnostics/coverage_test.cpp b/toolchain/diagnostics/coverage_test.cpp index 3791e398e7277..b1bde23d5dfd3 100644 --- a/toolchain/diagnostics/coverage_test.cpp +++ b/toolchain/diagnostics/coverage_test.cpp @@ -37,8 +37,8 @@ constexpr DiagnosticKind UntestedDiagnosticKinds[] = { // These aren't feasible to test with a normal testcase, but are tested in // lex/tokenized_buffer_test.cpp. DiagnosticKind::TooManyTokens, - DiagnosticKind::UnsupportedCRLineEnding, - DiagnosticKind::UnsupportedLFCRLineEnding, + DiagnosticKind::UnsupportedCrLineEnding, + DiagnosticKind::UnsupportedLfCrLineEnding, // This is a little long but is tested in lex/numeric_literal_test.cpp. DiagnosticKind::TooManyDigits, diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 6a8888df10984..84644d46c1fb8 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -64,8 +64,8 @@ CARBON_DIAGNOSTIC_KIND(UnicodeEscapeSurrogate) CARBON_DIAGNOSTIC_KIND(UnicodeEscapeTooLarge) CARBON_DIAGNOSTIC_KIND(UnknownBaseSpecifier) CARBON_DIAGNOSTIC_KIND(UnknownEscapeSequence) -CARBON_DIAGNOSTIC_KIND(UnsupportedCRLineEnding) -CARBON_DIAGNOSTIC_KIND(UnsupportedLFCRLineEnding) +CARBON_DIAGNOSTIC_KIND(UnsupportedCrLineEnding) +CARBON_DIAGNOSTIC_KIND(UnsupportedLfCrLineEnding) CARBON_DIAGNOSTIC_KIND(UnmatchedOpening) CARBON_DIAGNOSTIC_KIND(UnmatchedClosing) CARBON_DIAGNOSTIC_KIND(UnrecognizedCharacters) diff --git a/toolchain/docs/adding_features.md b/toolchain/docs/adding_features.md index be62da9fd2688..e3cae3d4211c1 100644 --- a/toolchain/docs/adding_features.md +++ b/toolchain/docs/adding_features.md @@ -332,7 +332,7 @@ Adding an instruction will generally also require a handler in the Lower step. Most new instructions will automatically be formatted reasonably by the SemIR formatter. If not, then add a `FormatInst` overload to [`sem_ir/formatter.cpp`](/toolchain/sem_ir/formatter.cpp). If only the arguments -need custom formatting, then a `FormatInstRHS` overload can be implemented +need custom formatting, then a `FormatInstRhs` overload can be implemented instead. If the resulting SemIR needs a new built-in, add it to diff --git a/toolchain/driver/compile_benchmark.cpp b/toolchain/driver/compile_benchmark.cpp index 337c57ae905a4..2d565b3f9c7fb 100644 --- a/toolchain/driver/compile_benchmark.cpp +++ b/toolchain/driver/compile_benchmark.cpp @@ -93,7 +93,7 @@ static auto ComputeFileCount(int target_lines) -> int { } template -static auto BM_CompileAPIFileDenseDecls(benchmark::State& state) -> void { +static auto BM_CompileApiFileDenseDecls(benchmark::State& state) -> void { CompileBenchmark bench; int target_lines = state.range(0); int num_files = ComputeFileCount(target_lines); @@ -106,7 +106,7 @@ static auto BM_CompileAPIFileDenseDecls(benchmark::State& state) -> void { double total_tokens = 0.0; double total_lines = 0.0; for (std::string& source : sources) { - source = bench.gen().GenAPIFileDenseDecls(target_lines, + source = bench.gen().GenApiFileDenseDecls(target_lines, SourceGen::DenseDeclParams{}); total_bytes += source.size(); total_tokens += compile_helper.GetTokenizedBuffer(source).size(); @@ -151,13 +151,13 @@ static auto BM_CompileAPIFileDenseDecls(benchmark::State& state) -> void { // Benchmark from 256-line test cases through 256k line test cases, and for each // phase of compilation. -BENCHMARK(BM_CompileAPIFileDenseDecls) +BENCHMARK(BM_CompileApiFileDenseDecls) ->RangeMultiplier(4) ->Range(256, static_cast(256 * 1024)); -BENCHMARK(BM_CompileAPIFileDenseDecls) +BENCHMARK(BM_CompileApiFileDenseDecls) ->RangeMultiplier(4) ->Range(256, static_cast(256 * 1024)); -BENCHMARK(BM_CompileAPIFileDenseDecls) +BENCHMARK(BM_CompileApiFileDenseDecls) ->RangeMultiplier(4) ->Range(256, static_cast(256 * 1024)); diff --git a/toolchain/lex/lex.cpp b/toolchain/lex/lex.cpp index e7e098750c594..587b3c135a3bc 100644 --- a/toolchain/lex/lex.cpp +++ b/toolchain/lex/lex.cpp @@ -230,23 +230,23 @@ class [[clang::internal_linkage]] Lexer { #if CARBON_USE_SIMD namespace { #if __ARM_NEON -using SIMDMaskT = uint8x16_t; +using SimdMaskT = uint8x16_t; #elif __x86_64__ -using SIMDMaskT = __m128i; +using SimdMaskT = __m128i; #else #error "Unsupported SIMD architecture!" #endif -using SIMDMaskArrayT = std::array; +using SimdMaskArrayT = std::array; } // namespace // A table of masks to include 0-16 bytes of an SSE register. -static constexpr SIMDMaskArrayT PrefixMasks = []() constexpr { - SIMDMaskArrayT masks = {}; +static constexpr SimdMaskArrayT PrefixMasks = []() constexpr { + SimdMaskArrayT masks = {}; for (int i = 1; i < static_cast(masks.size()); ++i) { masks[i] = // The SIMD types and constexpr require a C-style cast. // NOLINTNEXTLINE(google-readability-casting) - (SIMDMaskT)(std::numeric_limits::max() >> - ((sizeof(SIMDMaskT) - i) * 8)); + (SimdMaskT)(std::numeric_limits::max() >> + ((sizeof(SimdMaskT) - i) * 8)); } return masks; }(); @@ -829,17 +829,17 @@ auto Lexer::LexCR(llvm::StringRef source_text, ssize_t& position) -> void { return; } - CARBON_DIAGNOSTIC(UnsupportedLFCRLineEnding, Error, + CARBON_DIAGNOSTIC(UnsupportedLfCrLineEnding, Error, "the LF+CR line ending is not supported, only LF and CR+LF " "are supported"); - CARBON_DIAGNOSTIC(UnsupportedCRLineEnding, Error, + CARBON_DIAGNOSTIC(UnsupportedCrLineEnding, Error, "a raw CR line ending is not supported, only LF and CR+LF " "are supported"); bool is_lfcr = position > 0 && source_text[position - 1] == '\n'; // TODO: This diagnostic has an unfortunate snippet -- we should tweak the // snippet rendering to gracefully handle CRs. emitter_.Emit(source_text.begin() + position, - is_lfcr ? UnsupportedLFCRLineEnding : UnsupportedCRLineEnding); + is_lfcr ? UnsupportedLfCrLineEnding : UnsupportedCrLineEnding); // Recover by treating the CR as a horizontal whitespace. This should make our // whitespace rules largely work and parse cleanly without disrupting the line diff --git a/toolchain/lex/tokenized_buffer_test.cpp b/toolchain/lex/tokenized_buffer_test.cpp index 0a014d4c1861b..a2bfe2cb966c2 100644 --- a/toolchain/lex/tokenized_buffer_test.cpp +++ b/toolchain/lex/tokenized_buffer_test.cpp @@ -86,7 +86,7 @@ TEST_F(LexerTest, TracksLinesAndColumns) { })); } -TEST_F(LexerTest, TracksLinesAndColumnsCRLF) { +TEST_F(LexerTest, TracksLinesAndColumnsCrLf) { auto& buffer = compile_helper_.GetTokenizedBuffer( "\r\n ;;\r\n ;;;\r\n x\"foo\" '''baz\r\n a\r\n ''' y"); EXPECT_FALSE(buffer.has_errors()); @@ -146,7 +146,7 @@ TEST_F(LexerTest, InvalidCR) { })); } -TEST_F(LexerTest, InvalidLFCR) { +TEST_F(LexerTest, InvalidLfCr) { auto& buffer = compile_helper_.GetTokenizedBuffer("\n ;;\n\r ;\n x"); EXPECT_TRUE(buffer.has_errors()); EXPECT_THAT( @@ -1123,15 +1123,15 @@ TEST_F(LexerTest, DiagnosticInvalidDigit) { TEST_F(LexerTest, DiagnosticCR) { Testing::MockDiagnosticConsumer consumer; EXPECT_CALL(consumer, HandleDiagnostic(IsSingleDiagnostic( - DiagnosticKind::UnsupportedCRLineEnding, + DiagnosticKind::UnsupportedCrLineEnding, DiagnosticLevel::Error, 1, 1, _))); compile_helper_.GetTokenizedBuffer("\r", &consumer); } -TEST_F(LexerTest, DiagnosticLFCR) { +TEST_F(LexerTest, DiagnosticLfCr) { Testing::MockDiagnosticConsumer consumer; EXPECT_CALL(consumer, HandleDiagnostic(IsSingleDiagnostic( - DiagnosticKind::UnsupportedLFCRLineEnding, + DiagnosticKind::UnsupportedLfCrLineEnding, DiagnosticLevel::Error, 2, 1, _))); compile_helper_.GetTokenizedBuffer("\n\r", &consumer); } diff --git a/toolchain/parse/tree_test.cpp b/toolchain/parse/tree_test.cpp index c4ea99ca56aeb..d72dc6df82fdc 100644 --- a/toolchain/parse/tree_test.cpp +++ b/toolchain/parse/tree_test.cpp @@ -85,7 +85,7 @@ TEST_F(TreeTest, AsAndTryAs) { EXPECT_TRUE(*any_decl_id == any_decl_id2); } -TEST_F(TreeTest, PrintPostorderAsYAML) { +TEST_F(TreeTest, PrintPostorderAsYaml) { auto [tokens, tree_and_subtrees] = compile_helper_.GetTokenizedBufferWithTreeAndSubtrees("fn F();"); EXPECT_FALSE(tree_and_subtrees.tree().has_errors()); @@ -114,7 +114,7 @@ TEST_F(TreeTest, PrintPostorderAsYAML) { IsYaml(ElementsAre(root))); } -TEST_F(TreeTest, PrintPreorderAsYAML) { +TEST_F(TreeTest, PrintPreorderAsYaml) { auto [tokens, tree_and_subtrees] = compile_helper_.GetTokenizedBufferWithTreeAndSubtrees("fn F();"); EXPECT_FALSE(tree_and_subtrees.tree().has_errors()); diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 7c25a7e9dd10c..31439f4e1bf0e 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -754,13 +754,13 @@ class FormatterImpl { template auto FormatInst(InstId inst_id, InstT inst) -> void { Indent(); - FormatInstLHS(inst_id, inst); + FormatInstLhs(inst_id, inst); out_ << InstT::Kind.ir_name(); pending_constant_value_ = sem_ir_->constant_values().Get(inst_id); pending_constant_value_is_self_ = sem_ir_->constant_values().GetInstIdIfValid(pending_constant_value_) == inst_id; - FormatInstRHS(inst); + FormatInstRhs(inst); FormatPendingConstantValue(AddSpace::Before); out_ << "\n"; } @@ -768,9 +768,9 @@ class FormatterImpl { // Don't print a constant for ImportRefUnloaded. auto FormatInst(InstId inst_id, ImportRefUnloaded inst) -> void { Indent(); - FormatInstLHS(inst_id, inst); + FormatInstLhs(inst_id, inst); out_ << ImportRefUnloaded::Kind.ir_name(); - FormatInstRHS(inst); + FormatInstRhs(inst); out_ << "\n"; } @@ -835,7 +835,7 @@ class FormatterImpl { pending_constant_value_ = ConstantId::NotConstant; } - auto FormatInstLHS(InstId inst_id, Inst inst) -> void { + auto FormatInstLhs(InstId inst_id, Inst inst) -> void { switch (inst.kind().value_kind()) { case InstValueKind::Typed: FormatName(inst_id); @@ -863,26 +863,26 @@ class FormatterImpl { } // Format ImportCppDecl name. - auto FormatInstLHS(InstId inst_id, ImportCppDecl /*inst*/) -> void { + auto FormatInstLhs(InstId inst_id, ImportCppDecl /*inst*/) -> void { FormatName(inst_id); out_ << " = "; } // Format ImportDecl with its name. - auto FormatInstLHS(InstId inst_id, ImportDecl /*inst*/) -> void { + auto FormatInstLhs(InstId inst_id, ImportDecl /*inst*/) -> void { FormatName(inst_id); out_ << " = "; } // Print ImportRefUnloaded with type-like semantics even though it lacks a // type_id. - auto FormatInstLHS(InstId inst_id, ImportRefUnloaded /*inst*/) -> void { + auto FormatInstLhs(InstId inst_id, ImportRefUnloaded /*inst*/) -> void { FormatName(inst_id); out_ << " = "; } template - auto FormatInstRHS(InstT inst) -> void { + auto FormatInstRhs(InstT inst) -> void { // By default, an instruction has a comma-separated argument list. using Info = Internal::InstLikeTypeInfo; if constexpr (Info::NumArgs == 2) { @@ -904,7 +904,7 @@ class FormatterImpl { } } - auto FormatInstRHS(BindSymbolicName inst) -> void { + auto FormatInstRhs(BindSymbolicName inst) -> void { // A BindSymbolicName with no value is a purely symbolic binding, such as // the `Self` in an interface. Don't print out `none` for the value. if (inst.value_id.has_value()) { @@ -914,12 +914,12 @@ class FormatterImpl { } } - auto FormatInstRHS(BlockArg inst) -> void { + auto FormatInstRhs(BlockArg inst) -> void { out_ << " "; FormatLabel(inst.block_id); } - auto FormatInstRHS(Namespace inst) -> void { + auto FormatInstRhs(Namespace inst) -> void { if (inst.import_id.has_value()) { FormatArgs(inst.import_id, inst.name_scope_id); } else { @@ -961,7 +961,7 @@ class FormatterImpl { in_terminator_sequence_ = false; } - auto FormatInstRHS(Call inst) -> void { + auto FormatInstRhs(Call inst) -> void { out_ << " "; FormatArg(inst.callee_id); @@ -997,56 +997,56 @@ class FormatterImpl { } } - auto FormatInstRHS(ArrayInit inst) -> void { + auto FormatInstRhs(ArrayInit inst) -> void { FormatArgs(inst.inits_id); FormatReturnSlotArg(inst.dest_id); } - auto FormatInstRHS(InitializeFrom inst) -> void { + auto FormatInstRhs(InitializeFrom inst) -> void { FormatArgs(inst.src_id); FormatReturnSlotArg(inst.dest_id); } - auto FormatInstRHS(ValueParam inst) -> void { + auto FormatInstRhs(ValueParam inst) -> void { FormatArgs(inst.runtime_index); // Omit pretty_name because it's an implementation detail of // pretty-printing. } - auto FormatInstRHS(OutParam inst) -> void { + auto FormatInstRhs(OutParam inst) -> void { FormatArgs(inst.runtime_index); // Omit pretty_name because it's an implementation detail of // pretty-printing. } - auto FormatInstRHS(ReturnExpr ret) -> void { + auto FormatInstRhs(ReturnExpr ret) -> void { FormatArgs(ret.expr_id); if (ret.dest_id.has_value()) { FormatReturnSlotArg(ret.dest_id); } } - auto FormatInstRHS(ReturnSlot inst) -> void { + auto FormatInstRhs(ReturnSlot inst) -> void { // Omit inst.type_inst_id because it's not semantically significant. FormatArgs(inst.storage_id); } - auto FormatInstRHS(ReturnSlotPattern /*inst*/) -> void { + auto FormatInstRhs(ReturnSlotPattern /*inst*/) -> void { // No-op because type_id is the only semantically significant field, // and it's handled separately. } - auto FormatInstRHS(StructInit init) -> void { + auto FormatInstRhs(StructInit init) -> void { FormatArgs(init.elements_id); FormatReturnSlotArg(init.dest_id); } - auto FormatInstRHS(TupleInit init) -> void { + auto FormatInstRhs(TupleInit init) -> void { FormatArgs(init.elements_id); FormatReturnSlotArg(init.dest_id); } - auto FormatInstRHS(FunctionDecl inst) -> void { + auto FormatInstRhs(FunctionDecl inst) -> void { FormatArgs(inst.function_id); llvm::SaveAndRestore class_scope( scope_, inst_namer_->GetScopeFor(inst.function_id)); @@ -1055,7 +1055,7 @@ class FormatterImpl { FormatTrailingBlock(inst.decl_block_id); } - auto FormatInstRHS(ClassDecl inst) -> void { + auto FormatInstRhs(ClassDecl inst) -> void { FormatArgs(inst.class_id); llvm::SaveAndRestore class_scope(scope_, inst_namer_->GetScopeFor(inst.class_id)); @@ -1063,7 +1063,7 @@ class FormatterImpl { FormatTrailingBlock(inst.decl_block_id); } - auto FormatInstRHS(ImplDecl inst) -> void { + auto FormatInstRhs(ImplDecl inst) -> void { FormatArgs(inst.impl_id); llvm::SaveAndRestore class_scope(scope_, inst_namer_->GetScopeFor(inst.impl_id)); @@ -1071,7 +1071,7 @@ class FormatterImpl { FormatTrailingBlock(inst.decl_block_id); } - auto FormatInstRHS(InterfaceDecl inst) -> void { + auto FormatInstRhs(InterfaceDecl inst) -> void { FormatArgs(inst.interface_id); llvm::SaveAndRestore class_scope( scope_, inst_namer_->GetScopeFor(inst.interface_id)); @@ -1080,28 +1080,28 @@ class FormatterImpl { FormatTrailingBlock(inst.decl_block_id); } - auto FormatInstRHS(AssociatedConstantDecl inst) -> void { + auto FormatInstRhs(AssociatedConstantDecl inst) -> void { FormatArgs(inst.assoc_const_id); llvm::SaveAndRestore assoc_const_scope( scope_, inst_namer_->GetScopeFor(inst.assoc_const_id)); FormatTrailingBlock(inst.decl_block_id); } - auto FormatInstRHS(IntValue inst) -> void { + auto FormatInstRhs(IntValue inst) -> void { out_ << " "; sem_ir_->ints() .Get(inst.int_id) .print(out_, sem_ir_->types().IsSignedInt(inst.type_id)); } - auto FormatInstRHS(FloatLiteral inst) -> void { + auto FormatInstRhs(FloatLiteral inst) -> void { llvm::SmallVector buffer; sem_ir_->floats().Get(inst.float_id).toString(buffer); out_ << " " << buffer; } // Format the metadata in File for `import Cpp`. - auto FormatInstRHS(ImportCppDecl /*inst*/) -> void { + auto FormatInstRhs(ImportCppDecl /*inst*/) -> void { out_ << " "; OpenBrace(); for (ImportCpp import_cpp : sem_ir_->import_cpps().array_ref()) { @@ -1114,7 +1114,7 @@ class FormatterImpl { CloseBrace(); } - auto FormatImportRefRHS(ImportIRInstId import_ir_inst_id, + auto FormatImportRefRhs(ImportIRInstId import_ir_inst_id, EntityNameId entity_name_id, llvm::StringLiteral loaded_label) -> void { out_ << " "; @@ -1148,29 +1148,29 @@ class FormatterImpl { out_ << ", " << loaded_label; } - auto FormatInstRHS(ImportRefLoaded inst) -> void { - FormatImportRefRHS(inst.import_ir_inst_id, inst.entity_name_id, "loaded"); + auto FormatInstRhs(ImportRefLoaded inst) -> void { + FormatImportRefRhs(inst.import_ir_inst_id, inst.entity_name_id, "loaded"); } - auto FormatInstRHS(ImportRefUnloaded inst) -> void { - FormatImportRefRHS(inst.import_ir_inst_id, inst.entity_name_id, "unloaded"); + auto FormatInstRhs(ImportRefUnloaded inst) -> void { + FormatImportRefRhs(inst.import_ir_inst_id, inst.entity_name_id, "unloaded"); } - auto FormatInstRHS(NameBindingDecl inst) -> void { + auto FormatInstRhs(NameBindingDecl inst) -> void { FormatTrailingBlock(inst.pattern_block_id); } - auto FormatInstRHS(SpliceBlock inst) -> void { + auto FormatInstRhs(SpliceBlock inst) -> void { FormatArgs(inst.result_id); FormatTrailingBlock(inst.block_id); } - auto FormatInstRHS(WhereExpr inst) -> void { + auto FormatInstRhs(WhereExpr inst) -> void { FormatArgs(inst.period_self_id); FormatTrailingBlock(inst.requirements_id); } - auto FormatInstRHS(StructType inst) -> void { + auto FormatInstRhs(StructType inst) -> void { out_ << " {"; llvm::ListSeparator sep; for (auto field : sem_ir_->struct_type_fields().Get(inst.fields_id)) { diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index 544bac9e50411..aae6315928e64 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -29,7 +29,7 @@ using ::testing::SizeIs; namespace Yaml = ::Carbon::Testing::Yaml; -TEST(SemIRTest, YAML) { +TEST(SemIRTest, Yaml) { llvm::IntrusiveRefCntPtr fs = new llvm::vfs::InMemoryFileSystem; CARBON_CHECK(fs->addFile( From f97f1a3e11f0717ded8a0f9e5148f1316ba706c7 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 27 Feb 2025 09:01:29 -0800 Subject: [PATCH 35/56] Add error for virtual member function without self (#5005) This tripped over a lowering crash when a member function with self was declared-but-not-defined, so that's why some test cases were updated to have (empty) function definitions. I'll follow-up with/look into a fix for the self-declared-but-not-defined cases separately. --------- Co-authored-by: Jon Ross-Perkins Co-authored-by: Carbon Infra Bot --- toolchain/check/function.cpp | 4 +- toolchain/check/function.h | 24 +- toolchain/check/handle_class.cpp | 3 +- toolchain/check/handle_function.cpp | 5 + toolchain/check/handle_impl.cpp | 3 +- toolchain/check/impl.cpp | 4 +- toolchain/check/merge.cpp | 78 +-- toolchain/check/merge.h | 17 +- .../class/adapter/fail_adapt_with_base.carbon | 17 +- .../testdata/class/fail_modifiers.carbon | 53 +- .../testdata/class/virtual_modifiers.carbon | 559 +++++++++++++++--- toolchain/diagnostics/diagnostic_kind.def | 1 + toolchain/lower/testdata/class/virtual.carbon | 73 ++- 13 files changed, 648 insertions(+), 193 deletions(-) diff --git a/toolchain/check/function.cpp b/toolchain/check/function.cpp index 901e4e8fd9475..2d6468301d7db 100644 --- a/toolchain/check/function.cpp +++ b/toolchain/check/function.cpp @@ -14,7 +14,7 @@ auto CheckFunctionTypeMatches(Context& context, const SemIR::Function& new_function, const SemIR::Function& prev_function, SemIR::SpecificId prev_specific_id, - bool check_syntax) -> bool { + bool check_syntax, bool check_self) -> bool { // TODO: When check_syntax is false, the functions should be allowed to have // different signatures as long as we can synthesize a suitable thunk. i.e., // when there's an implicit conversion from the original parameter types to @@ -23,7 +23,7 @@ auto CheckFunctionTypeMatches(Context& context, // Also, build that thunk. if (!CheckRedeclParamsMatch(context, DeclParams(new_function), DeclParams(prev_function), prev_specific_id, - check_syntax)) { + /*diagnose=*/true, check_syntax, check_self)) { return false; } diff --git a/toolchain/check/function.h b/toolchain/check/function.h index 346c3cb6749b5..fe697675b8bc0 100644 --- a/toolchain/check/function.h +++ b/toolchain/check/function.h @@ -29,11 +29,25 @@ struct SuspendedFunction { // Checks that `new_function` has the same parameter types and return type as // `prev_function`, or if `prev_function_id` is specified, a specific version of // `prev_function`. Prints a suitable diagnostic and returns false if not. -auto CheckFunctionTypeMatches( - Context& context, const SemIR::Function& new_function, - const SemIR::Function& prev_function, - SemIR::SpecificId prev_specific_id = SemIR::SpecificId::None, - bool check_syntax = true) -> bool; +// +// `check_syntax` is false if the redeclaration can be called via a thunk with +// implicit conversions from the original declaration. +// `check_self` is false if the self declaration does not have to match (for +// instance in impls of virtual functions). +auto CheckFunctionTypeMatches(Context& context, + const SemIR::Function& new_function, + const SemIR::Function& prev_function, + SemIR::SpecificId prev_specific_id, + bool check_syntax, bool check_self) -> bool; + +inline auto CheckFunctionTypeMatches(Context& context, + const SemIR::Function& new_function, + const SemIR::Function& prev_function) + -> bool { + return CheckFunctionTypeMatches(context, new_function, prev_function, + SemIR::SpecificId::None, + /*check_syntax=*/true, /*check_self=*/true); +} // Checks that the return type of the specified function is complete, issuing an // error if not. This computes the return slot usage for the function if diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index 7716ecb7eba9e..486329c72a2a9 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -736,7 +736,8 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id, // `SpecificId::None`. CheckFunctionTypeMatches(context, override_fn, fn, SemIR::SpecificId::None, - /*check_syntax=*/false); + /*check_syntax=*/false, + /*check_self=*/false); fn_decl_id = override_fn_decl_id; } } diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index a8caf9da9e567..3cec9eedec7fe 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -278,6 +278,11 @@ static auto BuildFunctionDecl(Context& context, self_param_id = *i; } + if (virtual_modifier != SemIR::Function::VirtualModifier::None && + !self_param_id.has_value()) { + CARBON_DIAGNOSTIC(VirtualWithoutSelf, Error, "virtual class function"); + context.emitter().Build(node_id, VirtualWithoutSelf).Emit(); + } // Build the function entity. This will be merged into an existing function if // there is one, or otherwise added to the function store. auto function_info = diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 8fecb950ca75c..606b272601405 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -254,7 +254,8 @@ static auto MergeImplRedecl(Context& context, SemIR::Impl& new_impl, // `impl`. Keep looking for a prior declaration without issuing a diagnostic. if (!CheckRedeclParamsMatch(context, DeclParams(new_impl), DeclParams(prev_impl), SemIR::SpecificId::None, - /*check_syntax=*/true, /*diagnose=*/false)) { + /*diagnose=*/false, /*check_syntax=*/true, + /*check_self=*/true)) { // NOLINTNEXTLINE(readability-simplify-boolean-expr) return false; } diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index aec86c4058b93..c257231b740b0 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -72,8 +72,8 @@ static auto CheckAssociatedFunctionImplementation( if (!CheckFunctionTypeMatches( context, context.functions().Get(impl_function_decl->function_id), context.functions().Get(interface_function_type.function_id), - interface_function_specific_id, - /*check_syntax=*/false)) { + interface_function_specific_id, /*check_syntax=*/false, + /*check_self=*/true)) { return SemIR::ErrorInst::SingletonInstId; } return impl_decl_id; diff --git a/toolchain/check/merge.cpp b/toolchain/check/merge.cpp index 82481ad3464a1..04cde311d1e4b 100644 --- a/toolchain/check/merge.cpp +++ b/toolchain/check/merge.cpp @@ -201,8 +201,8 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param, int32_t param_index, SemIR::InstId new_param_pattern_id, SemIR::InstId prev_param_pattern_id, - SemIR::SpecificId prev_specific_id, bool diagnose) - -> bool { + SemIR::SpecificId prev_specific_id, bool diagnose, + bool check_self) -> bool { // TODO: Consider differentiating between type and name mistakes. For now, // taking the simpler approach because I also think we may want to refactor // params. @@ -231,25 +231,6 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param, return false; } - auto prev_param_type_id = SemIR::GetTypeInSpecific( - context.sem_ir(), prev_specific_id, prev_param_pattern.type_id()); - if (!context.types().AreEqualAcrossDeclarations(new_param_pattern.type_id(), - prev_param_type_id)) { - if (!diagnose) { - return false; - } - CARBON_DIAGNOSTIC(RedeclParamDiffersType, Error, - "type {3} of {0:implicit |}parameter {1} in " - "redeclaration differs from previous parameter type {2}", - BoolAsSelect, int32_t, SemIR::TypeId, SemIR::TypeId); - context.emitter() - .Build(new_param_pattern_id, RedeclParamDiffersType, is_implicit_param, - param_index + 1, prev_param_type_id, new_param_pattern.type_id()) - .Note(prev_param_pattern_id, RedeclParamPrevious, is_implicit_param) - .Emit(); - return false; - } - if (new_param_pattern.Is()) { new_param_pattern = context.insts().Get( new_param_pattern.As().inner_id); @@ -270,11 +251,40 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param, return false; } - auto new_entity_name = context.entity_names().Get( - new_param_pattern.As().entity_name_id); - auto prev_entity_name = context.entity_names().Get( - prev_param_pattern.As().entity_name_id); - if (new_entity_name.name_id != prev_entity_name.name_id) { + auto new_name_id = + context.entity_names() + .Get(new_param_pattern.As().entity_name_id) + .name_id; + auto prev_name_id = + context.entity_names() + .Get(prev_param_pattern.As().entity_name_id) + .name_id; + + if (!check_self && new_name_id == SemIR::NameId::SelfValue && + prev_name_id == SemIR::NameId::SelfValue) { + return true; + } + + auto prev_param_type_id = SemIR::GetTypeInSpecific( + context.sem_ir(), prev_specific_id, prev_param_pattern.type_id()); + if (!context.types().AreEqualAcrossDeclarations(new_param_pattern.type_id(), + prev_param_type_id)) { + if (!diagnose) { + return false; + } + CARBON_DIAGNOSTIC(RedeclParamDiffersType, Error, + "type {3} of {0:implicit |}parameter {1} in " + "redeclaration differs from previous parameter type {2}", + BoolAsSelect, int32_t, SemIR::TypeId, SemIR::TypeId); + context.emitter() + .Build(new_param_pattern_id, RedeclParamDiffersType, is_implicit_param, + param_index + 1, prev_param_type_id, new_param_pattern.type_id()) + .Note(prev_param_pattern_id, RedeclParamPrevious, is_implicit_param) + .Emit(); + return false; + } + + if (new_name_id != prev_name_id) { emit_diagnostic(); return false; } @@ -288,8 +298,8 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc, SemIRLoc prev_decl_loc, SemIR::InstBlockId prev_param_patterns_id, bool is_implicit_param, - SemIR::SpecificId prev_specific_id, bool diagnose) - -> bool { + SemIR::SpecificId prev_specific_id, bool diagnose, + bool check_self) -> bool { // This will often occur for empty params. if (new_param_patterns_id == prev_param_patterns_id) { return true; @@ -347,7 +357,7 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc, llvm::enumerate(new_param_pattern_ids, prev_param_pattern_ids)) { if (!CheckRedeclParam(context, is_implicit_param, index, new_param_pattern_id, prev_param_pattern_id, - prev_specific_id, diagnose)) { + prev_specific_id, diagnose, check_self)) { return false; } } @@ -458,8 +468,8 @@ static auto CheckRedeclParamSyntax(Context& context, auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, const DeclParams& prev_entity, - SemIR::SpecificId prev_specific_id, - bool check_syntax, bool diagnose) -> bool { + SemIR::SpecificId prev_specific_id, bool diagnose, + bool check_syntax, bool check_self) -> bool { if (EntityHasParamError(context, new_entity) || EntityHasParamError(context, prev_entity)) { return false; @@ -467,13 +477,15 @@ auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, if (!CheckRedeclParams( context, new_entity.loc, new_entity.implicit_param_patterns_id, prev_entity.loc, prev_entity.implicit_param_patterns_id, - /*is_implicit_param=*/true, prev_specific_id, diagnose)) { + /*is_implicit_param=*/true, prev_specific_id, diagnose, check_self)) { return false; } + // Don't forward `check_self` here because it's extra cost, and `self` is only + // allowed in implicit params. if (!CheckRedeclParams(context, new_entity.loc, new_entity.param_patterns_id, prev_entity.loc, prev_entity.param_patterns_id, /*is_implicit_param=*/false, prev_specific_id, - diagnose)) { + diagnose, /*check_self=*/true)) { return false; } if (check_syntax && diff --git a/toolchain/check/merge.h b/toolchain/check/merge.h index 677eafe1acebe..fe659c7a8fc8d 100644 --- a/toolchain/check/merge.h +++ b/toolchain/check/merge.h @@ -96,11 +96,18 @@ struct DeclParams { // Checks that the parameters in a redeclaration of an entity match the // parameters in the prior declaration. If not, produces a diagnostic if // `diagnose` is true, and returns false. -auto CheckRedeclParamsMatch( - Context& context, const DeclParams& new_entity, - const DeclParams& prev_entity, - SemIR::SpecificId prev_specific_id = SemIR::SpecificId::None, - bool check_syntax = true, bool diagnose = true) -> bool; +auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, + const DeclParams& prev_entity, + SemIR::SpecificId prev_specific_id, bool diagnose, + bool check_syntax, bool check_self) -> bool; + +inline auto CheckRedeclParamsMatch(Context& context, + const DeclParams& new_entity, + const DeclParams& prev_entity) -> bool { + return CheckRedeclParamsMatch(context, new_entity, prev_entity, + SemIR::SpecificId::None, /*diagnose=*/true, + /*check_syntax=*/true, /*check_self=*/true); +} } // namespace Carbon::Check diff --git a/toolchain/check/testdata/class/adapter/fail_adapt_with_base.carbon b/toolchain/check/testdata/class/adapter/fail_adapt_with_base.carbon index 5352d64562d5b..356f2acd9e596 100644 --- a/toolchain/check/testdata/class/adapter/fail_adapt_with_base.carbon +++ b/toolchain/check/testdata/class/adapter/fail_adapt_with_base.carbon @@ -9,13 +9,13 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/adapter/fail_adapt_with_base.carbon class Simple {}; base class AdaptWithVirtual { - virtual fn F(); + virtual fn F[self: Self](); // CHECK:STDERR: fail_adapt_with_base.carbon:[[@LINE+7]]:3: error: adapter with virtual function [AdaptWithVirtual] // CHECK:STDERR: adapt Simple; // CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: fail_adapt_with_base.carbon:[[@LINE-4]]:3: note: first virtual function declaration is here [AdaptWithVirtualHere] - // CHECK:STDERR: virtual fn F(); - // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: virtual fn F[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: adapt Simple; } @@ -58,7 +58,14 @@ base class AdaptWithVirtual { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @AdaptWithVirtual { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %self.patt: %AdaptWithVirtual = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %AdaptWithVirtual = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %AdaptWithVirtual = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptWithVirtual [concrete = constants.%AdaptWithVirtual] +// CHECK:STDOUT: %self: %AdaptWithVirtual = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %Simple.ref: type = name_ref Simple, file.%Simple.decl [concrete = constants.%Simple] // CHECK:STDOUT: adapt_decl %Simple.ref [concrete] // CHECK:STDOUT: complete_type_witness = @@ -69,5 +76,5 @@ base class AdaptWithVirtual { // CHECK:STDOUT: .Simple = // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F(); +// CHECK:STDOUT: virtual fn @F[%self.param_patt: %AdaptWithVirtual](); // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_modifiers.carbon b/toolchain/check/testdata/class/fail_modifiers.carbon index 63c56a07c6432..68c6589b4b438 100644 --- a/toolchain/check/testdata/class/fail_modifiers.carbon +++ b/toolchain/check/testdata/class/fail_modifiers.carbon @@ -83,18 +83,18 @@ abstract protected class WrongOrder { } abstract base class AbstractAndBase {} abstract class AbstractWithDefinition { - // CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:19: error: definition of `abstract` function [DefinedAbstractFunction] - // CHECK:STDERR: abstract fn F() {} - // CHECK:STDERR: ^ + // CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:31: error: definition of `abstract` function [DefinedAbstractFunction] + // CHECK:STDERR: abstract fn F[self: Self]() {} + // CHECK:STDERR: ^ // CHECK:STDERR: - abstract fn F() {} - abstract fn G(); + abstract fn F[self: Self]() {} + abstract fn G[self: Self](); } -// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:31: error: definition of `abstract` function [DefinedAbstractFunction] -// CHECK:STDERR: fn AbstractWithDefinition.G() { -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:43: error: definition of `abstract` function [DefinedAbstractFunction] +// CHECK:STDERR: fn AbstractWithDefinition.G[self: Self]() { +// CHECK:STDERR: ^ // CHECK:STDERR: -fn AbstractWithDefinition.G() { +fn AbstractWithDefinition.G[self: Self]() { } // CHECK:STDOUT: --- fail_modifiers.carbon @@ -115,9 +115,9 @@ fn AbstractWithDefinition.G() { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %.9a5: = vtable (%F, %G) [concrete] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -151,7 +151,14 @@ fn AbstractWithDefinition.G() { // CHECK:STDOUT: %WrongOrder.decl: type = class_decl @WrongOrder [concrete = constants.%WrongOrder] {} {} // CHECK:STDOUT: %AbstractAndBase.decl: type = class_decl @AbstractAndBase [concrete = constants.%AbstractAndBase] {} {} // CHECK:STDOUT: %AbstractWithDefinition.decl: type = class_decl @AbstractWithDefinition [concrete = constants.%AbstractWithDefinition] {} {} -// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { +// CHECK:STDOUT: %self.patt: %AbstractWithDefinition = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %AbstractWithDefinition = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc97: %AbstractWithDefinition = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref.loc97: type = name_ref Self, constants.%AbstractWithDefinition [concrete = constants.%AbstractWithDefinition] +// CHECK:STDOUT: %self.loc97: %AbstractWithDefinition = bind_name self, %self.param.loc97 +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @DuplicatePrivate; @@ -195,8 +202,22 @@ fn AbstractWithDefinition.G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @AbstractWithDefinition { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %self.patt: %AbstractWithDefinition = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %AbstractWithDefinition = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %AbstractWithDefinition = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AbstractWithDefinition [concrete = constants.%AbstractWithDefinition] +// CHECK:STDOUT: %self: %AbstractWithDefinition = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { +// CHECK:STDOUT: %self.patt: %AbstractWithDefinition = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %AbstractWithDefinition = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc91: %AbstractWithDefinition = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref.loc91: type = name_ref Self, constants.%AbstractWithDefinition [concrete = constants.%AbstractWithDefinition] +// CHECK:STDOUT: %self.loc91: %AbstractWithDefinition = bind_name self, %self.param.loc91 +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc92: = vtable (%F.decl, %G.decl) [concrete = constants.%.9a5] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -207,12 +228,12 @@ fn AbstractWithDefinition.G() { // CHECK:STDOUT: .G = %G.decl // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: abstract fn @F() { +// CHECK:STDOUT: abstract fn @F[%self.param_patt: %AbstractWithDefinition]() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: abstract fn @G() { +// CHECK:STDOUT: abstract fn @G[%self.param_patt: %AbstractWithDefinition]() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index a5183db06bf14..65d7e28d79873 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -13,13 +13,13 @@ package Modifiers; base class Base { - virtual fn H(); + virtual fn H[self: Self](); } abstract class Abstract { - abstract fn J(); + abstract fn J[self: Self](); - virtual fn K(); + virtual fn K[self: Self](); } // --- override_import.carbon @@ -30,7 +30,7 @@ import Modifiers; class Derived { extend base: Modifiers.Base; - impl fn H(); + impl fn H[self: Self](); } // --- todo_fail_later_base.carbon @@ -40,7 +40,7 @@ library "[[@TEST_NAME]]"; import Modifiers; base class Derived { - virtual fn F(); + virtual fn F[self: Self](); extend base: Modifiers.Base; } @@ -59,12 +59,12 @@ fn F() { library "[[@TEST_NAME]]"; abstract class A1 { - virtual fn F(); + virtual fn F[self: Self](); } abstract class A2 { extend base: A1; - impl fn F(); + impl fn F[self: Self](); } // --- impl_base.carbon @@ -72,17 +72,17 @@ abstract class A2 { library "[[@TEST_NAME]]"; base class B1 { - virtual fn F(); + virtual fn F[self: Self](); } base class B2 { extend base: B1; - impl fn F(); + impl fn F[self: Self](); } class C { extend base: B2; - impl fn F(); + impl fn F[self: Self](); } // --- fail_modifiers.carbon @@ -91,10 +91,10 @@ library "[[@TEST_NAME]]"; class C { // CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:3: error: impl without base class [ImplWithoutBase] - // CHECK:STDERR: impl fn F(); - // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: impl fn F[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - impl fn F(); + impl fn F[self: Self](); } // --- init_members.carbon @@ -105,7 +105,7 @@ base class Base { var m1: i32; var m2: i32; - virtual fn F(); + virtual fn F[self: Self](); } fn F() { @@ -127,7 +127,7 @@ base class Base { class Derived { extend base: Base; - impl fn F(); + impl fn F[self: Self](); } // --- abstract_impl.carbon @@ -135,7 +135,7 @@ class Derived { library "[[@TEST_NAME]]"; abstract class AbstractBase { - abstract fn F(); + abstract fn F[self: Self](); } abstract class AbstractIntermediate { @@ -144,7 +144,7 @@ abstract class AbstractIntermediate { class Derived { extend base: AbstractIntermediate; - impl fn F(); + impl fn F[self: Self](); } // --- virtual_impl.carbon @@ -152,7 +152,7 @@ class Derived { library "[[@TEST_NAME]]"; base class VirtualBase { - virtual fn F(); + virtual fn F[self: Self](); } base class VirtualIntermediate { @@ -161,7 +161,7 @@ base class VirtualIntermediate { class Derived { extend base: VirtualIntermediate; - impl fn F(); + impl fn F[self: Self](); } // --- fail_impl_mismatch.carbon @@ -169,19 +169,19 @@ class Derived { library "[[@TEST_NAME]]"; base class Base { - virtual fn F(); + virtual fn F[self: Self](); } class Derived { extend base: Base; // CHECK:STDERR: fail_impl_mismatch.carbon:[[@LINE+7]]:3: error: redeclaration differs because of parameter count of 1 [RedeclParamCountDiffers] - // CHECK:STDERR: impl fn F(v: i32); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: impl fn F[self: Self](v: i32); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_mismatch.carbon:[[@LINE-8]]:3: note: previously declared with parameter count of 0 [RedeclParamCountPrevious] - // CHECK:STDERR: virtual fn F(); - // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: virtual fn F[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - impl fn F(v: i32); + impl fn F[self: Self](v: i32); } // --- fail_todo_impl_conversion.carbon @@ -201,19 +201,19 @@ impl T2 as Core.ImplicitAs(T1) { } base class Base { - virtual fn F() -> T1; + virtual fn F[self: Self]() -> T1; } class Derived { extend base: Base; // CHECK:STDERR: fail_todo_impl_conversion.carbon:[[@LINE+7]]:3: error: function redeclaration differs because return type is `T2` [FunctionRedeclReturnTypeDiffers] - // CHECK:STDERR: impl fn F() -> T2; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: impl fn F[self: Self]() -> T2; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_todo_impl_conversion.carbon:[[@LINE-8]]:3: note: previously declared with return type `T1` [FunctionRedeclReturnTypePrevious] - // CHECK:STDERR: virtual fn F() -> T1; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: virtual fn F[self: Self]() -> T1; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - impl fn F() -> T2; + impl fn F[self: Self]() -> T2; } // --- fail_todo_impl_generic_base.carbon @@ -224,19 +224,65 @@ class T1 { } base class Base(T:! type) { - virtual fn F(t: T); + virtual fn F[self: Self](t: T); } class Derived { extend base: Base(T1); - // CHECK:STDERR: fail_todo_impl_generic_base.carbon:[[@LINE+7]]:13: error: type `T1` of parameter 1 in redeclaration differs from previous parameter type `T` [RedeclParamDiffersType] - // CHECK:STDERR: impl fn F(t: T1); - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_todo_impl_generic_base.carbon:[[@LINE-8]]:16: note: previous declaration's corresponding parameter here [RedeclParamPrevious] - // CHECK:STDERR: virtual fn F(t: T); - // CHECK:STDERR: ^~~~ + // CHECK:STDERR: fail_todo_impl_generic_base.carbon:[[@LINE+7]]:25: error: type `T1` of parameter 1 in redeclaration differs from previous parameter type `T` [RedeclParamDiffersType] + // CHECK:STDERR: impl fn F[self: Self](t: T1); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: fail_todo_impl_generic_base.carbon:[[@LINE-8]]:28: note: previous declaration's corresponding parameter here [RedeclParamPrevious] + // CHECK:STDERR: virtual fn F[self: Self](t: T); + // CHECK:STDERR: ^~~~ // CHECK:STDERR: - impl fn F(t: T1); + impl fn F[self: Self](t: T1); +} + +// --- fail_virtual_without_self.carbon + +library "[[@TEST_NAME]]"; + +abstract class T1 { + // CHECK:STDERR: fail_virtual_without_self.carbon:[[@LINE+4]]:3: error: virtual class function [VirtualWithoutSelf] + // CHECK:STDERR: virtual fn F(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: + virtual fn F(); + // CHECK:STDERR: fail_virtual_without_self.carbon:[[@LINE+4]]:3: error: virtual class function [VirtualWithoutSelf] + // CHECK:STDERR: abstract fn G(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: + abstract fn G(); +} + +class T2 { + extend base: T1; + // CHECK:STDERR: fail_virtual_without_self.carbon:[[@LINE+4]]:3: error: virtual class function [VirtualWithoutSelf] + // CHECK:STDERR: impl fn F(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + impl fn F(); +} + +// --- fail_addr_self_mismatch.carbon + +library "[[@TEST_NAME]]"; + +base class T1 { + virtual fn F1[self: Self*](); +} + +class T2 { + extend base: T1; + // CHECK:STDERR: fail_addr_self_mismatch.carbon:[[@LINE+7]]:14: error: redeclaration differs at implicit parameter 1 [RedeclParamDiffers] + // CHECK:STDERR: impl fn F1[addr self: Self*](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_addr_self_mismatch.carbon:[[@LINE-8]]:17: note: previous declaration's corresponding implicit parameter here [RedeclParamPrevious] + // CHECK:STDERR: virtual fn F1[self: Self*](); + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: + impl fn F1[addr self: Self*](); } // CHECK:STDOUT: --- modifiers.carbon @@ -276,7 +322,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Base { -// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [concrete = constants.%H] {} {} +// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [concrete = constants.%H] { +// CHECK:STDOUT: %self.patt: %Base = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Base = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Base = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %Base = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%H.decl) [concrete = constants.%.c3d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -287,8 +340,22 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { -// CHECK:STDOUT: %J.decl: %J.type = fn_decl @J [concrete = constants.%J] {} {} -// CHECK:STDOUT: %K.decl: %K.type = fn_decl @K [concrete = constants.%K] {} {} +// CHECK:STDOUT: %J.decl: %J.type = fn_decl @J [concrete = constants.%J] { +// CHECK:STDOUT: %self.patt: %Abstract = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Abstract = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Abstract = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %Abstract = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %K.decl: %K.type = fn_decl @K [concrete = constants.%K] { +// CHECK:STDOUT: %self.patt: %Abstract = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Abstract = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Abstract = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %Abstract = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc12: = vtable (%J.decl, %K.decl) [concrete = constants.%.2b2] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -299,11 +366,11 @@ class Derived { // CHECK:STDOUT: .K = %K.decl // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @H(); +// CHECK:STDOUT: virtual fn @H[%self.param_patt: %Base](); // CHECK:STDOUT: -// CHECK:STDOUT: abstract fn @J(); +// CHECK:STDOUT: abstract fn @J[%self.param_patt: %Abstract](); // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @K(); +// CHECK:STDOUT: virtual fn @K[%self.param_patt: %Abstract](); // CHECK:STDOUT: // CHECK:STDOUT: --- override_import.carbon // CHECK:STDOUT: @@ -333,7 +400,7 @@ class Derived { // CHECK:STDOUT: %Modifiers.Base: type = import_ref Modifiers//default, Base, loaded [concrete = constants.%Base] // CHECK:STDOUT: %Modifiers.import_ref.05e: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type.513] // CHECK:STDOUT: %Modifiers.import_ref.1f3 = import_ref Modifiers//default, inst16 [no loc], unloaded -// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_17, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_29, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -351,7 +418,14 @@ class Derived { // CHECK:STDOUT: %Modifiers.ref: = name_ref Modifiers, imports.%Modifiers [concrete = imports.%Modifiers] // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Modifiers.Base [concrete = constants.%Base] // CHECK:STDOUT: %.loc7: %Derived.elem = base_decl %Base.ref, element0 [concrete] -// CHECK:STDOUT: %H.decl: %H.type.dba = fn_decl @H.1 [concrete = constants.%H.bce] {} {} +// CHECK:STDOUT: %H.decl: %H.type.dba = fn_decl @H.1 [concrete = constants.%H.bce] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc9: = vtable (%H.decl) [concrete = constants.%.dce] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.0e2] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -372,9 +446,9 @@ class Derived { // CHECK:STDOUT: .H = imports.%Modifiers.import_ref.2cc // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @H.1(); +// CHECK:STDOUT: impl fn @H.1[%self.param_patt: %Derived](); // CHECK:STDOUT: -// CHECK:STDOUT: fn @H.2() [from "modifiers.carbon"]; +// CHECK:STDOUT: fn @H.2[%self.param_patt: %Base]() [from "modifiers.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: --- todo_fail_later_base.carbon // CHECK:STDOUT: @@ -406,7 +480,7 @@ class Derived { // CHECK:STDOUT: %Modifiers.Base: type = import_ref Modifiers//default, Base, loaded [concrete = constants.%Base] // CHECK:STDOUT: %Modifiers.import_ref.05e: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type.513] // CHECK:STDOUT: %Modifiers.import_ref.1f3 = import_ref Modifiers//default, inst16 [no loc], unloaded -// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_17, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_29, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -421,7 +495,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Derived { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %Modifiers.ref: = name_ref Modifiers, imports.%Modifiers [concrete = imports.%Modifiers] // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Modifiers.Base [concrete = constants.%Base] // CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Base.ref, element0 [concrete] @@ -445,9 +526,9 @@ class Derived { // CHECK:STDOUT: .H = imports.%Modifiers.import_ref.2cc // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F(); +// CHECK:STDOUT: virtual fn @F[%self.param_patt: %Derived](); // CHECK:STDOUT: -// CHECK:STDOUT: fn @H() [from "modifiers.carbon"]; +// CHECK:STDOUT: fn @H[%self.param_patt: %Base]() [from "modifiers.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: --- init.carbon // CHECK:STDOUT: @@ -473,7 +554,7 @@ class Derived { // CHECK:STDOUT: %Modifiers.Base: type = import_ref Modifiers//default, Base, loaded [concrete = constants.%Base] // CHECK:STDOUT: %Modifiers.import_ref.05e: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Modifiers.import_ref.1f3 = import_ref Modifiers//default, inst16 [no loc], unloaded -// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_17, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_29, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -555,7 +636,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @A1 { -// CHECK:STDOUT: %F.decl: %F.type.13a = fn_decl @F.1 [concrete = constants.%F.df5] {} {} +// CHECK:STDOUT: %F.decl: %F.type.13a = fn_decl @F.1 [concrete = constants.%F.df5] { +// CHECK:STDOUT: %self.patt: %A1 = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %A1 = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %A1 = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A1 [concrete = constants.%A1] +// CHECK:STDOUT: %self: %A1 = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%F.decl) [concrete = constants.%.593] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -568,7 +656,14 @@ class Derived { // CHECK:STDOUT: class @A2 { // CHECK:STDOUT: %A1.ref: type = name_ref A1, file.%A1.decl [concrete = constants.%A1] // CHECK:STDOUT: %.loc9: %A2.elem = base_decl %A1.ref, element0 [concrete] -// CHECK:STDOUT: %F.decl: %F.type.4ae = fn_decl @F.2 [concrete = constants.%F.1d5] {} {} +// CHECK:STDOUT: %F.decl: %F.type.4ae = fn_decl @F.2 [concrete = constants.%F.1d5] { +// CHECK:STDOUT: %self.patt: %A2 = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %A2 = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %A2 = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A2 [concrete = constants.%A2] +// CHECK:STDOUT: %self: %A2 = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc11: = vtable (%F.decl) [concrete = constants.%.943] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.a6f] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -581,9 +676,9 @@ class Derived { // CHECK:STDOUT: extend %A1.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %A1](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %A2](); // CHECK:STDOUT: // CHECK:STDOUT: --- impl_base.carbon // CHECK:STDOUT: @@ -632,7 +727,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B1 { -// CHECK:STDOUT: %F.decl: %F.type.e4c = fn_decl @F.1 [concrete = constants.%F.8f5] {} {} +// CHECK:STDOUT: %F.decl: %F.type.e4c = fn_decl @F.1 [concrete = constants.%F.8f5] { +// CHECK:STDOUT: %self.patt: %B1 = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %B1 = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %B1 = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B1 [concrete = constants.%B1] +// CHECK:STDOUT: %self: %B1 = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%F.decl) [concrete = constants.%.bc5] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -645,7 +747,14 @@ class Derived { // CHECK:STDOUT: class @B2 { // CHECK:STDOUT: %B1.ref: type = name_ref B1, file.%B1.decl [concrete = constants.%B1] // CHECK:STDOUT: %.loc9: %B2.elem = base_decl %B1.ref, element0 [concrete] -// CHECK:STDOUT: %F.decl: %F.type.b26 = fn_decl @F.2 [concrete = constants.%F.d48] {} {} +// CHECK:STDOUT: %F.decl: %F.type.b26 = fn_decl @F.2 [concrete = constants.%F.d48] { +// CHECK:STDOUT: %self.patt: %B2 = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %B2 = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %B2 = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B2 [concrete = constants.%B2] +// CHECK:STDOUT: %self: %B2 = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc11: = vtable (%F.decl) [concrete = constants.%.579] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.508 [concrete = constants.%complete_type.5ac] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -661,7 +770,14 @@ class Derived { // CHECK:STDOUT: class @C { // CHECK:STDOUT: %B2.ref: type = name_ref B2, file.%B2.decl [concrete = constants.%B2] // CHECK:STDOUT: %.loc14: %C.elem = base_decl %B2.ref, element0 [concrete] -// CHECK:STDOUT: %F.decl: %F.type.c29 = fn_decl @F.3 [concrete = constants.%F.437] {} {} +// CHECK:STDOUT: %F.decl: %F.type.c29 = fn_decl @F.3 [concrete = constants.%F.437] { +// CHECK:STDOUT: %self.patt: %C = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %C = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %C = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc16: = vtable (%F.decl) [concrete = constants.%.5f6] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.421 [concrete = constants.%complete_type.066] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -674,11 +790,11 @@ class Derived { // CHECK:STDOUT: extend %B2.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %B1](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %B2](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.3(); +// CHECK:STDOUT: impl fn @F.3[%self.param_patt: %C](); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_modifiers.carbon // CHECK:STDOUT: @@ -709,7 +825,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %self.patt: %C = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %C = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %C = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %C = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc10: = vtable () [concrete = constants.%.f2b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -719,7 +842,7 @@ class Derived { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F(); +// CHECK:STDOUT: impl fn @F[%self.param_patt: %C](); // CHECK:STDOUT: // CHECK:STDOUT: --- init_members.carbon // CHECK:STDOUT: @@ -790,7 +913,14 @@ class Derived { // CHECK:STDOUT: %.loc6_3: %Base.elem = var_pattern %.loc6_9 // CHECK:STDOUT: } // CHECK:STDOUT: %.var.loc6: ref %Base.elem = var -// CHECK:STDOUT: %F.decl: %F.type.7c6 = fn_decl @F.1 [concrete = constants.%F.d17] {} {} +// CHECK:STDOUT: %F.decl: %F.type.7c6 = fn_decl @F.1 [concrete = constants.%F.d17] { +// CHECK:STDOUT: %self.patt: %Base = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Base = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Base = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %Base = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc9: = vtable (%F.decl) [concrete = constants.%.5ee] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr.m1.m2 [concrete = constants.%complete_type.cf7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -802,7 +932,7 @@ class Derived { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %Base](); // CHECK:STDOUT: // CHECK:STDOUT: fn @F.2() { // CHECK:STDOUT: !entry: @@ -933,7 +1063,14 @@ class Derived { // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Base.ref, element1 [concrete] -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc10: = vtable () [concrete = constants.%.f2b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr.base [concrete = constants.%complete_type.336] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -946,7 +1083,7 @@ class Derived { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F(); +// CHECK:STDOUT: impl fn @F[%self.param_patt: %Derived](); // CHECK:STDOUT: // CHECK:STDOUT: --- abstract_impl.carbon // CHECK:STDOUT: @@ -992,7 +1129,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @AbstractBase { -// CHECK:STDOUT: %F.decl: %F.type.85b = fn_decl @F.1 [concrete = constants.%F.6e9] {} {} +// CHECK:STDOUT: %F.decl: %F.type.85b = fn_decl @F.1 [concrete = constants.%F.6e9] { +// CHECK:STDOUT: %self.patt: %AbstractBase = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %AbstractBase = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %AbstractBase = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AbstractBase [concrete = constants.%AbstractBase] +// CHECK:STDOUT: %self: %AbstractBase = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%F.decl) [concrete = constants.%.6ec] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1019,7 +1163,14 @@ class Derived { // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %AbstractIntermediate.ref: type = name_ref AbstractIntermediate, file.%AbstractIntermediate.decl [concrete = constants.%AbstractIntermediate] // CHECK:STDOUT: %.loc13: %Derived.elem = base_decl %AbstractIntermediate.ref, element0 [concrete] -// CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] {} {} +// CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc15: = vtable (%F.decl) [concrete = constants.%.88d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.da5 [concrete = constants.%complete_type.f8c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1032,9 +1183,9 @@ class Derived { // CHECK:STDOUT: extend %AbstractIntermediate.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: abstract fn @F.1(); +// CHECK:STDOUT: abstract fn @F.1[%self.param_patt: %AbstractBase](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %Derived](); // CHECK:STDOUT: // CHECK:STDOUT: --- virtual_impl.carbon // CHECK:STDOUT: @@ -1080,7 +1231,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @VirtualBase { -// CHECK:STDOUT: %F.decl: %F.type.e62 = fn_decl @F.1 [concrete = constants.%F.3e7] {} {} +// CHECK:STDOUT: %F.decl: %F.type.e62 = fn_decl @F.1 [concrete = constants.%F.3e7] { +// CHECK:STDOUT: %self.patt: %VirtualBase = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %VirtualBase = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %VirtualBase = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%VirtualBase [concrete = constants.%VirtualBase] +// CHECK:STDOUT: %self: %VirtualBase = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%F.decl) [concrete = constants.%.def] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1107,7 +1265,14 @@ class Derived { // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %VirtualIntermediate.ref: type = name_ref VirtualIntermediate, file.%VirtualIntermediate.decl [concrete = constants.%VirtualIntermediate] // CHECK:STDOUT: %.loc13: %Derived.elem = base_decl %VirtualIntermediate.ref, element0 [concrete] -// CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] {} {} +// CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc15: = vtable (%F.decl) [concrete = constants.%.88d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.43c [concrete = constants.%complete_type.fa6] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1120,9 +1285,9 @@ class Derived { // CHECK:STDOUT: extend %VirtualIntermediate.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %VirtualBase](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %Derived](); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_impl_mismatch.carbon // CHECK:STDOUT: @@ -1165,7 +1330,14 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Base { -// CHECK:STDOUT: %F.decl: %F.type.7c6 = fn_decl @F.1 [concrete = constants.%F.d17] {} {} +// CHECK:STDOUT: %F.decl: %F.type.7c6 = fn_decl @F.1 [concrete = constants.%F.d17] { +// CHECK:STDOUT: %self.patt: %Base = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Base = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %Base = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %Base = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: %.loc6: = vtable (%F.decl) [concrete = constants.%.5ee] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1179,10 +1351,15 @@ class Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc9: %Derived.elem = base_decl %Base.ref, element0 [concrete] // CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %v.patt: %i32 = binding_pattern v -// CHECK:STDOUT: %v.param_patt: %i32 = value_param_pattern %v.patt, runtime_param0 +// CHECK:STDOUT: %v.param_patt: %i32 = value_param_pattern %v.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %v.param: %i32 = value_param runtime_param0 +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: %v.param: %i32 = value_param runtime_param1 // CHECK:STDOUT: %.loc17: type = splice_block %i32 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -1201,9 +1378,9 @@ class Derived { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %Base](); // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(%v.param_patt: %i32); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %Derived](%v.param_patt: %i32); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_impl_conversion.carbon // CHECK:STDOUT: @@ -1306,11 +1483,16 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %F.decl: %F.type.7c6 = fn_decl @F.1 [concrete = constants.%F.d17] { +// CHECK:STDOUT: %self.patt: %Base = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Base = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %return.patt: %T1 = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %T1 = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: %return.param_patt: %T1 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] -// CHECK:STDOUT: %return.param: ref %T1 = out_param runtime_param0 +// CHECK:STDOUT: %self.param: %Base = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %Base = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref %T1 = out_param runtime_param1 // CHECK:STDOUT: %return: ref %T1 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %.loc18: = vtable (%F.decl) [concrete = constants.%.5ee] @@ -1328,11 +1510,16 @@ class Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc21: %Derived.elem = base_decl %Base.ref, element0 [concrete] // CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %return.patt: %T2 = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %T2 = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: %return.param_patt: %T2 = out_param_pattern %return.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %T2.ref: type = name_ref T2, file.%T2.decl [concrete = constants.%T2] -// CHECK:STDOUT: %return.param: ref %T2 = out_param runtime_param0 +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref %T2 = out_param runtime_param1 // CHECK:STDOUT: %return: ref %T2 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %.loc30: = vtable (%F.decl) [concrete = constants.%.88d] @@ -1356,9 +1543,9 @@ class Derived { // CHECK:STDOUT: return %.loc12_14 to %return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn @F.1() -> %T1; +// CHECK:STDOUT: virtual fn @F.1[%self.param_patt: %Base]() -> %T1; // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2() -> %T2; +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %Derived]() -> %T2; // CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_impl_generic_base.carbon // CHECK:STDOUT: @@ -1435,10 +1622,18 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %F.decl: @Base.%F.type (%F.type.f17) = fn_decl @F.1 [symbolic = @Base.%F (constants.%F.e26)] { +// CHECK:STDOUT: %self.patt: @F.1.%Base (%Base.370) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @F.1.%Base (%Base.370) = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %t.patt: @F.1.%T (%T) = binding_pattern t -// CHECK:STDOUT: %t.param_patt: @F.1.%T (%T) = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: %t.param_patt: @F.1.%T (%T) = value_param_pattern %t.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %t.param: @F.1.%T (%T) = value_param runtime_param0 +// CHECK:STDOUT: %self.param: @F.1.%Base (%Base.370) = value_param runtime_param0 +// CHECK:STDOUT: %.loc8_22.1: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc8_22.2: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_22.2 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @F.1.%Base (%Base.370) = bind_name self, %self.param +// CHECK:STDOUT: %t.param: @F.1.%T (%T) = value_param runtime_param1 // CHECK:STDOUT: %T.ref: type = name_ref T, @Base.%T.loc7_17.1 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @F.1.%T (%T) = bind_name t, %t.param // CHECK:STDOUT: } @@ -1460,10 +1655,15 @@ class Derived { // CHECK:STDOUT: %Base: type = class_type @Base, @Base(constants.%T1) [concrete = constants.%Base.ea5] // CHECK:STDOUT: %.loc12: %Derived.elem = base_decl %Base, element0 [concrete] // CHECK:STDOUT: %F.decl: %F.type.5da = fn_decl @F.2 [concrete = constants.%F.fa3] { +// CHECK:STDOUT: %self.patt: %Derived = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %Derived = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %t.patt: %T1 = binding_pattern t -// CHECK:STDOUT: %t.param_patt: %T1 = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: %t.param_patt: %T1 = value_param_pattern %t.patt, runtime_param1 // CHECK:STDOUT: } { -// CHECK:STDOUT: %t.param: %T1 = value_param runtime_param0 +// CHECK:STDOUT: %self.param: %Derived = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %Derived = bind_name self, %self.param +// CHECK:STDOUT: %t.param: %T1 = value_param runtime_param1 // CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] // CHECK:STDOUT: %t: %T1 = bind_name t, %t.param // CHECK:STDOUT: } @@ -1482,11 +1682,12 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: generic virtual fn @F.1(@Base.%T.loc7_17.1: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] // CHECK:STDOUT: -// CHECK:STDOUT: virtual fn(%t.param_patt: @F.1.%T (%T)); +// CHECK:STDOUT: virtual fn[%self.param_patt: @F.1.%Base (%Base.370)](%t.param_patt: @F.1.%T (%T)); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl fn @F.2(%t.param_patt: %T1); +// CHECK:STDOUT: impl fn @F.2[%self.param_patt: %Derived](%t.param_patt: %T1); // CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc7_17.2 => constants.%T @@ -1495,8 +1696,11 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: specific @F.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base(@F.1.%T) {} +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(%T.loc7_17.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T1) { @@ -1509,3 +1713,168 @@ class Derived { // CHECK:STDOUT: %.loc9_1.2 => constants.%.611 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- fail_virtual_without_self.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T1: type = class_type @T1 [concrete] +// CHECK:STDOUT: %F.type.ba7: type = fn_type @F.1 [concrete] +// CHECK:STDOUT: %F.1a5: %F.type.ba7 = struct_value () [concrete] +// CHECK:STDOUT: %G.type: type = fn_type @G [concrete] +// CHECK:STDOUT: %G: %G.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] +// CHECK:STDOUT: %.e62: = vtable (%F.1a5, %G) [concrete] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] +// CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] +// CHECK:STDOUT: %T2: type = class_type @T2 [concrete] +// CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1 [concrete] +// CHECK:STDOUT: %F.type.834: type = fn_type @F.2 [concrete] +// CHECK:STDOUT: %F.a48: %F.type.834 = struct_value () [concrete] +// CHECK:STDOUT: %.025: = vtable (%F.a48, %G) [concrete] +// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete] +// CHECK:STDOUT: %complete_type.e14: = complete_type_witness %struct_type.base [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .T1 = %T1.decl +// CHECK:STDOUT: .T2 = %T2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %T1.decl: type = class_decl @T1 [concrete = constants.%T1] {} {} +// CHECK:STDOUT: %T2.decl: type = class_decl @T2 [concrete = constants.%T2] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T1 { +// CHECK:STDOUT: %F.decl: %F.type.ba7 = fn_decl @F.1 [concrete = constants.%F.1a5] {} {} +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} +// CHECK:STDOUT: %.loc15: = vtable (%F.decl, %G.decl) [concrete = constants.%.e62] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T1 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T2 { +// CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] +// CHECK:STDOUT: %.loc18: %T2.elem = base_decl %T1.ref, element0 [concrete] +// CHECK:STDOUT: %F.decl: %F.type.834 = fn_decl @F.2 [concrete = constants.%F.a48] {} {} +// CHECK:STDOUT: %.loc24: = vtable (%F.decl, constants.%G) [concrete = constants.%.025] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.e14] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T2 +// CHECK:STDOUT: .T1 = +// CHECK:STDOUT: .base = %.loc18 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: extend %T1.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: virtual fn @F.1(); +// CHECK:STDOUT: +// CHECK:STDOUT: abstract fn @G(); +// CHECK:STDOUT: +// CHECK:STDOUT: impl fn @F.2(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_addr_self_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T1: type = class_type @T1 [concrete] +// CHECK:STDOUT: %ptr.87b: type = ptr_type %T1 [concrete] +// CHECK:STDOUT: %F1.type.b96: type = fn_type @F1.1 [concrete] +// CHECK:STDOUT: %F1.765: %F1.type.b96 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] +// CHECK:STDOUT: %.278: = vtable (%F1.765) [concrete] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] +// CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] +// CHECK:STDOUT: %T2: type = class_type @T2 [concrete] +// CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1 [concrete] +// CHECK:STDOUT: %ptr.63e: type = ptr_type %T2 [concrete] +// CHECK:STDOUT: %F1.type.b0d: type = fn_type @F1.2 [concrete] +// CHECK:STDOUT: %F1.0ce: %F1.type.b0d = struct_value () [concrete] +// CHECK:STDOUT: %.20a: = vtable (%F1.0ce) [concrete] +// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete] +// CHECK:STDOUT: %complete_type.e14: = complete_type_witness %struct_type.base [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .T1 = %T1.decl +// CHECK:STDOUT: .T2 = %T2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %T1.decl: type = class_decl @T1 [concrete = constants.%T1] {} {} +// CHECK:STDOUT: %T2.decl: type = class_decl @T2 [concrete = constants.%T2] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T1 { +// CHECK:STDOUT: %F1.decl: %F1.type.b96 = fn_decl @F1.1 [concrete = constants.%F1.765] { +// CHECK:STDOUT: %self.patt: %ptr.87b = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %ptr.87b = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param runtime_param0 +// CHECK:STDOUT: %.loc5: type = splice_block %ptr [concrete = constants.%ptr.87b] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [concrete = constants.%ptr.87b] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc6: = vtable (%F1.decl) [concrete = constants.%.278] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T1 +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T2 { +// CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] +// CHECK:STDOUT: %.loc9: %T2.elem = base_decl %T1.ref, element0 [concrete] +// CHECK:STDOUT: %F1.decl: %F1.type.b0d = fn_decl @F1.2 [concrete = constants.%F1.0ce] { +// CHECK:STDOUT: %self.patt: %ptr.63e = binding_pattern self +// CHECK:STDOUT: %self.param_patt: %ptr.63e = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %.loc17_14: auto = addr_pattern %self.param_patt +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.63e = value_param runtime_param0 +// CHECK:STDOUT: %.loc17_29: type = splice_block %ptr [concrete = constants.%ptr.63e] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2] +// CHECK:STDOUT: %ptr: type = ptr_type %T2 [concrete = constants.%ptr.63e] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.63e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc18: = vtable (%F1.decl) [concrete = constants.%.20a] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.e14] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T2 +// CHECK:STDOUT: .T1 = +// CHECK:STDOUT: .base = %.loc9 +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: extend %T1.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: virtual fn @F1.1[%self.param_patt: %ptr.87b](); +// CHECK:STDOUT: +// CHECK:STDOUT: impl fn @F1.2[addr %self.param_patt: %ptr.63e](); +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 84644d46c1fb8..b895f9dcf11a8 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -256,6 +256,7 @@ CARBON_DIAGNOSTIC_KIND(ClassSpecificDeclPrevious) CARBON_DIAGNOSTIC_KIND(ClassIncompleteWithinDefinition) CARBON_DIAGNOSTIC_KIND(ExpectedSymbolicBindingInFieldDecl) CARBON_DIAGNOSTIC_KIND(ImplWithoutBase) +CARBON_DIAGNOSTIC_KIND(VirtualWithoutSelf) // Deduction. CARBON_DIAGNOSTIC_KIND(DeductionIncomplete) diff --git a/toolchain/lower/testdata/class/virtual.carbon b/toolchain/lower/testdata/class/virtual.carbon index b2c00f14e9052..978f0645fdd23 100644 --- a/toolchain/lower/testdata/class/virtual.carbon +++ b/toolchain/lower/testdata/class/virtual.carbon @@ -17,12 +17,12 @@ base class Base { base class Intermediate { extend base: Base; - virtual fn Fn(); + virtual fn Fn[self: Self]() { } } class Derived { extend base: Intermediate; - impl fn Fn(); + impl fn Fn[self: Self]() { } } // --- create.carbon @@ -47,7 +47,7 @@ package MemberInit; base class Base { var m: i32; - virtual fn Fn(); + virtual fn Fn[self: Self]() { } } fn Fn() { @@ -62,9 +62,15 @@ fn Fn() { // CHECK:STDOUT: ; ModuleID = 'classes.carbon' // CHECK:STDOUT: source_filename = "classes.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CFn.Intermediate.Classes() +// CHECK:STDOUT: define void @_CFn.Intermediate.Classes(ptr %self) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !7 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CFn.Derived.Classes() +// CHECK:STDOUT: define void @_CFn.Derived.Classes(ptr %self) !dbg !8 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !9 +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -73,6 +79,12 @@ fn Fn() { // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) // CHECK:STDOUT: !3 = !DIFile(filename: "classes.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.Intermediate.Classes", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 9, column: 3, scope: !4) +// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.Derived.Classes", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !9 = !DILocation(line: 14, column: 3, scope: !8) // CHECK:STDOUT: ; ModuleID = 'create.carbon' // CHECK:STDOUT: source_filename = "create.carbon" // CHECK:STDOUT: @@ -89,11 +101,11 @@ fn Fn() { // CHECK:STDOUT: // CHECK:STDOUT: define void @_CUse.Create(ptr %v) !dbg !9 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: call void @_CFn.Intermediate.Classes(), !dbg !10 +// CHECK:STDOUT: call void @_CFn.Intermediate.Classes(ptr %v), !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CFn.Intermediate.Classes() +// CHECK:STDOUT: declare void @_CFn.Intermediate.Classes(ptr) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 @@ -121,23 +133,26 @@ fn Fn() { // CHECK:STDOUT: ; ModuleID = 'member_init.carbon' // CHECK:STDOUT: source_filename = "member_init.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CFn.Base.MemberInit() +// CHECK:STDOUT: define void @_CFn.Base.MemberInit(ptr %self) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !7 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define void @_CFn.MemberInit() !dbg !4 { +// CHECK:STDOUT: define void @_CFn.MemberInit() !dbg !8 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !7 -// CHECK:STDOUT: %v.var = alloca { ptr, i32 }, align 8, !dbg !7 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %i.var), !dbg !7 -// CHECK:STDOUT: store i32 3, ptr %i.var, align 4, !dbg !7 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %v.var), !dbg !7 -// CHECK:STDOUT: %.loc12_24.2.vptr = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 0, !dbg !8 -// CHECK:STDOUT: store ptr null, ptr %.loc12_24.2.vptr, align 8, !dbg !8 -// CHECK:STDOUT: %.loc12_23 = load i32, ptr %i.var, align 4, !dbg !9 -// CHECK:STDOUT: %.loc12_24.5.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !8 -// CHECK:STDOUT: store i32 %.loc12_23, ptr %.loc12_24.5.m, align 4, !dbg !8 -// CHECK:STDOUT: %.loc15_4.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !10 -// CHECK:STDOUT: store i32 5, ptr %.loc15_4.m, align 4, !dbg !10 -// CHECK:STDOUT: ret void, !dbg !11 +// CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !9 +// CHECK:STDOUT: %v.var = alloca { ptr, i32 }, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %i.var), !dbg !9 +// CHECK:STDOUT: store i32 3, ptr %i.var, align 4, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %v.var), !dbg !9 +// CHECK:STDOUT: %.loc12_24.2.vptr = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store ptr null, ptr %.loc12_24.2.vptr, align 8, !dbg !10 +// CHECK:STDOUT: %.loc12_23 = load i32, ptr %i.var, align 4, !dbg !11 +// CHECK:STDOUT: %.loc12_24.5.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: store i32 %.loc12_23, ptr %.loc12_24.5.m, align 4, !dbg !10 +// CHECK:STDOUT: %.loc15_4.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !12 +// CHECK:STDOUT: store i32 5, ptr %.loc15_4.m, align 4, !dbg !12 +// CHECK:STDOUT: ret void, !dbg !13 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) @@ -155,11 +170,13 @@ fn Fn() { // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) // CHECK:STDOUT: !3 = !DIFile(filename: "member_init.carbon", directory: "") -// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.MemberInit", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.Base.MemberInit", scope: null, file: !3, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} -// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 3, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 12, column: 17, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 12, column: 23, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 15, column: 3, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !7 = !DILocation(line: 6, column: 3, scope: !4) +// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "Fn", linkageName: "_CFn.MemberInit", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !9 = !DILocation(line: 10, column: 3, scope: !8) +// CHECK:STDOUT: !10 = !DILocation(line: 12, column: 17, scope: !8) +// CHECK:STDOUT: !11 = !DILocation(line: 12, column: 23, scope: !8) +// CHECK:STDOUT: !12 = !DILocation(line: 15, column: 3, scope: !8) +// CHECK:STDOUT: !13 = !DILocation(line: 9, column: 1, scope: !8) From 92e635c2f0ad39c80fe079f58073daa1ebfaa14a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 27 Feb 2025 12:06:02 -0500 Subject: [PATCH 36/56] Use the constant value unconditionally in deduce diagnostic (#5034) When finding the binding entity name, always go through the binding instruction's constant value to get a canonical instruction which will always have an entity name attached to it. Currently the only instructions in this position without an entity name are ImportRefLoaded. But other indirect instructions may exist in the future, which evaluate to an AnyBindName but are not themselves one. So this makes the code more robust to change in the future. --- toolchain/check/deduce.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index 8036a7b71138b..5040f544c2bc0 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -511,11 +511,10 @@ auto DeductionContext::Deduce() -> bool { static auto GetEntityNameForGenericBinding(Context& context, SemIR::InstId binding_id) -> SemIR::NameId { - // If `binding_id` is imported, it may not have an entity name. Get a - // canonical local instruction from its constant value which does. - if (context.insts().Is(binding_id)) { - binding_id = context.constant_values().GetConstantInstId(binding_id); - } + // If `binding_id` is imported (or referenced indirectly perhaps in the + // future), it may not have an entity name. Get a canonical local instruction + // from its constant value which does. + binding_id = context.constant_values().GetConstantInstId(binding_id); if (auto bind_name = context.insts().TryGetAs(binding_id)) { From 129cf35d78054ccdc04066354e26ffd836c64377 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 27 Feb 2025 12:53:48 -0500 Subject: [PATCH 37/56] Support BitAnd operator between facet types (#5022) Doing so results in TODOs in the resulting semir, since we don't handle combining the facet types together properly or doing lookup into them. There's a test added demonstrating this, which will be made to work in followups. --------- Co-authored-by: Jon Ross-Perkins --- core/prelude/operators/bitwise.carbon | 8 ++ toolchain/check/eval.cpp | 69 ++++++++-- .../value_with_type_through_access.carbon | 44 +++--- .../testdata/class/generic/import.carbon | 6 +- toolchain/check/testdata/class/import.carbon | 2 +- .../testdata/facet/no_prelude/combine.carbon | 126 ++++++++++++++++++ .../function/generic/undefined.carbon | 2 +- .../if_expr/fail_not_in_function.carbon | 2 +- .../index/fail_negative_indexing.carbon | 4 +- .../overloaded/bit_complement.carbon | 8 +- toolchain/check/testdata/struct/import.carbon | 6 +- .../access/fail_negative_indexing.carbon | 4 +- toolchain/check/testdata/tuple/import.carbon | 6 +- .../testdata/where_expr/equal_rewrite.carbon | 16 +-- toolchain/check/type_completion.cpp | 6 +- toolchain/diagnostics/diagnostic_kind.def | 5 +- toolchain/lower/handle_call.cpp | 5 + toolchain/sem_ir/builtin_function_kind.cpp | 26 +++- toolchain/sem_ir/builtin_function_kind.def | 3 + toolchain/sem_ir/facet_type_info.h | 14 ++ 20 files changed, 293 insertions(+), 69 deletions(-) create mode 100644 toolchain/check/testdata/facet/no_prelude/combine.carbon diff --git a/core/prelude/operators/bitwise.carbon b/core/prelude/operators/bitwise.carbon index 1eecda4b94b06..e20ddff73e503 100644 --- a/core/prelude/operators/bitwise.carbon +++ b/core/prelude/operators/bitwise.carbon @@ -87,3 +87,11 @@ impl IntLiteral() as LeftShift { impl IntLiteral() as RightShift { fn Op[self: Self](other: Self) -> Self = "int.right_shift"; } + +// Operations for `type`. These need to be here because `type` has no +// associated library of its own. + +// Facet type combination. +impl forall [T:! type] T as BitAnd { + fn Op[self: Self](other: Self) -> Self = "type.and"; +} diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 29ac9e51c8fc9..c5cb700e864b0 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -331,6 +331,18 @@ static auto MakeFloatResult(Context& context, SemIR::TypeId type_id, Phase::Concrete); } +// Creates a FacetType constant. +static auto MakeFacetTypeResult(Context& context, + const SemIR::FacetTypeInfo& info, Phase phase) + -> SemIR::ConstantId { + SemIR::FacetTypeId facet_type_id = context.facet_types().Add(info); + return MakeConstantResult( + context, + SemIR::FacetType{.type_id = SemIR::TypeType::SingletonTypeId, + .facet_type_id = facet_type_id}, + phase); +} + // `GetConstantValue` checks to see whether the provided ID describes a value // with constant phase, and if so, returns the corresponding constant value. // Overloads are provided for different kinds of ID. @@ -1289,11 +1301,12 @@ static auto PerformBuiltinBoolComparison( } // Returns a constant for a call to a builtin function. -static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc, +static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc, SemIR::Call call, SemIR::BuiltinFunctionKind builtin_kind, llvm::ArrayRef arg_ids, Phase phase) -> SemIR::ConstantId { + auto& context = eval_context.context(); switch (builtin_kind) { case SemIR::BuiltinFunctionKind::None: CARBON_FATAL("Not a builtin function."); @@ -1306,6 +1319,46 @@ static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc, return SemIR::ConstantId::NotConstant; } + case SemIR::BuiltinFunctionKind::TypeAnd: { + CARBON_CHECK(arg_ids.size() == 2); + auto lhs_facet_type_id = SemIR::FacetTypeId::None; + auto rhs_facet_type_id = SemIR::FacetTypeId::None; + for (auto [facet_type_id, arg_id] : + llvm::zip(std::to_array({&lhs_facet_type_id, &rhs_facet_type_id}), + arg_ids)) { + if (auto facet_type = + context.insts().TryGetAs(arg_id)) { + *facet_type_id = facet_type->facet_type_id; + } else { + CARBON_DIAGNOSTIC(FacetTypeRequiredForTypeAndOperator, Error, + "non-facet type {0} combined with `&` operator", + SemIR::TypeId); + // TODO: Find a location for the lhs or rhs specifically, instead of + // the whole thing. If that's not possible we can change the text to + // say if it's referring to the left or the right side for the error. + // The `arg_id` instruction has no location in it for some reason. + context.emitter().Emit( + loc, FacetTypeRequiredForTypeAndOperator, + context.types().GetTypeIdForTypeInstId(arg_id)); + } + } + // Allow errors to be diagnosed for both sides of the operator before + // returning here if any error occurred on either side. + if (!lhs_facet_type_id.has_value() || !rhs_facet_type_id.has_value()) { + return SemIR::ErrorInst::SingletonConstantId; + } + // Reuse one of the argument instructions if nothing has changed. + if (lhs_facet_type_id == rhs_facet_type_id) { + return context.types().GetConstantId( + context.types().GetTypeIdForTypeInstId(arg_ids[0])); + } + auto info = SemIR::FacetTypeInfo::Combine( + context.facet_types().Get(lhs_facet_type_id), + context.facet_types().Get(rhs_facet_type_id)); + info.Canonicalize(); + return MakeFacetTypeResult(eval_context.context(), info, phase); + } + case SemIR::BuiltinFunctionKind::IntLiteralMakeType: { return context.constant_values().Get( SemIR::IntLiteralType::SingletonInstId); @@ -1525,25 +1578,13 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc, // Handle calls to builtins. if (builtin_kind != SemIR::BuiltinFunctionKind::None) { return MakeConstantForBuiltinCall( - eval_context.context(), loc, call, builtin_kind, + eval_context, loc, call, builtin_kind, eval_context.inst_blocks().Get(call.args_id), phase); } return SemIR::ConstantId::NotConstant; } -// Creates a FacetType constant. -static auto MakeFacetTypeResult(Context& context, - const SemIR::FacetTypeInfo& info, Phase phase) - -> SemIR::ConstantId { - SemIR::FacetTypeId facet_type_id = context.facet_types().Add(info); - return MakeConstantResult( - context, - SemIR::FacetType{.type_id = SemIR::TypeType::SingletonTypeId, - .facet_type_id = facet_type_id}, - phase); -} - // The result of constant evaluation of an instruction. class ConstantEvalResult { public: diff --git a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon index 864e599315129..bb9b699d19a17 100644 --- a/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon @@ -658,11 +658,11 @@ fn G() { // CHECK:STDOUT: constants { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete] -// CHECK:STDOUT: %T: %array_type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.patt: %array_type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.eb6: %array_type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.226: %array_type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %HoldsType.type: type = generic_class_type @HoldsType [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] -// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T.eb6) [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] @@ -707,19 +707,19 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %HoldsType.decl: %HoldsType.type = class_decl @HoldsType [concrete = constants.%HoldsType.generic] { -// CHECK:STDOUT: %T.patt.loc4_17.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: %array_type = value_param_pattern %T.patt.loc4_17.1, runtime_param [symbolic = %T.patt.loc4_17.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.patt.loc4_17.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt.226)] +// CHECK:STDOUT: %T.param_patt: %array_type = value_param_pattern %T.patt.loc4_17.1, runtime_param [symbolic = %T.patt.loc4_17.2 (constants.%T.patt.226)] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: %array_type = value_param runtime_param // CHECK:STDOUT: %.loc4: type = splice_block %array_type [concrete = constants.%array_type] { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete = constants.%array_type] // CHECK:STDOUT: } -// CHECK:STDOUT: %T.loc4_17.1: %array_type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_17.2 (constants.%T)] +// CHECK:STDOUT: %T.loc4_17.1: %array_type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_17.2 (constants.%T.eb6)] // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %T.patt.loc12_6.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: %array_type = value_param_pattern %T.patt.loc12_6.1, runtime_param [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.patt.loc12_6.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt.226)] +// CHECK:STDOUT: %T.param_patt: %array_type = value_param_pattern %T.patt.loc12_6.1, runtime_param [symbolic = %T.patt.loc12_6.2 (constants.%T.patt.226)] // CHECK:STDOUT: %x.patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = binding_pattern x // CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param_pattern %x.patt, runtime_param0 // CHECK:STDOUT: %a.patt: = binding_pattern a @@ -730,17 +730,17 @@ fn G() { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete = constants.%array_type] // CHECK:STDOUT: } -// CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_6.2 (constants.%T)] +// CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_6.2 (constants.%T.eb6)] // CHECK:STDOUT: %x.param: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param runtime_param0 // CHECK:STDOUT: %.loc12_40: type = splice_block %HoldsType.loc12_40.1 [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] { // CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic] -// CHECK:STDOUT: %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] -// CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] +// CHECK:STDOUT: %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T.eb6)] +// CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(constants.%T.eb6) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] // CHECK:STDOUT: } // CHECK:STDOUT: %x: @F.%HoldsType.loc12_40.2 (%HoldsType) = bind_name x, %x.param // CHECK:STDOUT: %a.param: = value_param runtime_param1 // CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)] +// CHECK:STDOUT: %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T.eb6)] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -761,8 +761,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic class @HoldsType(%T.loc4_17.1: %array_type) { -// CHECK:STDOUT: %T.loc4_17.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc4_17.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.loc4_17.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T.eb6)] +// CHECK:STDOUT: %T.patt.loc4_17.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt.226)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -784,8 +784,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc12_6.1: %array_type) { -// CHECK:STDOUT: %T.loc12_6.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc12_6.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.loc12_6.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T.eb6)] +// CHECK:STDOUT: %T.patt.loc12_6.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt.226)] // CHECK:STDOUT: %HoldsType.loc12_40.2: type = class_type @HoldsType, @HoldsType(%T.loc12_6.2) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -818,16 +818,16 @@ fn G() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @HoldsType(constants.%T) { -// CHECK:STDOUT: %T.loc4_17.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc4_17.2 => constants.%T +// CHECK:STDOUT: specific @HoldsType(constants.%T.eb6) { +// CHECK:STDOUT: %T.loc4_17.2 => constants.%T.eb6 +// CHECK:STDOUT: %T.patt.loc4_17.2 => constants.%T.eb6 // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%T) { -// CHECK:STDOUT: %T.loc12_6.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc12_6.2 => constants.%T +// CHECK:STDOUT: specific @F(constants.%T.eb6) { +// CHECK:STDOUT: %T.loc12_6.2 => constants.%T.eb6 +// CHECK:STDOUT: %T.patt.loc12_6.2 => constants.%T.eb6 // CHECK:STDOUT: %HoldsType.loc12_40.2 => constants.%HoldsType // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/import.carbon b/toolchain/check/testdata/class/generic/import.carbon index 48371f3249f52..749a950ab995a 100644 --- a/toolchain/check/testdata/class/generic/import.carbon +++ b/toolchain/check/testdata/class/generic/import.carbon @@ -254,10 +254,10 @@ class Class(U:! type) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic] -// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x [symbolic] @@ -778,12 +778,12 @@ class Class(U:! type) { // CHECK:STDOUT: --- fail_foo.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %U.patt: type = symbolic_binding_pattern U, 0 [symbolic] // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] // CHECK:STDOUT: %.type: type = generic_class_type @.1 [concrete] // CHECK:STDOUT: %.generic: %.type = struct_value () [concrete] // CHECK:STDOUT: %.e41: type = class_type @.1, @.1(%U) [symbolic] diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index 86673494ea2ba..9c12f6dda2d72 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -361,5 +361,5 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @F[%self.param_patt: %ForwardDeclared.7b34f2.1]() [from "a.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: fn @G[addr .inst1150: %ptr.6cf]() [from "a.carbon"]; +// CHECK:STDOUT: fn @G[addr .inst1179: %ptr.6cf]() [from "a.carbon"]; // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon new file mode 100644 index 0000000000000..0f1e769548260 --- /dev/null +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -0,0 +1,126 @@ +// 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 +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/no_prelude/combine.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/no_prelude/combine.carbon + +// --- core.carbon +package Core; + +interface As(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +interface BitAnd { + fn Op[self: Self](other: Self) -> Self; +} + +impl forall [T:! type] T as BitAnd { + fn Op[self: Self](other: Self) -> Self = "type.and"; +} + +// --- fail_combine_with_non_facet_type.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A {} +class C {} + +fn F() { + // CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] + // CHECK:STDERR: ({} as C) as (C as (A & C)); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + ({} as C) as (C as (A & C)); + // CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] + // CHECK:STDERR: ({} as C) as (C as (C & A)); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + ({} as C) as (C as (C & A)); + // CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+8]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] + // CHECK:STDERR: ({} as C) as (C as (C & C)); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] + // CHECK:STDERR: ({} as C) as (C as (C & C)); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + ({} as C) as (C as (C & C)); +} + +// --- same.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A { + fn G(); +} + +class C {} +impl C as A { + fn G() {} +} + +fn F() { + ({} as C).((A & A).G)(); + (({} as C) as (C as (A & A))).((A & A).G)(); + (({} as C) as (C as (A & A))).(A.G)(); +} + +// --- fail_todo_combine.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A {} +interface B { + fn G(); +} + +class C {} +impl C as A {} +impl C as B { + fn G() {} +} + +fn F() { + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:14: error: semantics TODO: `FacetType with more than one required interface. Sort and deduplicate` [SemanticsTodo] + // CHECK:STDERR: ({} as C).((A & B).G)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + ({} as C).((A & B).G)(); + + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+11]]:18: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A & B` with `as` [ExplicitAsConversionFailure] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A & B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + (({} as C) as (C as (A & B))).((A & B).G)(); + + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+11]]:18: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A & B` with `as` [ExplicitAsConversionFailure] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A & B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + (({} as C) as (C as (A & B))).((B).G)(); +} diff --git a/toolchain/check/testdata/function/generic/undefined.carbon b/toolchain/check/testdata/function/generic/undefined.carbon index 224ebcb007a5b..3487f0afea068 100644 --- a/toolchain/check/testdata/function/generic/undefined.carbon +++ b/toolchain/check/testdata/function/generic/undefined.carbon @@ -185,6 +185,7 @@ fn CallUndefined() -> i32 { // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete] // CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete] // CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete] @@ -194,7 +195,6 @@ fn CallUndefined() -> i32 { // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.5(%int_32) [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] // CHECK:STDOUT: %Defined.specific_fn: = specific_function %Defined, @Defined(%i32) [concrete] -// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { diff --git a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon index 168249a779cca..58964c23764ca 100644 --- a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon +++ b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon @@ -94,7 +94,7 @@ class C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: %i32 = bind_name x, .inst1072.loc27_14 +// CHECK:STDOUT: %x: %i32 = bind_name x, .inst1101.loc27_14 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %y.patt: %i32 = binding_pattern y // CHECK:STDOUT: %.loc37: %i32 = var_pattern %y.patt diff --git a/toolchain/check/testdata/index/fail_negative_indexing.carbon b/toolchain/check/testdata/index/fail_negative_indexing.carbon index 9314c80a8c80c..11f4a7deba112 100644 --- a/toolchain/check/testdata/index/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/index/fail_negative_indexing.carbon @@ -41,10 +41,10 @@ var d: i32 = c[-10]; // CHECK:STDOUT: %array: %array_type = tuple_value (%int_42.c68, %int_42.c68) [concrete] // CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete] // CHECK:STDOUT: %impl_witness.0f6: = impl_witness (imports.%Core.import_ref.c15) [concrete] -// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.13 [concrete] +// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.14 [concrete] // CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value Core.IntLiteral, %impl_witness.0f6 [concrete] // CHECK:STDOUT: %.45d: type = fn_type_with_self_type %Op.type.e42, %Negate.facet [concrete] -// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.14 [concrete] +// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.15 [concrete] // CHECK:STDOUT: %Op.bba: %Op.type.1be = struct_value () [concrete] // CHECK:STDOUT: %Op.bound: = bound_method %int_10, %Op.bba [concrete] // CHECK:STDOUT: %int_-10.06d: Core.IntLiteral = int_value -10 [concrete] diff --git a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon index 2c9957e9fe82b..941b0250f3f33 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon @@ -32,10 +32,10 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %BitComplement.type: type = facet_type <@BitComplement> [concrete] // CHECK:STDOUT: %Op.type.f25: type = fn_type @Op.1 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.5a3.%Op.decl) [concrete] +// CHECK:STDOUT: %impl_witness.40c: = impl_witness (@impl.5a3.%Op.decl) [concrete] // CHECK:STDOUT: %Op.type.544: type = fn_type @Op.2 [concrete] // CHECK:STDOUT: %Op.bf2: %Op.type.544 = struct_value () [concrete] -// CHECK:STDOUT: %BitComplement.facet: %BitComplement.type = facet_value %C, %impl_witness [concrete] +// CHECK:STDOUT: %BitComplement.facet: %BitComplement.type = facet_value %C, %impl_witness.40c [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [concrete] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [concrete] @@ -64,7 +64,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %BitComplement.ref: type = name_ref BitComplement, imports.%Core.BitComplement [concrete = constants.%BitComplement.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.5a3.%Op.decl) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.5a3.%Op.decl) [concrete = constants.%impl_witness.40c] // CHECK:STDOUT: %TestOp.decl: %TestOp.type = fn_decl @TestOp [concrete = constants.%TestOp] { // CHECK:STDOUT: %a.patt: %C = binding_pattern a // CHECK:STDOUT: %a.param_patt: %C = value_param_pattern %a.patt, runtime_param0 @@ -120,7 +120,7 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: fn @TestOp(%a.param_patt: %C) -> %return.param_patt: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %C = name_ref a, %a -// CHECK:STDOUT: %impl.elem0: %.784 = impl_witness_access constants.%impl_witness, element0 [concrete = constants.%Op.bf2] +// CHECK:STDOUT: %impl.elem0: %.784 = impl_witness_access constants.%impl_witness.40c, element0 [concrete = constants.%Op.bf2] // CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem0 // CHECK:STDOUT: %.loc23: ref %C = splice_block %return {} // CHECK:STDOUT: %Op.call: init %C = call %bound_method(%a.ref) to %.loc23 diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index 548a4988ed4f4..f163592524549 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -322,7 +322,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.a11: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1147 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1176 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -497,7 +497,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.a11: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1147 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1176 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -613,7 +613,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.a11: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1147 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1176 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon index 17ed689a0b421..3b3db61e1b992 100644 --- a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon @@ -42,10 +42,10 @@ var b: i32 = a.(-10); // CHECK:STDOUT: %tuple: %tuple.type.d07 = tuple_value (%int_12.1e1, %int_6.e56) [concrete] // CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete] // CHECK:STDOUT: %impl_witness.0f6: = impl_witness (imports.%Core.import_ref.c15) [concrete] -// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.13 [concrete] +// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.14 [concrete] // CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value Core.IntLiteral, %impl_witness.0f6 [concrete] // CHECK:STDOUT: %.45d: type = fn_type_with_self_type %Op.type.e42, %Negate.facet [concrete] -// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.14 [concrete] +// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.15 [concrete] // CHECK:STDOUT: %Op.bba: %Op.type.1be = struct_value () [concrete] // CHECK:STDOUT: %Op.bound: = bound_method %int_10, %Op.bba [concrete] // CHECK:STDOUT: %int_-10: Core.IntLiteral = int_value -10 [concrete] diff --git a/toolchain/check/testdata/tuple/import.carbon b/toolchain/check/testdata/tuple/import.carbon index e811009149965..1684b507ce1b5 100644 --- a/toolchain/check/testdata/tuple/import.carbon +++ b/toolchain/check/testdata/tuple/import.carbon @@ -351,7 +351,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.554: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1182 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1211 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -542,7 +542,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.554: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1182 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1211 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -659,7 +659,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.554: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1182 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1211 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/where_expr/equal_rewrite.carbon b/toolchain/check/testdata/where_expr/equal_rewrite.carbon index 8f205a5450820..916c3f4114343 100644 --- a/toolchain/check/testdata/where_expr/equal_rewrite.carbon +++ b/toolchain/check/testdata/where_expr/equal_rewrite.carbon @@ -1189,8 +1189,8 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: %.Self.as_wit.cef: = facet_access_witness %.Self.9aa [symbolic_self] // CHECK:STDOUT: %impl.elem0.51b: type = impl_witness_access %.Self.as_wit.cef, element0 [symbolic_self] // CHECK:STDOUT: %N_where.type: type = facet_type <@N where %impl.elem0.51b = %empty_struct_type> [concrete] -// CHECK:STDOUT: %T.patt: %N_where.type = symbolic_binding_pattern T, 0 [symbolic] -// CHECK:STDOUT: %T: %N_where.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.dbc: %N_where.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.7ae: %N_where.type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] // CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] // CHECK:STDOUT: %NestedRewrite.type: type = fn_type @NestedRewrite [concrete] @@ -1225,7 +1225,7 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: %Main.import_ref.169 = import_ref Main//equal_constraint, inst17 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.020 = import_ref Main//equal_constraint, loc5_8, unloaded // CHECK:STDOUT: %Main.P = import_ref Main//equal_constraint, P, unloaded -// CHECK:STDOUT: %Main.import_ref.bdf: %N_where.type = import_ref Main//equal_constraint, loc8_10, loaded [symbolic = @Equal.1.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.bdf: %N_where.type = import_ref Main//equal_constraint, loc8_10, loaded [symbolic = @Equal.1.%T (constants.%T.7ae)] // CHECK:STDOUT: %Main.import_ref.b61 = import_ref Main//nested_rewrites, inst17 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.91a = import_ref Main//nested_rewrites, loc5_8, unloaded // CHECK:STDOUT: %Main.import_ref.55d = import_ref Main//nested_rewrites, loc6_8, unloaded @@ -1276,8 +1276,8 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @Equal.1(imports.%Main.import_ref.bdf: %N_where.type) [from "equal_constraint.carbon"] { -// CHECK:STDOUT: %T: %N_where.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] -// CHECK:STDOUT: %T.patt: %N_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt)] +// CHECK:STDOUT: %T: %N_where.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.7ae)] +// CHECK:STDOUT: %T.patt: %N_where.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt.dbc)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%T.param_patt: %N_where.type); // CHECK:STDOUT: } @@ -1289,9 +1289,9 @@ let K: (E where .F = .Self.G) = bool; // CHECK:STDOUT: fn(%D.param_patt: %A_where.type.791); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Equal.1(constants.%T) { -// CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: %T.patt => constants.%T +// CHECK:STDOUT: specific @Equal.1(constants.%T.7ae) { +// CHECK:STDOUT: %T => constants.%T.7ae +// CHECK:STDOUT: %T.patt => constants.%T.7ae // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @NestedRewrite(constants.%D) { diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 77d0d6f456735..bcab9f0b033b5 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -318,7 +318,11 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { } // TODO: Sort and deduplicate result.required_interfaces. For now, we have // at most one. - CARBON_CHECK(result.required_interfaces.size() <= 1); + if (result.required_interfaces.size() > 1) { + context_.TODO(loc_, + "FacetType with more than one required interface. Sort " + "and deduplicate"); + } // TODO: Distinguish interfaces that are required but would not be // implemented, such as those from `where .Self impls I`. diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index b895f9dcf11a8..d5e72449730a5 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -448,11 +448,14 @@ CARBON_DIAGNOSTIC_KIND(AliasRequiresNameRef) CARBON_DIAGNOSTIC_KIND(ImplsOnNonFacetType) CARBON_DIAGNOSTIC_KIND(WhereOnNonFacetType) -// Facet type resolution +// Facet type resolution. CARBON_DIAGNOSTIC_KIND(AssociatedConstantNotConstantAfterConversion) CARBON_DIAGNOSTIC_KIND(AssociatedConstantWithDifferentValues) CARBON_DIAGNOSTIC_KIND(RewriteForAssociatedFunction) +// Facet type combination. +CARBON_DIAGNOSTIC_KIND(FacetTypeRequiredForTypeAndOperator) + // Pattern matching diagnostics. CARBON_DIAGNOSTIC_KIND(TuplePatternSizeDoesntMatchLiteral) diff --git a/toolchain/lower/handle_call.cpp b/toolchain/lower/handle_call.cpp index 6c9627a5d6f28..31b0913f8e40a 100644 --- a/toolchain/lower/handle_call.cpp +++ b/toolchain/lower/handle_call.cpp @@ -205,6 +205,11 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, return; } + case SemIR::BuiltinFunctionKind::TypeAnd: { + context.SetLocal(inst_id, context.GetTypeAsValue()); + return; + } + case SemIR::BuiltinFunctionKind::BoolMakeType: case SemIR::BuiltinFunctionKind::FloatMakeType: case SemIR::BuiltinFunctionKind::IntLiteralMakeType: diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index 0e8f7d80a3bad..7a070b1731eb0 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -109,6 +109,22 @@ struct AnyFloat { } }; +// Constraint that requires the type to be the type type. +using Type = BuiltinType; + +// Constraint that requires the type to be a type value, whose type is type +// type. Also accepts symbolic constant value types. +struct AnyType { + static auto Check(const File& sem_ir, ValidateState& state, TypeId type_id) + -> bool { + if (BuiltinType::Check(sem_ir, state, type_id)) { + return true; + } + return sem_ir.types().GetAsInst(type_id).type_id() == + TypeType::SingletonTypeId; + } +}; + // Checks that the specified type matches the given type constraint. template auto Check(const File& sem_ir, ValidateState& state, TypeId type_id) -> bool { @@ -130,9 +146,6 @@ auto Check(const File& sem_ir, ValidateState& state, TypeId type_id) -> bool { return false; } -// Constraint that requires the type to be the type type. -using Type = BuiltinType; - } // namespace // Validates that this builtin has a signature matching the specified signature. @@ -394,6 +407,10 @@ constexpr BuiltinInfo BoolEq = {"bool.eq", constexpr BuiltinInfo BoolNeq = {"bool.neq", ValidateSignatureBool>}; +// "type.and": facet type combination. +constexpr BuiltinInfo TypeAnd = { + "type.and", ValidateSignatureAnyType>}; + } // namespace BuiltinFunctionInfo CARBON_DEFINE_ENUM_CLASS_NAMES(BuiltinFunctionKind) = { @@ -495,6 +512,9 @@ auto BuiltinFunctionKind::IsCompTimeOnly(const File& sem_ir, // literal types. See AnyIntLiteralTypes comment for explanation. return AnyIntLiteralTypes(sem_ir, arg_ids, return_type_id); + case TypeAnd: + return true; + default: // TODO: Should the sized MakeType functions be compile-time only? We // can't produce diagnostics for bad sizes at runtime. diff --git a/toolchain/sem_ir/builtin_function_kind.def b/toolchain/sem_ir/builtin_function_kind.def index 6c224f2fa1cb2..235c56f7cc95a 100644 --- a/toolchain/sem_ir/builtin_function_kind.def +++ b/toolchain/sem_ir/builtin_function_kind.def @@ -84,4 +84,7 @@ CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatGreaterEq) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(BoolEq) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(BoolNeq) +// Facet type combination. +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(TypeAnd) + #undef CARBON_SEM_IR_BUILTIN_FUNCTION_KIND diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index a00687c30fb29..ba7c8303885ca 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -25,6 +25,20 @@ constexpr SpecificInterface SpecificInterface::None = { .interface_id = InterfaceId::None, .specific_id = SpecificId::None}; struct FacetTypeInfo : Printable { + // Returns a FacetTypeInfo that combines `lhs` and `rhs`. It is not + // canonicalized, so that it can be further modified by the caller if desired. + static auto Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs) + -> FacetTypeInfo { + FacetTypeInfo info = {.other_requirements = false}; + llvm::append_range(info.impls_constraints, lhs.impls_constraints); + llvm::append_range(info.impls_constraints, rhs.impls_constraints); + llvm::append_range(info.rewrite_constraints, lhs.rewrite_constraints); + llvm::append_range(info.rewrite_constraints, rhs.rewrite_constraints); + info.other_requirements |= lhs.other_requirements; + info.other_requirements |= rhs.other_requirements; + return info; + } + // TODO: Need to switch to a processed, canonical form, that can support facet // type equality as defined by // https://github.com/carbon-language/carbon-lang/issues/2409. From 0d10b5cd4c3edc033a214d16bdb9824836a33e6b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 27 Feb 2025 14:48:10 -0500 Subject: [PATCH 38/56] Allow facet types to be combined (#5026) The resulting facet type has its complete facet type canonicalized by sorting and deduplicating the `required_interfaces`. Impl lookup now uses the complete facet type. It continues to diagnose with a TODO if it sees a complete facet type with 0 or more than 1 interface in it. Impl lookup to convert from a type to a facet value hits this diagnosis. Member lookup by name works on a facet type with more than one interface because the name knows which interface to look for from the name, and AppendLookupScopesForConstant() looks through all interfaces on the complete facet type already to get the correct scope for the name. --------- Co-authored-by: Jon Ross-Perkins --- toolchain/check/impl_lookup.cpp | 29 +++++-- .../testdata/facet/no_prelude/combine.carbon | 85 ++++++++++++++++++- .../facet/no_prelude/fail_incomplete.carbon | 83 ++++++++++++++++++ toolchain/check/type_completion.cpp | 8 +- toolchain/sem_ir/facet_type_info.cpp | 12 +++ toolchain/sem_ir/facet_type_info.h | 4 + 6 files changed, 204 insertions(+), 17 deletions(-) create mode 100644 toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 95358fc50db61..8b077c5bbeebf 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -5,6 +5,7 @@ #include "toolchain/check/impl_lookup.h" #include "toolchain/check/deduce.h" +#include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/generic.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/type_completion.h" @@ -164,23 +165,39 @@ static auto FindAndDiagnoseImplLookupCycle( static auto GetInterfaceIdFromConstantId(Context& context, SemIR::LocId loc_id, SemIR::ConstantId interface_const_id) -> SemIR::InterfaceId { + // The `interface_const_id` is a constant value for some facet type. We do + // this long chain of steps to go from that constant value to the + // `FacetTypeId` found on the `FacetType` instruction of this constant value, + // and finally to the `CompleteFacetType`. auto facet_type_inst_id = context.constant_values().GetInstId(interface_const_id); - auto facet_type_id = - context.insts().GetAs(facet_type_inst_id).facet_type_id; - const auto& facet_type_info = context.facet_types().Get(facet_type_id); - if (facet_type_info.impls_constraints.empty()) { + auto facet_type_inst = + context.insts().GetAs(facet_type_inst_id); + auto facet_type_id = facet_type_inst.facet_type_id; + auto complete_facet_type_id = + context.complete_facet_types().TryGetId(facet_type_id); + // The facet type will already be completed before coming here. If we're + // converting from a concrete type to a facet type, the conversion step + // requires everything to be complete before doing impl lookup. + CARBON_CHECK(complete_facet_type_id.has_value()); + const auto& complete_facet_type = + context.complete_facet_types().Get(complete_facet_type_id); + + if (complete_facet_type.required_interfaces.empty()) { + // This should never happen - a FacetType either requires or is bounded by + // some `.Self impls` clause. Otherwise you would just have `type` (aka + // `TypeType` in the toolchain implementation) which is not a facet type. context.TODO(loc_id, "impl lookup for a FacetType with no interface (using " "`where .Self impls ...` instead?)"); return SemIR::InterfaceId::None; } - if (facet_type_info.impls_constraints.size() > 1) { + if (complete_facet_type.required_interfaces.size() > 1) { context.TODO(loc_id, "impl lookup for a FacetType with more than one interface"); return SemIR::InterfaceId::None; } - return facet_type_info.impls_constraints[0].interface_id; + return complete_facet_type.required_interfaces[0].interface_id; } static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon index 0f1e769548260..466a859134a25 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine.carbon +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -17,6 +17,10 @@ interface As(Dest:! type) { fn Convert[self: Self]() -> Dest; } +interface ImplicitAs(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + interface BitAnd { fn Op[self: Self](other: Self) -> Self; } @@ -75,28 +79,54 @@ fn F() { (({} as C) as (C as (A & A))).(A.G)(); } -// --- fail_todo_combine.carbon +// --- fail_name_collision.carbon library "[[@TEST_NAME]]"; import Core; -interface A {} +interface A { + fn G(); +} interface B { fn G(); } class C {} -impl C as A {} +impl C as A { + fn G(); +} impl C as B { fn G() {} } fn F() { - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:14: error: semantics TODO: `FacetType with more than one required interface. Sort and deduplicate` [SemanticsTodo] + // TODO: This error message is wrong here, we are not using `extend`. + + // CHECK:STDERR: fail_name_collision.carbon:[[@LINE+4]]:14: error: ambiguous use of name `G` found in multiple extended scopes [NameAmbiguousDueToExtend] // CHECK:STDERR: ({} as C).((A & B).G)(); // CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: ({} as C).((A & B).G)(); +} + +// --- fail_todo_combine.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A {} +interface B { + fn G(); +} + +class C {} +impl C as A {} +impl C as B { + fn G() {} +} + +fn F() { + ({} as C).((A & B).G)(); // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+11]]:18: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); @@ -124,3 +154,50 @@ fn F() { // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); } + +// --- fail_todo_generic_combine.carbon + +library "[[@TEST_NAME]]"; + +import Core; + +interface A { +} +interface B { + fn G(); +} + +fn G[T:! A & B](t: T) { + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: t.(B.G)(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + t.(B.G)(); +} + +class C {} +impl C as A {} +impl C as B { + fn G() {} +} + +fn F() { + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+17]]:3: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE-18]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn G[T:! A & B](t: T) { + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+10]]:3: error: cannot implicitly convert from `type` to `A & B` [ImplicitAsConversionFailure] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(A & B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE-28]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn G[T:! A & B](t: T) { + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + G({} as C); +} diff --git a/toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon b/toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon new file mode 100644 index 0000000000000..18b1ab61dcf7a --- /dev/null +++ b/toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon @@ -0,0 +1,83 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/no_prelude/fail_incomplete.carbon + +// --- core.carbon +package Core; + +interface As(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +interface BitAnd { + fn Op[self: Self](other: Self) -> Self; +} + +impl forall [T:! type] T as BitAnd { + fn Op[self: Self](other: Self) -> Self = "type.and"; +} + +// --- fail_incomplete.carbon + +library "[[@TEST_NAME]]"; + +import Core; + +interface A; +interface B {} +class C {} + +fn G[T:! A](t: T) {} +fn H[T:! A & B](t: T) {} + +fn F() { + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+7]]:17: error: invalid use of incomplete type `A` [IncompleteTypeInConversion] + // CHECK:STDERR: ({} as C) as (C as A); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-11]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] + // CHECK:STDERR: interface A; + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + ({} as C) as (C as A); + + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+7]]:17: error: invalid use of incomplete type `A & B` [IncompleteTypeInConversion] + // CHECK:STDERR: ({} as C) as (C as (A & B)); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-20]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] + // CHECK:STDERR: interface A; + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + ({} as C) as (C as (A & B)); + + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+10]]:3: error: forming value of incomplete type `A` [IncompleteTypeInValueConversion] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-29]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] + // CHECK:STDERR: interface A; + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-28]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn G[T:! A](t: T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + G({} as C); + + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE+10]]:3: error: forming value of incomplete type `A & B` [IncompleteTypeInValueConversion] + // CHECK:STDERR: H({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-41]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] + // CHECK:STDERR: interface A; + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete.carbon:[[@LINE-39]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn H[T:! A & B](t: T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + H({} as C); +} diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index bcab9f0b033b5..815ddf3e36967 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -316,13 +316,7 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { {.interface_id = interface_id, .specific_id = impl_interface.specific_id}); } - // TODO: Sort and deduplicate result.required_interfaces. For now, we have - // at most one. - if (result.required_interfaces.size() > 1) { - context_.TODO(loc_, - "FacetType with more than one required interface. Sort " - "and deduplicate"); - } + result.CanonicalizeRequiredInterfaces(); // TODO: Distinguish interfaces that are required but would not be // implemented, such as those from `where .Self impls I`. diff --git a/toolchain/sem_ir/facet_type_info.cpp b/toolchain/sem_ir/facet_type_info.cpp index c5ee01ec58278..132c9b13404ca 100644 --- a/toolchain/sem_ir/facet_type_info.cpp +++ b/toolchain/sem_ir/facet_type_info.cpp @@ -26,6 +26,14 @@ static auto RewriteLess(const FacetTypeInfo::RewriteConstraint& lhs, std::tie(rhs.lhs_const_id.index, rhs.rhs_const_id.index); } +// Canonically ordered by the numerical ids. +static auto RequiredLess(const CompleteFacetType::RequiredInterface& lhs, + const CompleteFacetType::RequiredInterface& rhs) + -> bool { + return std::tie(lhs.interface_id.index, lhs.specific_id.index) < + std::tie(rhs.interface_id.index, rhs.specific_id.index); +} + auto FacetTypeInfo::Canonicalize() -> void { SortAndDeduplicate(impls_constraints, ImplsLess); SortAndDeduplicate(rewrite_constraints, RewriteLess); @@ -61,4 +69,8 @@ auto FacetTypeInfo::Print(llvm::raw_ostream& out) const -> void { out << "}"; } +auto CompleteFacetType::CanonicalizeRequiredInterfaces() -> void { + SortAndDeduplicate(required_interfaces, RequiredLess); +} + } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index ba7c8303885ca..2f09240a0d08a 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -114,6 +114,10 @@ struct CompleteFacetType { int num_to_impl; // TODO: Which interfaces to perform name lookup into. + + // Sorts and deduplicates `required_interfaces`. Call after building the sets + // of interfaces, and then don't mutate them value afterwards. + auto CanonicalizeRequiredInterfaces() -> void; }; // See common/hashing.h. From 1f5e5a7b44c9f49fe83aff4aeeaf4258f12bf0a4 Mon Sep 17 00:00:00 2001 From: Alina Sbirlea Date: Thu, 27 Feb 2025 13:17:46 -0800 Subject: [PATCH 39/56] Add basic lowering of generic function definitions. (#5015) Very basic (incomplete) lowering of function definitions for generics. --- toolchain/lower/file_context.cpp | 44 +++++-- toolchain/lower/file_context.h | 11 +- .../testdata/function/generic/call.carbon | 67 +++++++--- .../function/generic/call_basic.carbon | 123 ++++++++++++++++++ .../function/generic/call_method.carbon | 7 +- 5 files changed, 222 insertions(+), 30 deletions(-) create mode 100644 toolchain/lower/testdata/function/generic/call_basic.carbon diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index a7cb36cc37140..5156ec729402c 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -86,6 +86,16 @@ auto FileContext::Run() -> std::unique_ptr { for (auto [id, _] : sem_ir_->functions().enumerate()) { BuildFunctionDefinition(id); } + + // Lower function definitions for generics. + // This cannot be a range-based loop, as new definitions can be added + // while building other definitions. + // NOLINTNEXTLINE + for (size_t i = 0; i != specific_function_definitions_.size(); ++i) { + auto [function_id, specific_id] = specific_function_definitions_[i]; + BuildFunctionDefinition(function_id, specific_id); + } + // Append `__global_init` to `llvm::global_ctors` to initialize global // variables. if (sem_ir().global_ctor_id().has_value()) { @@ -185,8 +195,8 @@ auto FileContext::GetOrCreateFunction(SemIR::FunctionId function_id, // TODO: Add this function to a list of specific functions whose definitions // we need to emit. specific_functions_[specific_id.index] = result; - // TODO: Should this be a pair of ? - specific_function_definitions_.push_back(specific_id); + // TODO: Use this to generate definitions for these functions. + specific_function_definitions_.push_back({function_id, specific_id}); return result; } @@ -302,7 +312,8 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id, return llvm_function; } -auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) +auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id, + SemIR::SpecificId specific_id) -> void { const auto& function = sem_ir().functions().Get(function_id); const auto& body_block_ids = function.body_block_ids; @@ -311,14 +322,22 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) return; } - llvm::Function* llvm_function = GetFunction(function_id); - if (!llvm_function) { - // We chose not to lower this function at all, for example because it's a - // generic function. - return; + llvm::Function* llvm_function; + if (specific_id.has_value()) { + llvm_function = specific_functions_[specific_id.index]; + } else { + llvm_function = GetFunction(function_id); + if (!llvm_function) { + // We chose not to lower this function at all, for example because it's a + // generic function. + return; + } } - BuildFunctionBody(function_id, function, llvm_function); + // For non-generics we do not lower. For generics, the llvm function was + // created via GetOrCreateFunction prior to this when building the + // declaration. + BuildFunctionBody(function_id, function, llvm_function, specific_id); } auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id, @@ -350,12 +369,15 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id, auto lower_param = [&](SemIR::InstId param_id) { // Get the value of the parameter from the function argument. auto param_inst = sem_ir().insts().GetAs(param_id); - llvm::Value* param_value = - llvm::PoisonValue::get(GetType(param_inst.type_id)); + llvm::Value* param_value; + if (SemIR::ValueRepr::ForType(sem_ir(), param_inst.type_id).kind != SemIR::ValueRepr::None) { param_value = llvm_function->getArg(param_index); ++param_index; + } else { + param_value = llvm::PoisonValue::get(GetType( + SemIR::GetTypeInSpecific(sem_ir(), specific_id, param_inst.type_id))); } // The value of the parameter is the value of the argument. function_lowering.SetLocal(param_id, param_value); diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 305baf40195fc..ff61628e0307f 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -103,8 +103,12 @@ class FileContext { SemIR::SpecificId::None) -> llvm::Function*; // Builds the definition for the given function. If the function is only a - // declaration with no definition, does nothing. - auto BuildFunctionDefinition(SemIR::FunctionId function_id) -> void; + // declaration with no definition, does nothing. If this is a generic it'll + // only be lowered if the specific_id is specified. During this lowering of + // a generic, more generic functions may be added for lowering. + auto BuildFunctionDefinition( + SemIR::FunctionId function_id, + SemIR::SpecificId specific_id = SemIR::SpecificId::None) -> void; // Builds a functions body. Common functionality for all functions. auto BuildFunctionBody( @@ -163,7 +167,8 @@ class FileContext { // definitions lowered after the lowering of other definitions. // This list may grow while lowering generic definitions from this list. // The list uses the `SpecificId` to index into specific_functions_. - llvm::SmallVector specific_function_definitions_; + llvm::SmallVector, 10> + specific_function_definitions_; // Provides lowered versions of types. // Vector indexes correspond to `TypeId` indexes for non-symbolic types. We diff --git a/toolchain/lower/testdata/function/generic/call.carbon b/toolchain/lower/testdata/function/generic/call.carbon index 84a82a01b6cde..c2808ea939e79 100644 --- a/toolchain/lower/testdata/function/generic/call.carbon +++ b/toolchain/lower/testdata/function/generic/call.carbon @@ -18,10 +18,12 @@ fn G() { var c: C = {}; var d: D = {}; var n: i32 = 0; + var m: f64 = 0.0; F(c); F(d); F(n); + F(m); F(i32); } @@ -38,18 +40,23 @@ fn G() { // CHECK:STDOUT: %c.var = alloca {}, align 8, !dbg !7 // CHECK:STDOUT: %d.var = alloca {}, align 8, !dbg !7 // CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %m.var = alloca double, align 8, !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !7 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @C.val.loc18_3.2, i64 0, i1 false), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %d.var), !dbg !7 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %d.var, ptr align 1 @D.val.loc19_3.2, i64 0, i1 false), !dbg !8 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !9 -// CHECK:STDOUT: call void @_CF.Main.15b1f98bd9cc0c5b(ptr %c.var), !dbg !10 -// CHECK:STDOUT: call void @_CF.Main.2cc450fc05045897(ptr %d.var), !dbg !11 -// CHECK:STDOUT: %.loc24 = load i32, ptr %n.var, align 4, !dbg !12 -// CHECK:STDOUT: call void @_CF.Main.b88d1103f417c6d4(i32 %.loc24), !dbg !13 -// CHECK:STDOUT: call void @_CF.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !14 -// CHECK:STDOUT: ret void, !dbg !15 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %m.var), !dbg !7 +// CHECK:STDOUT: store double 0.000000e+00, ptr %m.var, align 8, !dbg !10 +// CHECK:STDOUT: call void @_CF.Main.15b1f98bd9cc0c5b(ptr %c.var), !dbg !11 +// CHECK:STDOUT: call void @_CF.Main.2cc450fc05045897(ptr %d.var), !dbg !12 +// CHECK:STDOUT: %.loc25 = load i32, ptr %n.var, align 4, !dbg !13 +// CHECK:STDOUT: call void @_CF.Main.b88d1103f417c6d4(i32 %.loc25), !dbg !14 +// CHECK:STDOUT: %.loc26 = load double, ptr %m.var, align 8, !dbg !15 +// CHECK:STDOUT: call void @_CF.Main.66be507887ceee78(double %.loc26), !dbg !16 +// CHECK:STDOUT: call void @_CF.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !17 +// CHECK:STDOUT: ret void, !dbg !18 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) @@ -58,16 +65,33 @@ fn G() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1 // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CF.Main.15b1f98bd9cc0c5b(ptr) +// CHECK:STDOUT: define void @_CF.Main.15b1f98bd9cc0c5b(ptr %x) !dbg !19 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !20 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CF.Main.2cc450fc05045897(ptr) +// CHECK:STDOUT: define void @_CF.Main.2cc450fc05045897(ptr %x) !dbg !21 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !22 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CF.Main.b88d1103f417c6d4(i32) +// CHECK:STDOUT: define void @_CF.Main.b88d1103f417c6d4(i32 %x) !dbg !23 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !24 +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_CF.Main.5754c7a55c7cbe4a(%type) +// CHECK:STDOUT: define void @_CF.Main.66be507887ceee78(double %x) !dbg !25 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !26 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CF.Main.5754c7a55c7cbe4a(%type %x) !dbg !27 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !28 +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -86,9 +110,22 @@ fn G() { // CHECK:STDOUT: !7 = !DILocation(line: 18, column: 3, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 19, column: 3, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 20, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 22, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 21, column: 3, scope: !4) // CHECK:STDOUT: !11 = !DILocation(line: 23, column: 3, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 24, column: 5, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 24, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 24, column: 3, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 25, column: 5, scope: !4) // CHECK:STDOUT: !14 = !DILocation(line: 25, column: 3, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 17, column: 1, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 26, column: 5, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 26, column: 3, scope: !4) +// CHECK:STDOUT: !17 = !DILocation(line: 27, column: 3, scope: !4) +// CHECK:STDOUT: !18 = !DILocation(line: 17, column: 1, scope: !4) +// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.15b1f98bd9cc0c5b", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !20 = !DILocation(line: 11, column: 1, scope: !19) +// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.2cc450fc05045897", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !22 = !DILocation(line: 11, column: 1, scope: !21) +// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.b88d1103f417c6d4", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !24 = !DILocation(line: 11, column: 1, scope: !23) +// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.66be507887ceee78", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !26 = !DILocation(line: 11, column: 1, scope: !25) +// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.5754c7a55c7cbe4a", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !28 = !DILocation(line: 11, column: 1, scope: !27) diff --git a/toolchain/lower/testdata/function/generic/call_basic.carbon b/toolchain/lower/testdata/function/generic/call_basic.carbon new file mode 100644 index 0000000000000..5cc998a769aba --- /dev/null +++ b/toolchain/lower/testdata/function/generic/call_basic.carbon @@ -0,0 +1,123 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/function/generic/call_basic.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/function/generic/call_basic.carbon + +fn F[T:! type](x: T) { +} + +fn H[T:! type](x: T) { +} + +fn G[T:! type](x: T) -> T { + // TODO: the call below is crashing because proper type resolution to + // use the G specific, not the G generic is not done yet. + // H(T); + return x; +} + + +fn M() { + var n: i32 = 0; + var m: i32; + var p: f64 = 1.0; + var q: f64; + + F(n); + m = G(n); + F(p); + q = G(p); +} + +// CHECK:STDOUT: ; ModuleID = 'call_basic.carbon' +// CHECK:STDOUT: source_filename = "call_basic.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CM.Main() !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %m.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %p.var = alloca double, align 8, !dbg !7 +// CHECK:STDOUT: %q.var = alloca double, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !7 +// CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %m.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %p.var), !dbg !7 +// CHECK:STDOUT: store double 1.000000e+00, ptr %p.var, align 8, !dbg !8 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %q.var), !dbg !7 +// CHECK:STDOUT: %.loc31 = load i32, ptr %n.var, align 4, !dbg !9 +// CHECK:STDOUT: call void @_CF.Main.b88d1103f417c6d4(i32 %.loc31), !dbg !10 +// CHECK:STDOUT: %.loc32 = load i32, ptr %n.var, align 4, !dbg !11 +// CHECK:STDOUT: %G.call.loc32 = call i32 @_CG.Main.b88d1103f417c6d4(i32 %.loc32), !dbg !12 +// CHECK:STDOUT: store i32 %G.call.loc32, ptr %m.var, align 4, !dbg !13 +// CHECK:STDOUT: %.loc33 = load double, ptr %p.var, align 8, !dbg !14 +// CHECK:STDOUT: call void @_CF.Main.66be507887ceee78(double %.loc33), !dbg !15 +// CHECK:STDOUT: %.loc34 = load double, ptr %p.var, align 8, !dbg !16 +// CHECK:STDOUT: %G.call.loc34 = call double @_CG.Main.66be507887ceee78(double %.loc34), !dbg !17 +// CHECK:STDOUT: store double %G.call.loc34, ptr %q.var, align 8, !dbg !18 +// CHECK:STDOUT: ret void, !dbg !19 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CF.Main.b88d1103f417c6d4(i32 %x) !dbg !20 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !21 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @_CG.Main.b88d1103f417c6d4(i32 %x) !dbg !22 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret i32 %x, !dbg !23 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CF.Main.66be507887ceee78(double %x) !dbg !24 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !25 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define double @_CG.Main.66be507887ceee78(double %x) !dbg !26 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret double %x, !dbg !27 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "call_basic.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "M", linkageName: "_CM.Main", scope: null, file: !3, line: 25, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 26, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 28, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 31, column: 5, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 31, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 32, column: 9, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 32, column: 7, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 32, column: 3, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 33, column: 5, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 33, column: 3, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 34, column: 9, scope: !4) +// CHECK:STDOUT: !17 = !DILocation(line: 34, column: 7, scope: !4) +// CHECK:STDOUT: !18 = !DILocation(line: 34, column: 3, scope: !4) +// CHECK:STDOUT: !19 = !DILocation(line: 25, column: 1, scope: !4) +// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.b88d1103f417c6d4", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !21 = !DILocation(line: 11, column: 1, scope: !20) +// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "G", linkageName: "_CG.Main.b88d1103f417c6d4", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !23 = !DILocation(line: 21, column: 3, scope: !22) +// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.66be507887ceee78", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !25 = !DILocation(line: 11, column: 1, scope: !24) +// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "G", linkageName: "_CG.Main.66be507887ceee78", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !27 = !DILocation(line: 21, column: 3, scope: !26) diff --git a/toolchain/lower/testdata/function/generic/call_method.carbon b/toolchain/lower/testdata/function/generic/call_method.carbon index 5fb5e2f5b3905..9872cc6bc9624 100644 --- a/toolchain/lower/testdata/function/generic/call_method.carbon +++ b/toolchain/lower/testdata/function/generic/call_method.carbon @@ -44,7 +44,10 @@ fn CallF() -> i32 { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1 // CHECK:STDOUT: -// CHECK:STDOUT: declare i32 @_CF.C.Main.b88d1103f417c6d4(ptr, i32) +// CHECK:STDOUT: define i32 @_CF.C.Main.b88d1103f417c6d4(ptr %self, i32 %x) !dbg !12 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret i32 %x, !dbg !13 +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } @@ -67,3 +70,5 @@ fn CallF() -> i32 { // CHECK:STDOUT: !9 = !DILocation(line: 20, column: 14, scope: !4) // CHECK:STDOUT: !10 = !DILocation(line: 20, column: 10, scope: !4) // CHECK:STDOUT: !11 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main.b88d1103f417c6d4", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !13 = !DILocation(line: 13, column: 5, scope: !12) From 80e1a6ef61508c252a740c4ce7ad28b853025180 Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Thu, 27 Feb 2025 23:46:46 +0100 Subject: [PATCH 40/56] Avoid copying `NameScope` and only allow moving it (#5032) This class is not intended to be copied. Part of #4622. --- toolchain/check/import.cpp | 2 +- toolchain/sem_ir/name_scope.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index c708f2e22f80a..e0cd3d0612ef5 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -253,7 +253,7 @@ static auto CopyAncestorNameScopesFromImportIR( // Add ancestor namespace names, starting with the outermost. for (auto import_scope_id : llvm::reverse(new_namespaces)) { - auto import_scope = import_sem_ir.name_scopes().Get(import_scope_id); + const auto& import_scope = import_sem_ir.name_scopes().Get(import_scope_id); auto name_id = CopyNameFromImportIR(context, import_sem_ir, import_scope.name_id()); scope_cursor = diff --git a/toolchain/sem_ir/name_scope.h b/toolchain/sem_ir/name_scope.h index 8f1f43b6e63aa..0c757d06d3521 100644 --- a/toolchain/sem_ir/name_scope.h +++ b/toolchain/sem_ir/name_scope.h @@ -135,6 +135,10 @@ class NameScope : public Printable { using IdBase::IdBase; }; + // Disallow copy, allow move. + NameScope(NameScope&& other) = default; + auto operator=(NameScope&& other) -> NameScope& = default; + explicit NameScope(InstId inst_id, NameId name_id, NameScopeId parent_scope_id) : inst_id_(inst_id), From 536bfd9cbff83e82b776210ecac925162a0a3eb2 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 27 Feb 2025 15:31:13 -0800 Subject: [PATCH 41/56] Switch test manifests to embedded C++ (#5036) Inconsistent execution environments make using a path-as-define difficult, so switch to an embedded file. Also fixes the lldb launch so that passing tests run cleanly, and adds TEST_TARGET to gdb (but without testing there). I'm dropping `sourceMap` because it's not handled quite correctly (also not great to be trying to pass source mappings in two different ways), and `env` didn't seem to be working as intended either; maybe specifying `initCommands` causes other things to not be evaluated. But the straight `initCommands` looks like it's working. I used lldb to validate execution of these changes. ``` Running initCommands: (lldb) command script import external/+llvm_project+llvm-project/llvm/utils/lldbDataFormatters.py (lldb) settings set target.source-map "." "/usr/local/google/home/jperkins/dev/carbon-lang" (lldb) settings set target.source-map "/proc/self/cwd" "/usr/local/google/home/jperkins/dev/carbon-lang" (lldb) env TEST_TARGET=//toolchain/testing:file_test (lldb) env TEST_TMPDIR=/tmp Running tests with 128 thread(s) . Done! Note: Google Test filter = ToolchainFileTest.toolchain/check/testdata/const/collapse.carbon [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from ToolchainFileTest [ RUN ] ToolchainFileTest.toolchain/check/testdata/const/collapse.carbon [ OK ] ToolchainFileTest.toolchain/check/testdata/const/collapse.carbon (0 ms) [----------] 1 test from ToolchainFileTest (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (1 ms total) [ PASSED ] 1 test. Process 3869310 exited with status = 0 (0x00000000) ``` --- .vscode/gdb_launch.json | 5 ++- .vscode/lldb_launch.json | 14 +++---- bazel/manifest/defs.bzl | 51 +++++++++++++++++++++--- explorer/BUILD | 3 ++ explorer/file_test.cpp | 12 +++++- scripts/fix_cc_deps.py | 2 +- testing/file_test/BUILD | 20 ++++++++-- testing/file_test/file_test_base.cpp | 11 +---- testing/file_test/file_test_base.h | 6 +-- testing/file_test/file_test_manifest.cpp | 13 ------ testing/file_test/manifest.cpp | 21 ++++++++++ testing/file_test/manifest.h | 21 ++++++++++ testing/file_test/rules.bzl | 35 ++++++++++------ 13 files changed, 154 insertions(+), 60 deletions(-) delete mode 100644 testing/file_test/file_test_manifest.cpp create mode 100644 testing/file_test/manifest.cpp create mode 100644 testing/file_test/manifest.h diff --git a/.vscode/gdb_launch.json b/.vscode/gdb_launch.json index cb9ddf8a311d1..966d70e5654d1 100644 --- a/.vscode/gdb_launch.json +++ b/.vscode/gdb_launch.json @@ -8,7 +8,10 @@ "program": "bazel-bin/toolchain/testing/file_test", "programArgs": "--file_tests=${relativeFile}", "cwd": "${workspaceFolder}", - "env": { "TEST_TMPDIR": "/tmp" } + "env": { + "TEST_TARGET": "//toolchain/testing:file_test", + "TEST_TMPDIR": "/tmp" + } }, { "type": "by-gdb", diff --git a/.vscode/lldb_launch.json b/.vscode/lldb_launch.json index 007c16662665f..c977bc10aa6f9 100644 --- a/.vscode/lldb_launch.json +++ b/.vscode/lldb_launch.json @@ -10,12 +10,11 @@ "debuggerRoot": "${workspaceFolder}", "initCommands": [ "command script import external/+llvm_project+llvm-project/llvm/utils/lldbDataFormatters.py", - "settings set target.source-map \".\" \"${workspaceFolder}\"" - ], - "env": { "TEST_TMPDIR": "/tmp" }, - "sourceMap": { - "/proc/self/cwd/": "${workspaceFolder}" - } + "settings set target.source-map \".\" \"${workspaceFolder}\"", + "settings set target.source-map \"/proc/self/cwd\" \"${workspaceFolder}\"", + "env TEST_TARGET=//toolchain/testing:file_test", + "env TEST_TMPDIR=/tmp" + ] }, { "type": "lldb-dap", @@ -32,7 +31,8 @@ "debuggerRoot": "${workspaceFolder}", "initCommands": [ "command script import external/+llvm_project+llvm-project/llvm/utils/lldbDataFormatters.py", - "settings set target.source-map \".\" \"${workspaceFolder}\"" + "settings set target.source-map \".\" \"${workspaceFolder}\"", + "settings set target.source-map \"/proc/self/cwd\" \"${workspaceFolder}\"" ] } ] diff --git a/bazel/manifest/defs.bzl b/bazel/manifest/defs.bzl index 926ec1f514c3d..04695d6287423 100644 --- a/bazel/manifest/defs.bzl +++ b/bazel/manifest/defs.bzl @@ -4,9 +4,7 @@ """Rule for producing a manifest for a filegroup.""" -def _manifest(ctx): - out = ctx.actions.declare_file(ctx.label.name) - +def _get_files(ctx): files = [] for src in ctx.attr.srcs: files.extend([f.path for f in src[DefaultInfo].files.to_list()]) @@ -17,11 +15,16 @@ def _manifest(ctx): if ctx.attr.strip_package_dir: package_dir = ctx.label.package + "/" - content = [f.removeprefix(package_dir) for f in files] + files_stripped = [f.removeprefix(package_dir) for f in files] else: - content = files + files_stripped = files - ctx.actions.write(out, "\n".join(content) + "\n") + return files_stripped + +def _manifest(ctx): + out = ctx.actions.declare_file(ctx.label.name) + files = _get_files(ctx) + ctx.actions.write(out, "\n".join(files) + "\n") return [ DefaultInfo( @@ -30,6 +33,7 @@ def _manifest(ctx): ), ] +# Produces the manifest as a series of lines. manifest = rule( implementation = _manifest, attrs = { @@ -37,3 +41,38 @@ manifest = rule( "strip_package_dir": attr.bool(default = False), }, ) + +def _manifest_as_cpp(ctx): + out = ctx.actions.declare_file(ctx.label.name) + files = _get_files(ctx) + lines = [ + "// Auto-generated by manifest_as_cpp.", + "const char* {0}[] = {{".format(ctx.attr.var_name), + ] + lines += [ + " \"{0}\",".format(file) + for file in files + ] + lines += [ + " nullptr,", + "};", + ] + ctx.actions.write(out, "\n".join(lines) + "\n") + + return [ + DefaultInfo( + files = depset(direct = [out]), + runfiles = ctx.runfiles(files = [out]), + ), + ] + +# Produces the manifest as a nullptr-terminated `const char* var_name[]`. +# Use with `extern const char* var_name[];`. +manifest_as_cpp = rule( + implementation = _manifest_as_cpp, + attrs = { + "srcs": attr.label_list(allow_files = True, mandatory = True), + "strip_package_dir": attr.bool(default = False), + "var_name": attr.string(mandatory = True), + }, +) diff --git a/explorer/BUILD b/explorer/BUILD index e93d4b12859f0..1c47ba0ae251f 100644 --- a/explorer/BUILD +++ b/explorer/BUILD @@ -58,8 +58,11 @@ cc_binary( ":main", "//common:check", "//common:raw_string_ostream", + "//testing/base:file_helpers", "//testing/file_test:file_test_base", + "//testing/file_test:manifest", "@abseil-cpp//absl/flags:flag", + "@abseil-cpp//absl/strings", "@re2", ], ) diff --git a/explorer/file_test.cpp b/explorer/file_test.cpp index 22a28f3ffd3b6..210bf4518340f 100644 --- a/explorer/file_test.cpp +++ b/explorer/file_test.cpp @@ -3,10 +3,13 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "absl/flags/flag.h" +#include "absl/strings/str_split.h" #include "common/raw_string_ostream.h" #include "explorer/main.h" #include "re2/re2.h" +#include "testing/base/file_helpers.h" #include "testing/file_test/file_test_base.h" +#include "testing/file_test/manifest.h" ABSL_FLAG(bool, trace, false, "Set to true to run tests with tracing enabled, even if they don't " @@ -115,8 +118,13 @@ class ExplorerFileTest : public FileTestBase { } // namespace // Explorer uses a non-standard approach to getting the manifest path. -auto GetFileTestManifestPath() -> std::filesystem::path { - return absl::GetFlag(FLAGS_explorer_test_targets_file); +auto GetFileTestManifest() -> llvm::SmallVector { + llvm::SmallVector manifest; + auto content = ReadFile(absl::GetFlag(FLAGS_explorer_test_targets_file)); + for (const auto& line : absl::StrSplit(*content, "\n", absl::SkipEmpty())) { + manifest.push_back(std::string(line)); + } + return manifest; } CARBON_FILE_TEST_FACTORY(ExplorerFileTest) diff --git a/scripts/fix_cc_deps.py b/scripts/fix_cc_deps.py index 81b7c38757d12..fd4d8bba73b69 100755 --- a/scripts/fix_cc_deps.py +++ b/scripts/fix_cc_deps.py @@ -68,7 +68,7 @@ class RuleChoice(NamedTuple): } IGNORE_SOURCE_FILE_REGEX = re.compile( - "^(third_party/clangd.*|common/version.*\\.cpp)$" + r"^(third_party/clangd.*|common/version.*\.cpp|.*_autogen_manifest\.cpp)$" ) diff --git a/testing/file_test/BUILD b/testing/file_test/BUILD index 63e61ec29b93c..6560c8a8129f8 100644 --- a/testing/file_test/BUILD +++ b/testing/file_test/BUILD @@ -7,9 +7,6 @@ load("rules.bzl", "file_test") package(default_visibility = ["//visibility:public"]) -# Used to access a `#define` with the manifest file, produced by rules.bzl. -exports_files(["file_test_manifest.cpp"]) - cc_library( name = "autoupdate", testonly = 1, @@ -42,6 +39,7 @@ cc_library( hdrs = ["file_test_base.h"], deps = [ ":autoupdate", + ":manifest", "//common:check", "//common:error", "//common:exe_path", @@ -69,3 +67,19 @@ file_test( "@llvm-project//llvm:Support", ], ) + +# Note this is separate from the implementation; see the .h file. +cc_library( + name = "manifest", + testonly = 1, + hdrs = ["manifest.h"], + deps = ["@llvm-project//llvm:Support"], +) + +# Used through `file_test` in rules.bzl. +cc_library( + name = "manifest_impl", + testonly = 1, + srcs = ["manifest.cpp"], + deps = [":manifest"], +) diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index 6a2c325c3fd3b..607353df09500 100644 --- a/testing/file_test/file_test_base.cpp +++ b/testing/file_test/file_test_base.cpp @@ -29,7 +29,6 @@ #include "absl/flags/flag.h" #include "absl/flags/parse.h" #include "absl/strings/str_join.h" -#include "absl/strings/str_split.h" #include "common/check.h" #include "common/error.h" #include "common/exe_path.h" @@ -42,7 +41,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/ThreadPool.h" -#include "testing/base/file_helpers.h" #include "testing/file_test/autoupdate.h" #include "testing/file_test/run_test.h" #include "testing/file_test/test_file.h" @@ -298,14 +296,9 @@ static auto RegisterTests(FileTestFactory* test_factory, llvm::StringRef exe_path, llvm::SmallVectorImpl& tests) -> ErrorOr { - GetFileTestManifestPath(); - CARBON_ASSIGN_OR_RETURN(auto test_manifest, - ReadFile(GetFileTestManifestPath())); - // Prepare the vector first, so that the location of entries won't change. - for (const auto& test_name : - absl::StrSplit(test_manifest, "\n", absl::SkipEmpty())) { - tests.push_back({.test_name = std::string(test_name)}); + for (auto& test_name : GetFileTestManifest()) { + tests.push_back({.test_name = test_name}); } // Amend entries with factory functions. diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index 6c7433685eb5c..4cd6d064e7025 100644 --- a/testing/file_test/file_test_base.h +++ b/testing/file_test/file_test_base.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/VirtualFileSystem.h" #include "testing/file_test/autoupdate.h" +#include "testing/file_test/manifest.h" namespace Carbon::Testing { @@ -133,11 +134,6 @@ struct FileTestFactory { // to implement this function. extern auto GetFileTestFactory() -> FileTestFactory; -// Returns the manifest path, which is provided by rules.bzl and -// file_test_manifest.cpp. This is exposed so that the explorer sharding -// approach can use a different implementation. -auto GetFileTestManifestPath() -> std::filesystem::path; - // Provides a standard GetFileTestFactory implementation. #define CARBON_FILE_TEST_FACTORY(Name) \ auto GetFileTestFactory() -> FileTestFactory { \ diff --git a/testing/file_test/file_test_manifest.cpp b/testing/file_test/file_test_manifest.cpp deleted file mode 100644 index 9467c93e1e891..0000000000000 --- a/testing/file_test/file_test_manifest.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include "testing/file_test/file_test_base.h" - -namespace Carbon::Testing { - -auto GetFileTestManifestPath() -> std::filesystem::path { - return CARBON_FILE_TEST_MANIFEST; -} - -} // namespace Carbon::Testing diff --git a/testing/file_test/manifest.cpp b/testing/file_test/manifest.cpp new file mode 100644 index 0000000000000..d71281344dbd3 --- /dev/null +++ b/testing/file_test/manifest.cpp @@ -0,0 +1,21 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "testing/file_test/manifest.h" + +// The test manifest, produced by `manifest_as_cpp`. +// NOLINTNEXTLINE(readability-identifier-naming): Constant in practice. +extern const char* CarbonFileTestManifest[]; + +namespace Carbon::Testing { + +auto GetFileTestManifest() -> llvm::SmallVector { + llvm::SmallVector manifest; + for (int i = 0; CarbonFileTestManifest[i]; ++i) { + manifest.push_back(CarbonFileTestManifest[i]); + } + return manifest; +} + +} // namespace Carbon::Testing diff --git a/testing/file_test/manifest.h b/testing/file_test/manifest.h new file mode 100644 index 0000000000000..09651469228c2 --- /dev/null +++ b/testing/file_test/manifest.h @@ -0,0 +1,21 @@ +// 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_TESTING_FILE_TEST_MANIFEST_H_ +#define CARBON_TESTING_FILE_TEST_MANIFEST_H_ + +#include + +#include "llvm/ADT/SmallVector.h" + +namespace Carbon::Testing { + +// Returns the manifest path, which is provided by rules.bzl and manifest.cpp. +// This is exposed separately so that the explorer sharding approach can use a +// different implementation. +auto GetFileTestManifest() -> llvm::SmallVector; + +} // namespace Carbon::Testing + +#endif // CARBON_TESTING_FILE_TEST_MANIFEST_H_ diff --git a/testing/file_test/rules.bzl b/testing/file_test/rules.bzl index d97f9b1072494..d4db39f488e72 100644 --- a/testing/file_test/rules.bzl +++ b/testing/file_test/rules.bzl @@ -10,12 +10,13 @@ a file which can be accessed as a list. This avoids long argument parsing. load("@rules_cc//cc:defs.bzl", "cc_test") load("//bazel/cc_toolchains:defs.bzl", "cc_env") -load("//bazel/manifest:defs.bzl", "manifest") +load("//bazel/manifest:defs.bzl", "manifest", "manifest_as_cpp") def file_test( name, tests, srcs = [], + deps = [], data = [], args = [], prebuilt_binary = None, @@ -30,6 +31,7 @@ def file_test( name: The base name of the tests. tests: The list of test files to use as data, typically a glob. srcs: Passed to cc_test. + deps: Passed to cc_test. data: Passed to cc_test. args: Passed to cc_test. prebuilt_binary: If set, specifies a prebuilt test binary to use instead @@ -38,34 +40,41 @@ def file_test( """ # Ensure tests are always a filegroup for tests_as_input_file_rule. - tests_file = "{0}.tests".format(name) - manifest( - name = tests_file, - srcs = tests, - testonly = 1, - ) - data = [":" + tests_file] + tests + data - if prebuilt_binary: # TODO: The prebuilt_binary support is only used by explorer. We should # remove this once explorer is removed, and think about better factoring # approaches if we need it later for toolchain. + tests_file = "{0}.tests".format(name) + manifest( + name = tests_file, + srcs = tests, + testonly = 1, + ) args = ["--explorer_test_targets_file=$(rootpath :{0})".format(tests_file)] + args + native.sh_test( name = name, srcs = srcs + [prebuilt_binary], - data = data, + deps = deps, + data = [":" + tests_file] + tests + data, args = args, env = cc_env(), **kwargs ) else: + manifest_cpp = "{0}_autogen_manifest.cpp".format(name) + manifest_as_cpp( + name = manifest_cpp, + var_name = "CarbonFileTestManifest", + srcs = tests, + testonly = 1, + ) cc_test( name = name, - srcs = srcs + ["//testing/file_test:file_test_manifest.cpp"], - data = data, + srcs = srcs + [":" + manifest_cpp], + deps = deps + ["//testing/file_test:manifest_impl"], + data = tests + data, args = args, env = cc_env(), - local_defines = ["CARBON_FILE_TEST_MANIFEST='\"$(rootpath :{0})\"'".format(tests_file)], **kwargs ) From f30fa2d3db7669ec05a745e14abdaa8b3d771980 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 27 Feb 2025 16:50:43 -0800 Subject: [PATCH 42/56] Move the `EvalConstantInst` overloads out of `eval.cpp` into their own file. (#5040) For now they're all in the same file; we might consider splitting them further if that file gets too large. --- toolchain/check/BUILD | 2 + toolchain/check/eval.cpp | 536 ++-------------------------------- toolchain/check/eval_inst.cpp | 373 +++++++++++++++++++++++ toolchain/check/eval_inst.h | 123 ++++++++ toolchain/check/type.cpp | 58 ++++ toolchain/check/type.h | 12 + 6 files changed, 596 insertions(+), 508 deletions(-) create mode 100644 toolchain/check/eval_inst.cpp create mode 100644 toolchain/check/eval_inst.h diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 186ffbd387c9c..d31dc1a013726 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -22,6 +22,7 @@ cc_library( "decl_name_stack.cpp", "deduce.cpp", "eval.cpp", + "eval_inst.cpp", "facet_type.cpp", "function.cpp", "generic.cpp", @@ -57,6 +58,7 @@ cc_library( "deduce.h", "diagnostic_helpers.h", "eval.h", + "eval_inst.h", "facet_type.h", "function.h", "generic.h", diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index c5cb700e864b0..0ad141a8da68e 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -6,6 +6,7 @@ #include "toolchain/base/kind_switch.h" #include "toolchain/check/diagnostic_helpers.h" +#include "toolchain/check/eval_inst.h" #include "toolchain/check/facet_type.h" #include "toolchain/check/generic.h" #include "toolchain/check/import_ref.h" @@ -694,39 +695,6 @@ static auto PerformArrayIndex(EvalContext& eval_context, SemIR::ArrayIndex inst) return eval_context.GetConstantValue(elements[index_val.getZExtValue()]); } -// Enforces that an integer type has a valid bit width. -static auto ValidateIntType(Context& context, SemIRLoc loc, - SemIR::IntType result) -> bool { - auto bit_width = - context.insts().TryGetAs(result.bit_width_id); - if (!bit_width) { - // Symbolic bit width. - return true; - } - const auto& bit_width_val = context.ints().Get(bit_width->int_id); - if (bit_width_val.isZero() || - (context.types().IsSignedInt(bit_width->type_id) && - bit_width_val.isNegative())) { - CARBON_DIAGNOSTIC(IntWidthNotPositive, Error, - "integer type width of {0} is not positive", TypedInt); - context.emitter().Emit( - loc, IntWidthNotPositive, - {.type = bit_width->type_id, .value = bit_width_val}); - return false; - } - if (bit_width_val.ugt(IntStore::MaxIntWidth)) { - CARBON_DIAGNOSTIC(IntWidthTooLarge, Error, - "integer type width of {0} is greater than the " - "maximum supported width of {1}", - TypedInt, int); - context.emitter().Emit(loc, IntWidthTooLarge, - {.type = bit_width->type_id, .value = bit_width_val}, - IntStore::MaxIntWidth); - return false; - } - return true; -} - // Forms a constant int type as an evaluation result. Requires that width_id is // constant. static auto MakeIntTypeResult(Context& context, SemIRLoc loc, @@ -742,31 +710,6 @@ static auto MakeIntTypeResult(Context& context, SemIRLoc loc, return MakeConstantResult(context, result, phase); } -// Enforces that the bit width is 64 for a float. -static auto ValidateFloatBitWidth(Context& context, SemIRLoc loc, - SemIR::InstId inst_id) -> bool { - auto inst = context.insts().GetAs(inst_id); - if (context.ints().Get(inst.int_id) == 64) { - return true; - } - - CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "bit width must be 64"); - context.emitter().Emit(loc, CompileTimeFloatBitWidth); - return false; -} - -// Enforces that a float type has a valid bit width. -static auto ValidateFloatType(Context& context, SemIRLoc loc, - SemIR::FloatType result) -> bool { - auto bit_width = - context.insts().TryGetAs(result.bit_width_id); - if (!bit_width) { - // Symbolic bit width. - return true; - } - return ValidateFloatBitWidth(context, loc, result.bit_width_id); -} - // Performs a conversion between integer types, truncating if the value doesn't // fit in the destination type. static auto PerformIntConvert(Context& context, SemIR::InstId arg_id, @@ -1585,454 +1528,33 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc, return SemIR::ConstantId::NotConstant; } -// The result of constant evaluation of an instruction. -class ConstantEvalResult { - public: - // Produce a new constant as the result of an evaluation. The phase of the - // produced constant must be the same as the greatest phase of the operands in - // the evaluation. This will typically be the case if the evaluation uses all - // of its operands. - static auto New(SemIR::Inst inst) -> ConstantEvalResult { - return ConstantEvalResult(inst); - } - - // Produce an existing constant as the result of an evaluation. - static constexpr auto Existing(SemIR::ConstantId existing_id) - -> ConstantEvalResult { - CARBON_CHECK(existing_id.is_constant()); - return ConstantEvalResult(existing_id); - } - - // Indicates that an error was produced by evaluation. - static const ConstantEvalResult Error; - - // Indicates that we encountered an instruction whose evaluation is - // non-constant despite having constant operands. This should be rare; - // usually we want to produce an error in this case. - static const ConstantEvalResult NotConstant; - - // Indicates that we encountered an instruction for which we've not - // implemented constant evaluation yet. Instruction is treated as not - // constant. - static const ConstantEvalResult TODO; - - // Returns whether the result of evaluation is that we should produce a new - // constant described by `new_inst()` rather than an existing `ConstantId` - // described by `existing()`. - auto is_new() const -> bool { return !result_id_.has_value(); } - - // Returns the existing constant that this the instruction evaluates to, or - // `None` if this is evaluation produces a new constant. - auto existing() const -> SemIR::ConstantId { return result_id_; } - - // Returns the new constant instruction that is the result of evaluation. - auto new_inst() const -> SemIR::Inst { - CARBON_CHECK(is_new()); - return new_inst_; - } - - private: - constexpr explicit ConstantEvalResult(SemIR::ConstantId raw_id) - : result_id_(raw_id) {} - - explicit ConstantEvalResult(SemIR::Inst inst) - : result_id_(SemIR::ConstantId::None), new_inst_(inst) {} - - SemIR::ConstantId result_id_; - union { - SemIR::Inst new_inst_; - }; -}; - -constexpr ConstantEvalResult ConstantEvalResult::Error = - Existing(SemIR::ErrorInst::SingletonConstantId); - -constexpr ConstantEvalResult ConstantEvalResult::NotConstant = - ConstantEvalResult(SemIR::ConstantId::NotConstant); - -constexpr ConstantEvalResult ConstantEvalResult::TODO = NotConstant; - -// `EvalConstantInst` evaluates an instruction whose operands are all constant, -// in a context unrelated to the enclosing evaluation. The function is given the -// instruction after its operands, including its type, are replaced by their -// evaluated value, and returns a `ConstantEvalResult` describing the result of -// evaluating the instruction. -// -// An overload is provided for each type whose constant kind is one of the -// following: -// -// - InstConstantKind::Indirect -// - InstConstantKind::SymbolicOnly -// - InstConstantKind::Conditional -// -// ... except for cases where the result of evaluation depends on the evaluation -// context itself. Those cases are handled by explicit specialization of -// `TryEvalTypedInst`. - -static auto EvalConstantInst(Context& context, SemIRLoc loc, - SemIR::ArrayType inst) -> ConstantEvalResult { - auto bound_inst = context.insts().Get(inst.bound_id); - auto int_bound = bound_inst.TryAs(); - if (!int_bound) { - CARBON_CHECK(context.constant_values().Get(inst.bound_id).is_symbolic(), - "Unexpected inst {0} for template constant int", bound_inst); - return ConstantEvalResult::New(inst); - } - // TODO: We should check that the size of the resulting array type - // fits in 64 bits, not just that the bound does. Should we use a - // 32-bit limit for 32-bit targets? - const auto& bound_val = context.ints().Get(int_bound->int_id); - if (context.types().IsSignedInt(int_bound->type_id) && - bound_val.isNegative()) { - CARBON_DIAGNOSTIC(ArrayBoundNegative, Error, - "array bound of {0} is negative", TypedInt); - context.emitter().Emit(loc, ArrayBoundNegative, - {.type = int_bound->type_id, .value = bound_val}); - return ConstantEvalResult::Error; - } - if (bound_val.getActiveBits() > 64) { - CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error, - "array bound of {0} is too large", TypedInt); - context.emitter().Emit(loc, ArrayBoundTooLarge, - {.type = int_bound->type_id, .value = bound_val}); - return ConstantEvalResult::Error; - } - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc loc, - SemIR::IntType inst) -> ConstantEvalResult { - return ValidateIntType(context, loc, inst) ? ConstantEvalResult::New(inst) - : ConstantEvalResult::Error; -} - -static auto EvalConstantInst(Context& context, SemIRLoc loc, - SemIR::FloatType inst) -> ConstantEvalResult { - return ValidateFloatType(context, loc, inst) ? ConstantEvalResult::New(inst) - : ConstantEvalResult::Error; -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::ArrayInit init) -> ConstantEvalResult { - // TODO: Add an `ArrayValue` to represent a constant array object - // representation instead of using a `TupleValue`. - return ConstantEvalResult::New( - SemIR::TupleValue{.type_id = init.type_id, .elements_id = init.inits_id}); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::ClassInit init) -> ConstantEvalResult { - // TODO: Add a `ClassValue` to represent a constant class object - // representation instead of using a `StructValue`. - return ConstantEvalResult::New(SemIR::StructValue{ - .type_id = init.type_id, .elements_id = init.elements_id}); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::StructInit init) -> ConstantEvalResult { - return ConstantEvalResult::New(SemIR::StructValue{ - .type_id = init.type_id, .elements_id = init.elements_id}); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::TupleInit init) -> ConstantEvalResult { - return ConstantEvalResult::New(SemIR::TupleValue{ - .type_id = init.type_id, .elements_id = init.elements_id}); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::FunctionDecl inst) -> ConstantEvalResult { - return ConstantEvalResult::New(SemIR::StructValue{ - .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ClassDecl inst) -> ConstantEvalResult { - // If the class has generic parameters, we don't produce a class type, but a - // callable whose return value is a class type. - if (context.classes().Get(inst.class_id).has_parameters()) { - return ConstantEvalResult::New(SemIR::StructValue{ - .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); - } - - // A non-generic class declaration evaluates to the class type. - return ConstantEvalResult::New( - SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, - .class_id = inst.class_id, - .specific_id = SemIR::SpecificId::None}); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::InterfaceDecl inst) -> ConstantEvalResult { - // If the interface has generic parameters, we don't produce an interface - // type, but a callable whose return value is an interface type. - if (context.interfaces().Get(inst.interface_id).has_parameters()) { - return ConstantEvalResult::New(SemIR::StructValue{ - .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); - } - - // A non-generic interface declaration evaluates to a facet type. - return ConstantEvalResult::New(FacetTypeFromInterface( - context, inst.interface_id, SemIR::SpecificId::None)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::SpecificConstant inst) - -> ConstantEvalResult { - // Pull the constant value out of the specific. - return ConstantEvalResult::Existing(SemIR::GetConstantValueInSpecific( - context.sem_ir(), inst.specific_id, inst.inst_id)); -} - -// Performs an access into an aggregate, retrieving the specified element. -static auto PerformAggregateAccess(Context& context, SemIR::Inst inst) - -> ConstantEvalResult { - auto access_inst = inst.As(); - if (auto aggregate = context.insts().TryGetAs( - access_inst.aggregate_id)) { - auto elements = context.inst_blocks().Get(aggregate->elements_id); - auto index = static_cast(access_inst.index.index); - CARBON_CHECK(index < elements.size(), "Access out of bounds."); - // `Phase` is not used here. If this element is a concrete constant, then - // so is the result of indexing, even if the aggregate also contains a - // symbolic context. - return ConstantEvalResult::Existing( - context.constant_values().Get(elements[index])); - } - - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ClassElementAccess inst) - -> ConstantEvalResult { - return PerformAggregateAccess(context, inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::StructAccess inst) -> ConstantEvalResult { - return PerformAggregateAccess(context, inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::TupleAccess inst) -> ConstantEvalResult { - return PerformAggregateAccess(context, inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc loc, - SemIR::ImplWitnessAccess inst) - -> ConstantEvalResult { - // This is PerformAggregateAccess followed by GetConstantInSpecific. - if (auto witness = - context.insts().TryGetAs(inst.witness_id)) { - auto elements = context.inst_blocks().Get(witness->elements_id); - auto index = static_cast(inst.index.index); - CARBON_CHECK(index < elements.size(), "Access out of bounds."); - auto element = elements[index]; - if (!element.has_value()) { - // TODO: Perhaps this should be a `{}` value with incomplete type? - CARBON_DIAGNOSTIC(ImplAccessMemberBeforeComplete, Error, - "accessing member from impl before the end of " - "its definition"); - // TODO: Add note pointing to the impl declaration. - context.emitter().Emit(loc, ImplAccessMemberBeforeComplete); - return ConstantEvalResult::Error; - } - - LoadImportRef(context, element); - return ConstantEvalResult::Existing(GetConstantValueInSpecific( - context.sem_ir(), witness->specific_id, element)); - } - - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::BindValue /*inst*/) -> ConstantEvalResult { - // TODO: Handle this once we've decided how to represent constant values of - // reference expressions. - return ConstantEvalResult::TODO; -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::Deref /*inst*/) -> ConstantEvalResult { - // TODO: Handle this. - return ConstantEvalResult::TODO; -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::Temporary /*inst*/) -> ConstantEvalResult { - // TODO: Handle this. Can we just return the value of `init_id`? - return ConstantEvalResult::TODO; -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::VtablePtr /*inst*/) -> ConstantEvalResult { - // TODO: Handle this. - return ConstantEvalResult::TODO; -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::AsCompatible inst) -> ConstantEvalResult { - // AsCompatible changes the type of the source instruction; its constant - // value, if there is one, needs to be modified to be of the same type. - auto value_id = context.constant_values().Get(inst.source_id); - CARBON_CHECK(value_id.is_constant()); +// Given an instruction, compute its phase based on its operands. +static auto ComputeInstPhase(Context& context, SemIR::Inst inst) -> Phase { + EvalContext eval_context(context, SemIR::InstId::None); - auto value_inst = - context.insts().Get(context.constant_values().GetInstId(value_id)); auto phase = GetPhase(context.constant_values(), - context.types().GetConstantId(inst.type_id)); - value_inst.SetType(inst.type_id); - - // Finish computing the new phase by incorporating the phases of the - // arguments. - EvalContext eval_context(context, SemIR::InstId::None); - auto kinds = value_inst.ArgKinds(); - GetConstantValueForArg(eval_context, kinds.first, value_inst.arg0(), &phase); - GetConstantValueForArg(eval_context, kinds.second, value_inst.arg1(), &phase); + context.types().GetConstantId(inst.type_id())); + auto kinds = inst.ArgKinds(); + GetConstantValueForArg(eval_context, kinds.first, inst.arg0(), &phase); + GetConstantValueForArg(eval_context, kinds.second, inst.arg1(), &phase); CARBON_CHECK(IsConstant(phase)); - - // We can't use `ConstantEvalResult::New` because it would use the wrong - // phase, so manually build a new constant. - return ConstantEvalResult::Existing( - MakeConstantResult(context, value_inst, phase)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::BindAlias inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.value_id)); + return phase; } -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ExportDecl inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.value_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::NameRef inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.value_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ValueParamPattern inst) - -> ConstantEvalResult { - // TODO: Treat this as a non-expression (here and in GetExprCategory) - // once generic deduction doesn't need patterns to have constant values. - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.subpattern_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::Converted inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.result_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::InitializeFrom inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.src_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::SpliceBlock inst) -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.result_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ValueOfInitializer inst) - -> ConstantEvalResult { - return ConstantEvalResult::Existing( - context.constant_values().Get(inst.init_id)); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::FacetAccessType inst) - -> ConstantEvalResult { - if (auto facet_value = context.insts().TryGetAs( - inst.facet_value_inst_id)) { - return ConstantEvalResult::Existing( - context.constant_values().Get(facet_value->type_inst_id)); - } - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::FacetAccessWitness inst) - -> ConstantEvalResult { - if (auto facet_value = context.insts().TryGetAs( - inst.facet_value_inst_id)) { - return ConstantEvalResult::Existing( - context.constant_values().Get(facet_value->witness_inst_id)); - } - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::UnaryOperatorNot inst) - -> ConstantEvalResult { - // `not true` -> `false`, `not false` -> `true`. - // All other uses of unary `not` are non-constant. - auto const_id = context.constant_values().Get(inst.operand_id); - if (const_id.is_concrete()) { - auto value = context.insts().GetAs( - context.constant_values().GetInstId(const_id)); - value.value = SemIR::BoolValue::From(!value.value.ToBool()); - return ConstantEvalResult::New(value); - } - return ConstantEvalResult::NotConstant; -} - -static auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, - SemIR::ConstType inst) -> ConstantEvalResult { - // `const (const T)` evaluates to `const T`. - if (context.types().Is(inst.inner_id)) { - return ConstantEvalResult::Existing( - context.types().GetConstantId(inst.inner_id)); - } - // Otherwise, `const T` evaluates to itself. - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& context, SemIRLoc loc, - SemIR::RequireCompleteType inst) - -> ConstantEvalResult { - auto witness_type_id = - GetSingletonType(context, SemIR::WitnessType::SingletonInstId); - - // If the type is a concrete constant, require it to be complete now. - auto complete_type_id = inst.complete_type_id; - if (context.types().GetConstantId(complete_type_id).is_concrete()) { - if (!TryToCompleteType(context, complete_type_id, loc, [&] { - // TODO: It'd be nice to report the original type prior to - // evaluation here. - CARBON_DIAGNOSTIC(IncompleteTypeInMonomorphization, Error, - "type {0} is incomplete", SemIR::TypeId); - return context.emitter().Build(loc, IncompleteTypeInMonomorphization, - complete_type_id); - })) { - return ConstantEvalResult::Error; - } - return ConstantEvalResult::New(SemIR::CompleteTypeWitness{ - .type_id = witness_type_id, - .object_repr_id = context.types().GetObjectRepr(complete_type_id)}); +// Convert a ConstantEvalResult to a ConstantId. Factored out of +// TryEvalTypedInst to avoid repeated instantiation of common code. +static auto ConvertEvalResultToConstantId(Context& context, + ConstantEvalResult result, + Phase orig_phase) + -> SemIR::ConstantId { + if (result.is_new()) { + return MakeConstantResult( + context, result.new_inst(), + result.same_phase_as_inst() + ? orig_phase + : ComputeInstPhase(context, result.new_inst())); } - - // If it's not a concrete constant, require it to be complete once it - // becomes one. - return ConstantEvalResult::New(inst); -} - -static auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, - SemIR::ImportRefUnloaded inst) - -> ConstantEvalResult { - CARBON_FATAL("ImportRefUnloaded should be loaded before TryEvalInst: {0}", - inst); + return result.existing(); } // Evaluates an instruction of a known type in an evaluation context. The @@ -2078,14 +1600,12 @@ static auto TryEvalTypedInst(EvalContext& eval_context, SemIR::InstId inst_id, ConstantKind == SemIR::InstConstantKind::WheneverPossible) { return MakeConstantResult(eval_context.context(), inst, phase); } else { - ConstantEvalResult result = EvalConstantInst( - eval_context.context(), eval_context.GetDiagnosticLoc({inst_id}), - inst.As()); - if (result.is_new()) { - return MakeConstantResult(eval_context.context(), result.new_inst(), - phase); - } - return result.existing(); + return ConvertEvalResultToConstantId( + eval_context.context(), + EvalConstantInst(eval_context.context(), + eval_context.GetDiagnosticLoc({inst_id}), + inst.As()), + phase); } } } diff --git a/toolchain/check/eval_inst.cpp b/toolchain/check/eval_inst.cpp new file mode 100644 index 0000000000000..dfac6ce843811 --- /dev/null +++ b/toolchain/check/eval_inst.cpp @@ -0,0 +1,373 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/check/eval_inst.h" + +#include "toolchain/check/facet_type.h" +#include "toolchain/check/import_ref.h" +#include "toolchain/check/type.h" +#include "toolchain/check/type_completion.h" + +namespace Carbon::Check { + +// Performs an access into an aggregate, retrieving the specified element. +static auto PerformAggregateAccess(Context& context, SemIR::Inst inst) + -> ConstantEvalResult { + auto access_inst = inst.As(); + if (auto aggregate = context.insts().TryGetAs( + access_inst.aggregate_id)) { + auto elements = context.inst_blocks().Get(aggregate->elements_id); + auto index = static_cast(access_inst.index.index); + CARBON_CHECK(index < elements.size(), "Access out of bounds."); + // `Phase` is not used here. If this element is a concrete constant, then + // so is the result of indexing, even if the aggregate also contains a + // symbolic context. + return ConstantEvalResult::Existing( + context.constant_values().Get(elements[index])); + } + + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ArrayInit inst) -> ConstantEvalResult { + // TODO: Add an `ArrayValue` to represent a constant array object + // representation instead of using a `TupleValue`. + return ConstantEvalResult::NewSamePhase( + SemIR::TupleValue{.type_id = inst.type_id, .elements_id = inst.inits_id}); +} + +auto EvalConstantInst(Context& context, SemIRLoc loc, SemIR::ArrayType inst) + -> ConstantEvalResult { + auto bound_inst = context.insts().Get(inst.bound_id); + auto int_bound = bound_inst.TryAs(); + if (!int_bound) { + CARBON_CHECK(context.constant_values().Get(inst.bound_id).is_symbolic(), + "Unexpected inst {0} for template constant int", bound_inst); + return ConstantEvalResult::NewSamePhase(inst); + } + // TODO: We should check that the size of the resulting array type + // fits in 64 bits, not just that the bound does. Should we use a + // 32-bit limit for 32-bit targets? + const auto& bound_val = context.ints().Get(int_bound->int_id); + if (context.types().IsSignedInt(int_bound->type_id) && + bound_val.isNegative()) { + CARBON_DIAGNOSTIC(ArrayBoundNegative, Error, + "array bound of {0} is negative", TypedInt); + context.emitter().Emit(loc, ArrayBoundNegative, + {.type = int_bound->type_id, .value = bound_val}); + return ConstantEvalResult::Error; + } + if (bound_val.getActiveBits() > 64) { + CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error, + "array bound of {0} is too large", TypedInt); + context.emitter().Emit(loc, ArrayBoundTooLarge, + {.type = int_bound->type_id, .value = bound_val}); + return ConstantEvalResult::Error; + } + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::AsCompatible inst) -> ConstantEvalResult { + // AsCompatible changes the type of the source instruction; its constant + // value, if there is one, needs to be modified to be of the same type. + auto value_id = context.constant_values().Get(inst.source_id); + CARBON_CHECK(value_id.is_constant()); + + auto value_inst = + context.insts().Get(context.constant_values().GetInstId(value_id)); + value_inst.SetType(inst.type_id); + return ConstantEvalResult::NewAnyPhase(value_inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, SemIR::BindAlias inst) + -> ConstantEvalResult { + // An alias evaluates to the value it's bound to. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::BindValue /*inst*/) -> ConstantEvalResult { + // TODO: Handle this once we've decided how to represent constant values of + // reference expressions. + return ConstantEvalResult::TODO; +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ClassElementAccess inst) -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, SemIR::ClassDecl inst) + -> ConstantEvalResult { + // If the class has generic parameters, we don't produce a class type, but a + // callable whose return value is a class type. + if (context.classes().Get(inst.class_id).has_parameters()) { + return ConstantEvalResult::NewSamePhase(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); + } + + // A non-generic class declaration evaluates to the class type. + return ConstantEvalResult::NewSamePhase( + SemIR::ClassType{.type_id = SemIR::TypeType::SingletonTypeId, + .class_id = inst.class_id, + .specific_id = SemIR::SpecificId::None}); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ClassInit inst) -> ConstantEvalResult { + // TODO: Add a `ClassValue` to represent a constant class object + // representation instead of using a `StructValue`. + return ConstantEvalResult::NewSamePhase(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = inst.elements_id}); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, SemIR::ConstType inst) + -> ConstantEvalResult { + // `const (const T)` evaluates to `const T`. + if (context.types().Is(inst.inner_id)) { + return ConstantEvalResult::Existing( + context.types().GetConstantId(inst.inner_id)); + } + // Otherwise, `const T` evaluates to itself. + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, SemIR::Converted inst) + -> ConstantEvalResult { + // A conversion evaluates to the result of the conversion. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.result_id)); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::Deref /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. + return ConstantEvalResult::TODO; +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ExportDecl inst) -> ConstantEvalResult { + // An export instruction evaluates to the exported declaration. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::FacetAccessType inst) -> ConstantEvalResult { + if (auto facet_value = context.insts().TryGetAs( + inst.facet_value_inst_id)) { + return ConstantEvalResult::Existing( + context.constant_values().Get(facet_value->type_inst_id)); + } + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::FacetAccessWitness inst) -> ConstantEvalResult { + if (auto facet_value = context.insts().TryGetAs( + inst.facet_value_inst_id)) { + return ConstantEvalResult::Existing( + context.constant_values().Get(facet_value->witness_inst_id)); + } + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc loc, SemIR::FloatType inst) + -> ConstantEvalResult { + return ValidateFloatType(context, loc, inst) + ? ConstantEvalResult::NewSamePhase(inst) + : ConstantEvalResult::Error; +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::FunctionDecl inst) -> ConstantEvalResult { + // A function declaration evaluates to a function object, which is an empty + // object of function type. + // TODO: Eventually we may need to handle captures here. + return ConstantEvalResult::NewSamePhase(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); +} + +auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::ImplWitnessAccess inst) -> ConstantEvalResult { + // This is PerformAggregateAccess followed by GetConstantInSpecific. + if (auto witness = + context.insts().TryGetAs(inst.witness_id)) { + auto elements = context.inst_blocks().Get(witness->elements_id); + auto index = static_cast(inst.index.index); + CARBON_CHECK(index < elements.size(), "Access out of bounds."); + auto element = elements[index]; + if (!element.has_value()) { + // TODO: Perhaps this should be a `{}` value with incomplete type? + CARBON_DIAGNOSTIC(ImplAccessMemberBeforeComplete, Error, + "accessing member from impl before the end of " + "its definition"); + // TODO: Add note pointing to the impl declaration. + context.emitter().Emit(loc, ImplAccessMemberBeforeComplete); + return ConstantEvalResult::Error; + } + + LoadImportRef(context, element); + return ConstantEvalResult::Existing(GetConstantValueInSpecific( + context.sem_ir(), witness->specific_id, element)); + } + + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::ImportRefUnloaded inst) -> ConstantEvalResult { + CARBON_FATAL("ImportRefUnloaded should be loaded before TryEvalInst: {0}", + inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::InitializeFrom inst) -> ConstantEvalResult { + // Initialization is not performed in-place during constant evaluation, so + // just return the value of the initializer. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.src_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc loc, SemIR::IntType inst) + -> ConstantEvalResult { + return ValidateIntType(context, loc, inst) + ? ConstantEvalResult::NewSamePhase(inst) + : ConstantEvalResult::Error; +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::InterfaceDecl inst) -> ConstantEvalResult { + // If the interface has generic parameters, we don't produce an interface + // type, but a callable whose return value is an interface type. + if (context.interfaces().Get(inst.interface_id).has_parameters()) { + return ConstantEvalResult::NewSamePhase(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = SemIR::InstBlockId::Empty}); + } + + // A non-generic interface declaration evaluates to a facet type. + return ConstantEvalResult::NewSamePhase(FacetTypeFromInterface( + context, inst.interface_id, SemIR::SpecificId::None)); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, SemIR::NameRef inst) + -> ConstantEvalResult { + // A name reference evaluates to the value the name resolves to. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.value_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc loc, + SemIR::RequireCompleteType inst) -> ConstantEvalResult { + auto witness_type_id = + GetSingletonType(context, SemIR::WitnessType::SingletonInstId); + + // If the type is a concrete constant, require it to be complete now. + auto complete_type_id = inst.complete_type_id; + if (context.types().GetConstantId(complete_type_id).is_concrete()) { + if (!TryToCompleteType(context, complete_type_id, loc, [&] { + // TODO: It'd be nice to report the original type prior to + // evaluation here. + CARBON_DIAGNOSTIC(IncompleteTypeInMonomorphization, Error, + "type {0} is incomplete", SemIR::TypeId); + return context.emitter().Build(loc, IncompleteTypeInMonomorphization, + complete_type_id); + })) { + return ConstantEvalResult::Error; + } + return ConstantEvalResult::NewSamePhase(SemIR::CompleteTypeWitness{ + .type_id = witness_type_id, + .object_repr_id = context.types().GetObjectRepr(complete_type_id)}); + } + + // If it's not a concrete constant, require it to be complete once it + // becomes one. + return ConstantEvalResult::NewSamePhase(inst); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::SpecificConstant inst) -> ConstantEvalResult { + // Pull the constant value out of the specific. + return ConstantEvalResult::Existing(SemIR::GetConstantValueInSpecific( + context.sem_ir(), inst.specific_id, inst.inst_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::SpliceBlock inst) -> ConstantEvalResult { + // SpliceBlock evaluates to the result value that is (typically) within the + // block. This can be constant even if the block contains other non-constant + // instructions. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.result_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::StructAccess inst) -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::StructInit inst) -> ConstantEvalResult { + return ConstantEvalResult::NewSamePhase(SemIR::StructValue{ + .type_id = inst.type_id, .elements_id = inst.elements_id}); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::Temporary /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. Can we just return the value of `init_id`? + return ConstantEvalResult::TODO; +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::TupleAccess inst) -> ConstantEvalResult { + return PerformAggregateAccess(context, inst); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::TupleInit inst) -> ConstantEvalResult { + return ConstantEvalResult::NewSamePhase(SemIR::TupleValue{ + .type_id = inst.type_id, .elements_id = inst.elements_id}); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::UnaryOperatorNot inst) -> ConstantEvalResult { + // `not true` -> `false`, `not false` -> `true`. + // All other uses of unary `not` are non-constant. + auto const_id = context.constant_values().Get(inst.operand_id); + if (const_id.is_concrete()) { + auto value = context.insts().GetAs( + context.constant_values().GetInstId(const_id)); + value.value = SemIR::BoolValue::From(!value.value.ToBool()); + return ConstantEvalResult::NewSamePhase(value); + } + return ConstantEvalResult::NotConstant; +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ValueOfInitializer inst) -> ConstantEvalResult { + // Values of value expressions and initializing expressions are represented in + // the same way during constant evaluation, so just return the value of the + // operand. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.init_id)); +} + +auto EvalConstantInst(Context& context, SemIRLoc /*loc*/, + SemIR::ValueParamPattern inst) -> ConstantEvalResult { + // TODO: Treat this as a non-expression (here and in GetExprCategory) + // once generic deduction doesn't need patterns to have constant values. + return ConstantEvalResult::Existing( + context.constant_values().Get(inst.subpattern_id)); +} + +auto EvalConstantInst(Context& /*context*/, SemIRLoc /*loc*/, + SemIR::VtablePtr /*inst*/) -> ConstantEvalResult { + // TODO: Handle this. + return ConstantEvalResult::TODO; +} + +} // namespace Carbon::Check diff --git a/toolchain/check/eval_inst.h b/toolchain/check/eval_inst.h new file mode 100644 index 0000000000000..058de381c7f9b --- /dev/null +++ b/toolchain/check/eval_inst.h @@ -0,0 +1,123 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_CHECK_EVAL_INST_H_ +#define CARBON_TOOLCHAIN_CHECK_EVAL_INST_H_ + +#include "toolchain/check/eval.h" + +namespace Carbon::Check { + +// The result of constant evaluation of an instruction. +class ConstantEvalResult { + public: + // Produce a new constant as the result of an evaluation. The phase of the + // produced constant must be the same as the greatest phase of the operands in + // the evaluation. This will typically be the case if the evaluation uses all + // of its operands. + static auto NewSamePhase(SemIR::Inst inst) -> ConstantEvalResult { + return ConstantEvalResult(inst, /*same_phase_as_inst=*/true); + } + + // Produce a new constant as the result of an evaluation. The constant may + // have any phase. Use `NewSamePhase` instead where possible, as it avoids a + // phase recomputation. + static auto NewAnyPhase(SemIR::Inst inst) -> ConstantEvalResult { + return ConstantEvalResult(inst, /*same_phase_as_inst=*/false); + } + + // Produce an existing constant as the result of an evaluation. + static constexpr auto Existing(SemIR::ConstantId existing_id) + -> ConstantEvalResult { + CARBON_CHECK(existing_id.is_constant()); + return ConstantEvalResult(existing_id); + } + + // Indicates that an error was produced by evaluation. + static const ConstantEvalResult Error; + + // Indicates that we encountered an instruction whose evaluation is + // non-constant despite having constant operands. This should be rare; + // usually we want to produce an error in this case. + static const ConstantEvalResult NotConstant; + + // Indicates that we encountered an instruction for which we've not + // implemented constant evaluation yet. Instruction is treated as not + // constant. + static const ConstantEvalResult TODO; + + // Returns whether the result of evaluation is that we should produce a new + // constant described by `new_inst()` rather than an existing `ConstantId` + // described by `existing()`. + auto is_new() const -> bool { return !result_id_.has_value(); } + + // Returns the existing constant that this the instruction evaluates to, or + // `None` if this is evaluation produces a new constant. + auto existing() const -> SemIR::ConstantId { return result_id_; } + + // Returns the new constant instruction that is the result of evaluation. + auto new_inst() const -> SemIR::Inst { + CARBON_CHECK(is_new()); + return new_inst_; + } + + // Whether the new constant instruction is known to have the same phase as the + // evaluated instruction. Requires `is_new()`. + auto same_phase_as_inst() const -> bool { + CARBON_CHECK(is_new()); + return same_phase_as_inst_; + } + + private: + constexpr explicit ConstantEvalResult(SemIR::ConstantId raw_id) + : result_id_(raw_id), same_phase_as_inst_(false) {} + + explicit ConstantEvalResult(SemIR::Inst inst, bool same_phase_as_inst) + : result_id_(SemIR::ConstantId::None), + new_inst_(inst), + same_phase_as_inst_(same_phase_as_inst) {} + + SemIR::ConstantId result_id_; + union { + SemIR::Inst new_inst_; + }; + bool same_phase_as_inst_; +}; + +constexpr ConstantEvalResult ConstantEvalResult::Error = + Existing(SemIR::ErrorInst::SingletonConstantId); + +constexpr ConstantEvalResult ConstantEvalResult::NotConstant = + ConstantEvalResult(SemIR::ConstantId::NotConstant); + +constexpr ConstantEvalResult ConstantEvalResult::TODO = NotConstant; + +// `EvalConstantInst` evaluates an instruction whose operands are all constant, +// in a context unrelated to the enclosing evaluation. The function is given the +// instruction after its operands, including its type, are replaced by their +// evaluated value, and returns a `ConstantEvalResult` describing the result of +// evaluating the instruction. +// +// An overload is defined for each type whose constant kind is one of the +// following: +// +// - InstConstantKind::Indirect +// - InstConstantKind::SymbolicOnly +// - InstConstantKind::Conditional +// +// ... except for cases where the result of evaluation depends on the evaluation +// context itself. Those cases are handled by explicit specialization of +// `TryEvalTypedInst` in `eval.cpp` instead. +// +// Overloads are *declared* for all types, because there isn't a good way to +// declare only the overloads we want here without duplicating the list of +// types. Missing overloads will be diagnosed when linking. +#define CARBON_SEM_IR_INST_KIND(Kind) \ + auto EvalConstantInst(Context& context, SemIRLoc loc, SemIR::Kind inst) \ + -> ConstantEvalResult; +#include "toolchain/sem_ir/inst_kind.def" + +} // namespace Carbon::Check + +#endif // CARBON_TOOLCHAIN_CHECK_EVAL_INST_H_ diff --git a/toolchain/check/type.cpp b/toolchain/check/type.cpp index 9e54c936a4b6b..2d4ee442ff2bf 100644 --- a/toolchain/check/type.cpp +++ b/toolchain/check/type.cpp @@ -10,6 +10,64 @@ namespace Carbon::Check { +// Enforces that an integer type has a valid bit width. +auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result) + -> bool { + auto bit_width = + context.insts().TryGetAs(result.bit_width_id); + if (!bit_width) { + // Symbolic bit width. + return true; + } + const auto& bit_width_val = context.ints().Get(bit_width->int_id); + if (bit_width_val.isZero() || + (context.types().IsSignedInt(bit_width->type_id) && + bit_width_val.isNegative())) { + CARBON_DIAGNOSTIC(IntWidthNotPositive, Error, + "integer type width of {0} is not positive", TypedInt); + context.emitter().Emit( + loc, IntWidthNotPositive, + {.type = bit_width->type_id, .value = bit_width_val}); + return false; + } + if (bit_width_val.ugt(IntStore::MaxIntWidth)) { + CARBON_DIAGNOSTIC(IntWidthTooLarge, Error, + "integer type width of {0} is greater than the " + "maximum supported width of {1}", + TypedInt, int); + context.emitter().Emit(loc, IntWidthTooLarge, + {.type = bit_width->type_id, .value = bit_width_val}, + IntStore::MaxIntWidth); + return false; + } + return true; +} + +// Enforces that the bit width is 64 for a float. +auto ValidateFloatBitWidth(Context& context, SemIRLoc loc, + SemIR::InstId inst_id) -> bool { + auto inst = context.insts().GetAs(inst_id); + if (context.ints().Get(inst.int_id) == 64) { + return true; + } + + CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "bit width must be 64"); + context.emitter().Emit(loc, CompileTimeFloatBitWidth); + return false; +} + +// Enforces that a float type has a valid bit width. +auto ValidateFloatType(Context& context, SemIRLoc loc, SemIR::FloatType result) + -> bool { + auto bit_width = + context.insts().TryGetAs(result.bit_width_id); + if (!bit_width) { + // Symbolic bit width. + return true; + } + return ValidateFloatBitWidth(context, loc, result.bit_width_id); +} + // Gets or forms a type_id for a type, given the instruction kind and arguments. template static auto GetTypeImpl(Context& context, EachArgT... each_arg) diff --git a/toolchain/check/type.h b/toolchain/check/type.h index 8d7f7ee77055b..93128f9f42c0a 100644 --- a/toolchain/check/type.h +++ b/toolchain/check/type.h @@ -11,6 +11,18 @@ namespace Carbon::Check { +// Enforces that an integer type has a valid bit width. +auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result) + -> bool; + +// Enforces that the bit width is 64 for a float. +auto ValidateFloatBitWidth(Context& context, SemIRLoc loc, + SemIR::InstId inst_id) -> bool; + +// Enforces that a float type has a valid bit width. +auto ValidateFloatType(Context& context, SemIRLoc loc, SemIR::FloatType result) + -> bool; + // Gets the type to use for an unbound associated entity declared in this // interface. For example, this is the type of `I.T` after // `interface I { let T:! type; }`. The name of the interface is used for From 43b9969058b3de2e0b05896ef8e4489c1dc85cb6 Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Fri, 28 Feb 2025 09:06:13 +0100 Subject: [PATCH 43/56] Split `impl/no_prelude/name_poisoning.carbon` to `interface/no_prelude/name_poisoning.carbon` and move `interface` tests there (#5031) See https://github.com/carbon-language/carbon-lang/pull/4950#discussion_r1972252460. Part of #4622. --- .../impl/no_prelude/name_poisoning.carbon | 866 ----------------- .../no_prelude/name_poisoning.carbon | 876 ++++++++++++++++++ 2 files changed, 876 insertions(+), 866 deletions(-) create mode 100644 toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon index 15e56a682d709..31bdb33974c60 100644 --- a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -8,218 +8,6 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon -// --- no_poison.carbon - -library "[[@TEST_NAME]]"; - -interface I; - -// `N.F` uses `N.I` and not `package.I`. -namespace N; -interface N.I {} -fn N.F(x:! I) {} - -fn TestCall(x:! N.I) { - // `N.F` accepts an `N.I` not a `package.I`. - N.F(x); -} - -// --- poison.carbon - -library "[[@TEST_NAME]]"; - -interface I; - -namespace N; -// Use `package.I` and poison `N.I`. -fn N.F(x:! I); - -// --- fail_declare_after_poison.carbon - -library "[[@TEST_NAME]]"; - -interface I; - -namespace N; -// Use `package.I` and poison `N.I`. -// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x:! I); -// CHECK:STDERR: ^ -fn N.F(x:! I); - -// Failure: N.I declared after it was poisoned. -// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface N.I {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -interface N.I {} - -// --- fail_use_poison.carbon - -library "[[@TEST_NAME]]"; - -interface I; - -namespace N; -// Use `package.I` and poison `N.I`. -fn N.F1(x:! I); - -// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] -// CHECK:STDERR: fn N.F2(x:! N.I); -// CHECK:STDERR: ^~~ -// CHECK:STDERR: -fn N.F2(x:! N.I); - -// --- fail_use_declaration_after_poison.carbon - -library "[[@TEST_NAME]]"; - -interface I; - -namespace N; -// Use `package.I` and poison `N.I`. -// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F1(x:! I); -// CHECK:STDERR: ^ -fn N.F1(x:! I); - -// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface N.I; -// CHECK:STDERR: ^ -// CHECK:STDERR: -interface N.I; - -// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] -// CHECK:STDERR: fn N.F2(x:! N.I); -// CHECK:STDERR: ^~~ -// CHECK:STDERR: -fn N.F2(x:! N.I); - -// --- fail_alias.carbon - -library "[[@TEST_NAME]]"; - -interface I; -namespace N; - -// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: alias N.I = I; -// CHECK:STDERR: ^ -// CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: alias N.I = I; -// CHECK:STDERR: ^ -// CHECK:STDERR: -alias N.I = I; - -// --- fail_poison_multiple_scopes.carbon - -library "[[@TEST_NAME]]"; - -interface I1; - -interface I2 { - interface I3 { - interface I4 { - // Use `package.I1` and poison: - // * `I2.I1` - // * `I2.I3.I1` - // * `I2.I3.I4.I1` - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x:! I1); - // CHECK:STDERR: ^~ - fn F(x:! I1); - - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: interface I1; - // CHECK:STDERR: ^~ - // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x:! I1); - // CHECK:STDERR: ^~ - interface I1; - } - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:15: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: interface I1; - // CHECK:STDERR: ^~ - // CHECK:STDERR: - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: fn F(x:! I1); - // CHECK:STDERR: ^~ - interface I1; - } - // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: interface I1; - // CHECK:STDERR: ^~ - // CHECK:STDERR: - interface I1; -} - -// --- ignored_poison_in_import.carbon - -library "[[@TEST_NAME]]"; -import library "poison"; - -// This doesn't fail. -interface N.I; - -// --- poison.impl.carbon - -impl library "[[@TEST_NAME]]"; - -// TODO: #4622 This should fail since `N.I` was poisoned in the api. -interface N.I; - -// --- fail_poison_when_lookup_fails.carbon - -library "[[@TEST_NAME]]"; - -namespace N; -// `package.I` and `N.I` poisoned when not found. -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:12: error: name `I` not found [NameNotFound] -// CHECK:STDERR: fn N.F(x:! I); -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x:! I); -// CHECK:STDERR: ^ -fn N.F(x:! I); - -// TODO: We should ideally only produce one diagnostic here. -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface I; -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn N.F(x:! I); -// CHECK:STDERR: ^ -interface I; -// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: interface N.I; -// CHECK:STDERR: ^ -// CHECK:STDERR: -interface N.I; - -// --- fail_poison_with_lexical_result.carbon - -library "[[@TEST_NAME]]"; - -fn F() { - interface I1 {} - - class C { - // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:12: error: name `I1` used before it was declared [NameUseBeforeDecl] - // CHECK:STDERR: var v: I1; - // CHECK:STDERR: ^~ - var v: I1; - - // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:15: note: declared here [NameUseBeforeDeclNote] - // CHECK:STDERR: interface I1; - // CHECK:STDERR: ^~ - // CHECK:STDERR: - interface I1; - } -} - // --- using_poisoned_name_in_impl.carbon library "[[@TEST_NAME]]"; @@ -235,660 +23,6 @@ class N.C { } } -// CHECK:STDOUT: --- no_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %x: %I.type.4da = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] -// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] -// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%x) [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .TestCall = %TestCall.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc8 -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc8: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc9_8.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc9_8.1, runtime_param [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: %x.loc9_8.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc9_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { -// CHECK:STDOUT: %x.patt.loc11_13.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc11_13.1, runtime_param [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param -// CHECK:STDOUT: %.loc11: type = splice_block %I.ref [concrete = constants.%I.type.4da] { -// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x.loc11_13.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2 { -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc9_8.1: %I.type.4da) { -// CHECK:STDOUT: %x.loc9_8.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc9_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc9_8.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @TestCall(%x.loc11_13.1: %I.type.4da) { -// CHECK:STDOUT: %x.loc11_13.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_13.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %F.specific_fn.loc13_4.2: = specific_function constants.%F, @F(%x.loc11_13.2) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %x.ref: %I.type.4da = name_ref x, %x.loc11_13.1 [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: %F.specific_fn.loc13_4.1: = specific_function %F.ref, @F(constants.%x) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] -// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn.loc13_4.1() -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc9_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc9_8.2 => constants.%x -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @TestCall(constants.%x) { -// CHECK:STDOUT: %x.loc11_13.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_13.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(@TestCall.%x.loc11_13.2) {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc8_8.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_8.1, runtime_param [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %x.loc8_8.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc8_8.1: %I.type) { -// CHECK:STDOUT: %x.loc8_8.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc8_8.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc8_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc8_8.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc11_8.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_8.1, runtime_param [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %x.loc11_8.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc18: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2 { -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc11_8.1: %I.type.733) { -// CHECK:STDOUT: %x.loc11_8.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_8.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc11_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_8.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt.3ad: %I.type = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt.loc14_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { -// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F2(%x: ) { -// CHECK:STDOUT: %x.patt.loc14_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F1(constants.%x) { -// CHECK:STDOUT: %x.loc8_9.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F2() { -// CHECK:STDOUT: %x.patt.loc14_9.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt.3ad: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt.loc11_9.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_9.1, runtime_param [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %x.loc11_9.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_9.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt.loc23_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F1(%x.loc11_9.1: %I.type.733) { -// CHECK:STDOUT: %x.loc11_9.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_9.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_9.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F2(%x: ) { -// CHECK:STDOUT: %x.patt.loc23_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F1(constants.%x) { -// CHECK:STDOUT: %x.loc11_9.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_9.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F2() { -// CHECK:STDOUT: %x.patt.loc23_9.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_alias.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.ref: type = name_ref I, %I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %I: type = bind_alias I, %I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I1.type.80c: type = facet_type <@I1.1> [concrete] -// CHECK:STDOUT: %I2.type: type = facet_type <@I2> [concrete] -// CHECK:STDOUT: %Self.c7b: %I2.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %I3.type.07a: type = facet_type <@I3> [concrete] -// CHECK:STDOUT: %I3.type.b2f: type = facet_type <@I3, @I3(%Self.c7b)> [symbolic] -// CHECK:STDOUT: %Self.60c: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic] -// CHECK:STDOUT: %I4.type.451: type = facet_type <@I4> [concrete] -// CHECK:STDOUT: %I4.type.78e: type = facet_type <@I4, @I4(%Self.c7b, %Self.60c)> [symbolic] -// CHECK:STDOUT: %Self.a4d: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic] -// CHECK:STDOUT: %x: %I1.type.80c = bind_symbolic_name x, 3 [symbolic] -// CHECK:STDOUT: %x.patt: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.c7b, %Self.60c) [symbolic] -// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] -// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type %I4.type.78e [symbolic] -// CHECK:STDOUT: %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%F.decl [symbolic] -// CHECK:STDOUT: %I1.type.f4e: type = facet_type <@I1.2> [concrete] -// CHECK:STDOUT: %I1.type.575: type = facet_type <@I1.3> [concrete] -// CHECK:STDOUT: %I1.type.e5b: type = facet_type <@I1.4> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I1 = %I1.decl -// CHECK:STDOUT: .I2 = %I2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.80c] {} {} -// CHECK:STDOUT: %I2.decl: type = interface_decl @I2 [concrete = constants.%I2.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I2 { -// CHECK:STDOUT: %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.c7b] -// CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [concrete = constants.%I3.type.07a] {} {} -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.4 [concrete = constants.%I1.type.e5b] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .I3 = %I3.decl -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I3(@I2.%Self: %I2.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] -// CHECK:STDOUT: %I3.type: type = facet_type <@I3, @I3(%Self.2)> [symbolic = %I3.type (constants.%I3.type.b2f)] -// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: -// CHECK:STDOUT: interface { -// CHECK:STDOUT: %Self.1: @I3.%I3.type (%I3.type.b2f) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [concrete = constants.%I4.type.451] {} {} -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.3 [concrete = constants.%I1.type.575] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self.1 -// CHECK:STDOUT: .I4 = %I4.decl -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I4(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] -// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: %I4.type: type = facet_type <@I4, @I4(%Self.2, %Self.3)> [symbolic = %I4.type (constants.%I4.type.78e)] -// CHECK:STDOUT: %Self.4: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.2, %Self.3) [symbolic = %F.type (constants.%F.type)] -// CHECK:STDOUT: %F: @I4.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] -// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type @I4.%I4.type (%I4.type.78e) [symbolic = %I4.assoc_type (constants.%I4.assoc_type)] -// CHECK:STDOUT: %assoc0.loc16_19.2: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] -// CHECK:STDOUT: -// CHECK:STDOUT: interface { -// CHECK:STDOUT: %Self.1: @I4.%I4.type (%I4.type.78e) = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] -// CHECK:STDOUT: %F.decl: @I4.%F.type (%F.type) = fn_decl @F [symbolic = @I4.%F (constants.%F)] { -// CHECK:STDOUT: %x.patt.loc16_12.2: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I1.type.80c = value_param_pattern %x.patt.loc16_12.2, runtime_param [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I1.type.80c = value_param runtime_param -// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] -// CHECK:STDOUT: %x.loc16_12.2: %I1.type.80c = bind_symbolic_name x, 3, %x.param [symbolic = %x.loc16_12.1 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc0.loc16_19.1: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.f4e] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self.1 -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: .F = %assoc0.loc16_19.1 -// CHECK:STDOUT: witness = (%F.decl) -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.2(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.3(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.4(@I2.%Self: %I2.type) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e), %x.loc16_12.2: %I1.type.80c) { -// CHECK:STDOUT: %x.loc16_12.1: %I1.type.80c = bind_symbolic_name x, 3 [symbolic = %x.loc16_12.1 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc16_12.1: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I1.type.80c); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I3(constants.%Self.c7b) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I4(constants.%Self.c7b, constants.%Self.60c) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d, constants.%x) { -// CHECK:STDOUT: %x.loc16_12.1 => constants.%x -// CHECK:STDOUT: %x.patt.loc16_12.1 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.2(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I4(%Self.2, %Self.3) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.3(constants.%Self.c7b, constants.%Self.60c) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I3(%Self.2) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.4(constants.%Self.c7b) {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- ignored_poison_in_import.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .I = file.%I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = imports.%Main.I -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .I = file.%I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = imports.%Main.I -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import.loc2_6.1 = import -// CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %x.patt: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .I = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc13_8.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc23: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %I.decl.loc28: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x: ) { -// CHECK:STDOUT: %x.patt.loc13_8.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F() { -// CHECK:STDOUT: %x.patt.loc13_8.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I1.type.06a: type = facet_type <@I1.1> [concrete] -// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I1.type.06a [concrete] -// CHECK:STDOUT: %I1.type.8ea: type = facet_type <@I1.2> [concrete] -// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %I1.type.06a} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.1 { -// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.2; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %.loc11_10: %C.elem = field_decl v, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc11_5: %C.elem = var_pattern %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %C.elem = var -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.8ea] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: .v = %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.06a] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: --- using_poisoned_name_in_impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon new file mode 100644 index 0000000000000..25242e04c8c12 --- /dev/null +++ b/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon @@ -0,0 +1,876 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon + +// --- no_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +// `N.F` uses `N.I` and not `package.I`. +namespace N; +interface N.I {} +fn N.F(x:! I) {} + +fn TestCall(x:! N.I) { + // `N.F` accepts an `N.I` not a `package.I`. + N.F(x); +} + +// --- poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +fn N.F(x:! I); + +// --- fail_declare_after_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +fn N.F(x:! I); + +// Failure: N.I declared after it was poisoned. +// CHECK:STDERR: fail_declare_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I {} +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I {} + +// --- fail_use_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +fn N.F1(x:! I); + +// CHECK:STDERR: fail_use_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x:! N.I); +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2(x:! N.I); + +// --- fail_use_declaration_after_poison.carbon + +library "[[@TEST_NAME]]"; + +interface I; + +namespace N; +// Use `package.I` and poison `N.I`. +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+3]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F1(x:! I); +// CHECK:STDERR: ^ +fn N.F1(x:! I); + +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I; + +// CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:13: error: member name `I` not found in `N` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn N.F2(x:! N.I); +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn N.F2(x:! N.I); + +// --- fail_alias.carbon + +library "[[@TEST_NAME]]"; + +interface I; +namespace N; + +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:13: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: alias N.I = I; +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE+4]]:9: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: alias N.I = I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +alias N.I = I; + +// --- fail_poison_multiple_scopes.carbon + +library "[[@TEST_NAME]]"; + +interface I1; + +interface I2 { + interface I3 { + interface I4 { + // Use `package.I1` and poison: + // * `I2.I1` + // * `I2.I3.I1` + // * `I2.I3.I4.I1` + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+3]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ + fn F(x:! I1); + + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:17: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-6]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ + interface I1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+7]]:15: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE-15]]:16: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn F(x:! I1); + // CHECK:STDERR: ^~ + interface I1; + } + // CHECK:STDERR: fail_poison_multiple_scopes.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + interface I1; +} + +// --- ignored_poison_in_import.carbon + +library "[[@TEST_NAME]]"; +import library "poison"; + +// This doesn't fail. +interface N.I; + +// --- poison.impl.carbon + +impl library "[[@TEST_NAME]]"; + +// TODO: #4622 This should fail since `N.I` was poisoned in the api. +interface N.I; + +// --- fail_poison_when_lookup_fails.carbon + +library "[[@TEST_NAME]]"; + +namespace N; +// `package.I` and `N.I` poisoned when not found. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:12: error: name `I` not found [NameNotFound] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+3]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +fn N.F(x:! I); + +// TODO: We should ideally only produce one diagnostic here. +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+7]]:11: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE-7]]:12: error: name `I` used before it was declared [NameUseBeforeDecl] +// CHECK:STDERR: fn N.F(x:! I); +// CHECK:STDERR: ^ +interface I; +// CHECK:STDERR: fail_poison_when_lookup_fails.carbon:[[@LINE+4]]:13: note: declared here [NameUseBeforeDeclNote] +// CHECK:STDERR: interface N.I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface N.I; + +// --- fail_poison_with_lexical_result.carbon + +library "[[@TEST_NAME]]"; + +fn F() { + interface I1 {} + + class C { + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+3]]:12: error: name `I1` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: var v: I1; + // CHECK:STDERR: ^~ + var v: I1; + + // CHECK:STDERR: fail_poison_with_lexical_result.carbon:[[@LINE+4]]:15: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: interface I1; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + interface I1; + } +} + +// CHECK:STDOUT: --- no_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %x: %I.type.4da = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] +// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] +// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%x) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .TestCall = %TestCall.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc8 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc8: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt.loc9_8.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc9_8.1, runtime_param [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] +// CHECK:STDOUT: %x.loc9_8.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc9_8.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { +// CHECK:STDOUT: %x.patt.loc11_13.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc11_13.1, runtime_param [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param +// CHECK:STDOUT: %.loc11: type = splice_block %I.ref [concrete = constants.%I.type.4da] { +// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.loc11_13.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_13.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2 { +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(%x.loc9_8.1: %I.type.4da) { +// CHECK:STDOUT: %x.loc9_8.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc9_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc9_8.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @TestCall(%x.loc11_13.1: %I.type.4da) { +// CHECK:STDOUT: %x.loc11_13.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc11_13.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_13.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %F.specific_fn.loc13_4.2: = specific_function constants.%F, @F(%x.loc11_13.2) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: %I.type.4da = name_ref x, %x.loc11_13.1 [symbolic = %x.loc11_13.2 (constants.%x)] +// CHECK:STDOUT: %F.specific_fn.loc13_4.1: = specific_function %F.ref, @F(constants.%x) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn.loc13_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc9_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc9_8.2 => constants.%x +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @TestCall(constants.%x) { +// CHECK:STDOUT: %x.loc11_13.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_13.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(@TestCall.%x.loc11_13.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt.loc8_8.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_8.1, runtime_param [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %x.loc8_8.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_8.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(%x.loc8_8.1: %I.type) { +// CHECK:STDOUT: %x.loc8_8.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc8_8.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc8_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc8_8.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declare_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt.loc11_8.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_8.1, runtime_param [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %x.loc11_8.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_8.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc18: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2 { +// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(%x.loc11_8.1: %I.type.733) { +// CHECK:STDOUT: %x.loc11_8.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_8.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_8.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%x) { +// CHECK:STDOUT: %x.loc11_8.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_8.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt.3ad: %I.type = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %x.patt.loc14_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [concrete = ] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %.1: = splice_block [concrete = ] { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { +// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F2(%x: ) { +// CHECK:STDOUT: %x.patt.loc14_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F1(constants.%x) { +// CHECK:STDOUT: %x.loc8_9.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F2() { +// CHECK:STDOUT: %x.patt.loc14_9.2 => +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] +// CHECK:STDOUT: %x.patt.3ad: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] +// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] +// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl.loc4 +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F1 = %F1.decl +// CHECK:STDOUT: .N = +// CHECK:STDOUT: .F2 = %F2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { +// CHECK:STDOUT: %x.patt.loc11_9.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_9.1, runtime_param [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] +// CHECK:STDOUT: %x.loc11_9.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_9.2 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { +// CHECK:STDOUT: %x.patt.loc23_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [concrete = ] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %.1: = splice_block [concrete = ] { +// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F1(%x.loc11_9.1: %I.type.733) { +// CHECK:STDOUT: %x.loc11_9.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_9.2 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc11_9.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F2(%x: ) { +// CHECK:STDOUT: %x.patt.loc23_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F1(constants.%x) { +// CHECK:STDOUT: %x.loc11_9.2 => constants.%x +// CHECK:STDOUT: %x.patt.loc11_9.2 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F2() { +// CHECK:STDOUT: %x.patt.loc23_9.2 => +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.ref: type = name_ref I, %I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %I: type = bind_alias I, %I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I1.type.80c: type = facet_type <@I1.1> [concrete] +// CHECK:STDOUT: %I2.type: type = facet_type <@I2> [concrete] +// CHECK:STDOUT: %Self.c7b: %I2.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %I3.type.07a: type = facet_type <@I3> [concrete] +// CHECK:STDOUT: %I3.type.b2f: type = facet_type <@I3, @I3(%Self.c7b)> [symbolic] +// CHECK:STDOUT: %Self.60c: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %I4.type.451: type = facet_type <@I4> [concrete] +// CHECK:STDOUT: %I4.type.78e: type = facet_type <@I4, @I4(%Self.c7b, %Self.60c)> [symbolic] +// CHECK:STDOUT: %Self.a4d: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic] +// CHECK:STDOUT: %x: %I1.type.80c = bind_symbolic_name x, 3 [symbolic] +// CHECK:STDOUT: %x.patt: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.c7b, %Self.60c) [symbolic] +// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] +// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type %I4.type.78e [symbolic] +// CHECK:STDOUT: %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%F.decl [symbolic] +// CHECK:STDOUT: %I1.type.f4e: type = facet_type <@I1.2> [concrete] +// CHECK:STDOUT: %I1.type.575: type = facet_type <@I1.3> [concrete] +// CHECK:STDOUT: %I1.type.e5b: type = facet_type <@I1.4> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I1 = %I1.decl +// CHECK:STDOUT: .I2 = %I2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.80c] {} {} +// CHECK:STDOUT: %I2.decl: type = interface_decl @I2 [concrete = constants.%I2.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I2 { +// CHECK:STDOUT: %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.c7b] +// CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [concrete = constants.%I3.type.07a] {} {} +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.4 [concrete = constants.%I1.type.e5b] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .I3 = %I3.decl +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I3(@I2.%Self: %I2.type) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] +// CHECK:STDOUT: %I3.type: type = facet_type <@I3, @I3(%Self.2)> [symbolic = %I3.type (constants.%I3.type.b2f)] +// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I3.%I3.type (%I3.type.b2f) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [concrete = constants.%I4.type.451] {} {} +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.3 [concrete = constants.%I1.type.575] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .I4 = %I4.decl +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I4(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] +// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] +// CHECK:STDOUT: %I4.type: type = facet_type <@I4, @I4(%Self.2, %Self.3)> [symbolic = %I4.type (constants.%I4.type.78e)] +// CHECK:STDOUT: %Self.4: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] +// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.2, %Self.3) [symbolic = %F.type (constants.%F.type)] +// CHECK:STDOUT: %F: @I4.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type @I4.%I4.type (%I4.type.78e) [symbolic = %I4.assoc_type (constants.%I4.assoc_type)] +// CHECK:STDOUT: %assoc0.loc16_19.2: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I4.%I4.type (%I4.type.78e) = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] +// CHECK:STDOUT: %F.decl: @I4.%F.type (%F.type) = fn_decl @F [symbolic = @I4.%F (constants.%F)] { +// CHECK:STDOUT: %x.patt.loc16_12.2: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: %I1.type.80c = value_param_pattern %x.patt.loc16_12.2, runtime_param [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %I1.type.80c = value_param runtime_param +// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] +// CHECK:STDOUT: %x.loc16_12.2: %I1.type.80c = bind_symbolic_name x, 3, %x.param [symbolic = %x.loc16_12.1 (constants.%x)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc16_19.1: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.f4e] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: .F = %assoc0.loc16_19.1 +// CHECK:STDOUT: witness = (%F.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.2(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.3(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I1.4(@I2.%Self: %I2.type) { +// CHECK:STDOUT: interface; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e), %x.loc16_12.2: %I1.type.80c) { +// CHECK:STDOUT: %x.loc16_12.1: %I1.type.80c = bind_symbolic_name x, 3 [symbolic = %x.loc16_12.1 (constants.%x)] +// CHECK:STDOUT: %x.patt.loc16_12.1: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: %I1.type.80c); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I3(constants.%Self.c7b) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I4(constants.%Self.c7b, constants.%Self.60c) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d, constants.%x) { +// CHECK:STDOUT: %x.loc16_12.1 => constants.%x +// CHECK:STDOUT: %x.patt.loc16_12.1 => constants.%x +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.2(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I4(%Self.2, %Self.3) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.3(constants.%Self.c7b, constants.%Self.60c) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I3(%Self.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I1.4(constants.%Self.c7b) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- ignored_poison_in_import.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .I = file.%I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- poison.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded +// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded +// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { +// CHECK:STDOUT: .F = %Main.F +// CHECK:STDOUT: .I = file.%I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .N = imports.%N +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %x.patt: = symbolic_binding_pattern x, 0 [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] +// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .I = +// CHECK:STDOUT: } +// CHECK:STDOUT: %N: = namespace [concrete] { +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %x.patt.loc13_8.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] +// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [concrete = ] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: = value_param runtime_param +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl.loc23: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} +// CHECK:STDOUT: %I.decl.loc28: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.1; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I.2; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @F(%x: ) { +// CHECK:STDOUT: %x.patt.loc13_8.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: ); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F() { +// CHECK:STDOUT: %x.patt.loc13_8.2 => +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %I1.type.06a: type = facet_type <@I1.1> [concrete] +// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I1.type.06a [concrete] +// CHECK:STDOUT: %I1.type.8ea: type = facet_type <@I1.2> [concrete] +// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %I1.type.06a} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.1 { +// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I1.2; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %.loc11_10: %C.elem = field_decl v, element0 [concrete] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %.loc11_5: %C.elem = var_pattern %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.var: ref %C.elem = var +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.8ea] {} {} +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .I1 = +// CHECK:STDOUT: .v = %.loc11_10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.06a] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: From ec58a48994a2746a50307647d463c200dbd6531c Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 28 Feb 2025 11:34:48 -0800 Subject: [PATCH 44/56] Consolidate parse function tests (#5039) These tests pretty much predate split tests. There are lots of files as a result, and I think consolidation will help (hopefully others agree). --- .../{definition => }/decl_statement.carbon | 4 +- .../testdata/function/declaration.carbon | 424 ++++++++++++++++++ .../testdata/function/declaration/addr.carbon | 27 -- .../function/declaration/basic.carbon | 22 - .../fail_identifier_instead_of_sig.carbon | 24 - .../fail_missing_implicit_close.carbon | 29 -- .../declaration/fail_missing_name.carbon | 24 - .../declaration/fail_no_sig_or_semi.carbon | 24 - .../declaration/fail_only_fn_and_semi.carbon | 24 - .../fail_repeated_fn_and_semi.carbon | 24 - ...skip_indented_newline_until_outdent.carbon | 32 -- ...ail_skip_indented_newline_with_semi.carbon | 32 -- ..._skip_indented_newline_without_semi.carbon | 32 -- .../fail_skip_to_newline_without_semi.carbon | 30 -- .../fail_skip_without_semi_to_curly.carbon | 29 -- .../fail_with_identifier_as_param.carbon | 29 -- ...hout_name_and_many_tokens_in_params.carbon | 24 - .../function/declaration/impl_fn.carbon | 48 -- .../declaration/implicit_empty.carbon | 24 - .../declaration/implicit_params.carbon | 31 -- .../function/declaration/no_params.carbon | 21 - .../function/declaration/params.carbon | 29 -- .../declaration/with_return_type.carbon | 24 - .../parse/testdata/function/definition.carbon | 240 ++++++++++ .../testdata/function/definition/basic.carbon | 23 - .../function/definition/builtin.carbon | 41 -- .../function/definition/extern.carbon | 44 -- .../function/definition/fail_builtin.carbon | 57 --- .../fail_identifier_in_statements.carbon | 33 -- .../function/definition/nested.carbon | 39 -- .../function/definition/with_params.carbon | 41 -- .../definition/with_return_type.carbon | 30 -- .../function/{declaration => }/extern.carbon | 38 +- 33 files changed, 702 insertions(+), 895 deletions(-) rename toolchain/parse/testdata/function/{definition => }/decl_statement.carbon (98%) create mode 100644 toolchain/parse/testdata/function/declaration.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/addr.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/basic.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_missing_name.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/impl_fn.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/implicit_empty.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/implicit_params.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/no_params.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/params.carbon delete mode 100644 toolchain/parse/testdata/function/declaration/with_return_type.carbon create mode 100644 toolchain/parse/testdata/function/definition.carbon delete mode 100644 toolchain/parse/testdata/function/definition/basic.carbon delete mode 100644 toolchain/parse/testdata/function/definition/builtin.carbon delete mode 100644 toolchain/parse/testdata/function/definition/extern.carbon delete mode 100644 toolchain/parse/testdata/function/definition/fail_builtin.carbon delete mode 100644 toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon delete mode 100644 toolchain/parse/testdata/function/definition/nested.carbon delete mode 100644 toolchain/parse/testdata/function/definition/with_params.carbon delete mode 100644 toolchain/parse/testdata/function/definition/with_return_type.carbon rename toolchain/parse/testdata/function/{declaration => }/extern.carbon (73%) diff --git a/toolchain/parse/testdata/function/definition/decl_statement.carbon b/toolchain/parse/testdata/function/decl_statement.carbon similarity index 98% rename from toolchain/parse/testdata/function/definition/decl_statement.carbon rename to toolchain/parse/testdata/function/decl_statement.carbon index 92d0104dafaca..f188ae5e2c5ee 100644 --- a/toolchain/parse/testdata/function/definition/decl_statement.carbon +++ b/toolchain/parse/testdata/function/decl_statement.carbon @@ -4,9 +4,9 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/decl_statement.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/decl_statement.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/decl_statement.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/decl_statement.carbon // --- valid.carbon diff --git a/toolchain/parse/testdata/function/declaration.carbon b/toolchain/parse/testdata/function/declaration.carbon new file mode 100644 index 0000000000000..6eb8ce089e7be --- /dev/null +++ b/toolchain/parse/testdata/function/declaration.carbon @@ -0,0 +1,424 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration.carbon + +// --- basic.carbon + +fn F(); + +// --- addr.carbon + +fn foo(addr a: i32*); + +// --- implicit_empty.carbon + +fn foo[](); + +// --- implicit_params.carbon + +fn foo[a: i32, b: i32](); + +// --- no_params.carbon + +fn foo {} + +// --- params.carbon + +fn foo(a: i32, b: i32); + +// --- with_return_type.carbon + +fn foo() -> u32; + +// --- impl_fn.carbon + +impl fn F(); +abstract impl fn G(); +impl abstract fn H(); +private impl default fn I(); + +// --- fail_identifier_instead_of_sig.carbon + +// CHECK:STDERR: fail_identifier_instead_of_sig.carbon:[[@LINE+4]]:8: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] +// CHECK:STDERR: fn foo bar; +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +fn foo bar; + +// --- fail_missing_implicit_close.carbon + +// CHECK:STDERR: fail_missing_implicit_close.carbon:[[@LINE+8]]:7: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] +// CHECK:STDERR: fn Div[(); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_missing_implicit_close.carbon:[[@LINE+4]]:7: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] +// CHECK:STDERR: fn Div[(); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn Div[(); + +// --- fail_missing_name.carbon + +// CHECK:STDERR: fail_missing_name.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn (); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn (); + +// --- fail_no_sig_or_semi.carbon + +fn foo +// CHECK:STDERR: fail_no_sig_or_semi.carbon:[[@LINE+4]]:1: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] +// CHECK:STDERR: +// CHECK:STDERR: ^ +// CHECK:STDERR: + +// --- fail_only_fn_and_semi.carbon + +// CHECK:STDERR: fail_only_fn_and_semi.carbon:[[@LINE+4]]:3: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn; +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn; + +// --- fail_repeated_fn_and_semi.carbon + +// CHECK:STDERR: fail_repeated_fn_and_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn fn; +// CHECK:STDERR: ^~ +// CHECK:STDERR: +fn fn; + +// --- fail_skip_indented_newline_until_outdent.carbon + + // CHECK:STDERR: fail_skip_indented_newline_until_outdent.carbon:[[@LINE+4]]:6: error: `fn` introducer should be followed by a name [ExpectedDeclName] + // CHECK:STDERR: fn (x, + // CHECK:STDERR: ^ + // CHECK:STDERR: + fn (x, + y, + z) +fn F(); + +// --- fail_skip_indented_newline_with_semi.carbon + +// CHECK:STDERR: fail_skip_indented_newline_with_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn (x, +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn (x, + y, + z); +fn F(); + +// --- fail_skip_indented_newline_without_semi.carbon + +// CHECK:STDERR: fail_skip_indented_newline_without_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn (x, +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn (x, + y, + z) +fn F(); + +// --- fail_skip_to_newline_without_semi.carbon + +// CHECK:STDERR: fail_skip_to_newline_without_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn () +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn () +fn F(); + +// --- fail_skip_without_semi_to_curly.carbon + +// CHECK:STDERR: fail_skip_without_semi_to_curly.carbon:[[@LINE+4]]:1: error: unrecognized declaration introducer [UnrecognizedDecl] +// CHECK:STDERR: struct X { fn () } +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: +struct X { fn () } +fn F(); + +// --- fail_with_identifier_as_param.carbon + +// CHECK:STDERR: fail_with_identifier_as_param.carbon:[[@LINE+4]]:11: error: expected `:` or `:!` in binding pattern [ExpectedBindingPattern] +// CHECK:STDERR: fn foo(bar); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn foo(bar); + +// --- fail_without_name_and_many_tokens_in_params.carbon + +// CHECK:STDERR: fail_without_name_and_many_tokens_in_params.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z); + +// CHECK:STDOUT: - filename: basic.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: addr.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'Addr', text: 'addr', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: implicit_empty.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['}, +// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: implicit_params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'b'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: no_params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'b'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: with_return_type.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'UnsignedIntTypeLiteral', text: 'u32'}, +// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: impl_fn.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'}, +// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, +// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'PrivateModifier', text: 'private'}, +// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, +// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'I'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_identifier_instead_of_sig.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_missing_implicit_close.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Div'}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_missing_name.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_no_sig_or_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: 'fn', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_only_fn_and_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_repeated_fn_and_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: 'fn', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_skip_indented_newline_until_outdent.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_skip_indented_newline_with_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_skip_indented_newline_without_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_skip_to_newline_without_semi.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_skip_without_semi_to_curly.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'InvalidParseStart', text: 'struct', has_error: yes}, +// CHECK:STDOUT: {kind: 'InvalidParseSubtree', text: '}', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_with_identifier_as_param.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'bar'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: 'bar', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_without_name_and_many_tokens_in_params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/addr.carbon b/toolchain/parse/testdata/function/declaration/addr.carbon deleted file mode 100644 index 5d4a6ef64686c..0000000000000 --- a/toolchain/parse/testdata/function/declaration/addr.carbon +++ /dev/null @@ -1,27 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/addr.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/addr.carbon - -fn foo(addr a: i32*); - -// CHECK:STDOUT: - filename: addr.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'Addr', text: 'addr', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 10}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/basic.carbon b/toolchain/parse/testdata/function/declaration/basic.carbon deleted file mode 100644 index a10a1f2a86315..0000000000000 --- a/toolchain/parse/testdata/function/declaration/basic.carbon +++ /dev/null @@ -1,22 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/basic.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/basic.carbon - -fn F(); - -// CHECK:STDOUT: - filename: basic.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon b/toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon deleted file mode 100644 index faeed0a495bb1..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_identifier_instead_of_sig.carbon - -// CHECK:STDERR: fail_identifier_instead_of_sig.carbon:[[@LINE+4]]:8: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] -// CHECK:STDERR: fn foo bar; -// CHECK:STDERR: ^~~ -// CHECK:STDERR: -fn foo bar; - -// CHECK:STDOUT: - filename: fail_identifier_instead_of_sig.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon b/toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon deleted file mode 100644 index 719c393789ada..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_missing_implicit_close.carbon - -// Fix and uncomment this to test error handling. -// CHECK:STDERR: fail_missing_implicit_close.carbon:[[@LINE+8]]:7: error: opening symbol without a corresponding closing symbol [UnmatchedOpening] -// CHECK:STDERR: fn Div[(); -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_missing_implicit_close.carbon:[[@LINE+4]]:7: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] -// CHECK:STDERR: fn Div[(); -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn Div[(); - -// CHECK:STDOUT: - filename: fail_missing_implicit_close.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Div'}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_missing_name.carbon b/toolchain/parse/testdata/function/declaration/fail_missing_name.carbon deleted file mode 100644 index d71fc4b01eca9..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_missing_name.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_missing_name.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_missing_name.carbon - -// CHECK:STDERR: fail_missing_name.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn (); -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn (); - -// CHECK:STDOUT: - filename: fail_missing_name.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon deleted file mode 100644 index b74fb4b2aefda..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_no_sig_or_semi.carbon - -fn foo - -// CHECK:STDERR: fail_no_sig_or_semi.carbon:[[@LINE+11]]:21: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition] -// CHECK:STDERR: // CHECK:STDOUT: ] -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDOUT: - filename: fail_no_sig_or_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: 'fn', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon deleted file mode 100644 index 08286af1ae52a..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_only_fn_and_semi.carbon - -// CHECK:STDERR: fail_only_fn_and_semi.carbon:[[@LINE+4]]:3: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn; -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn; - -// CHECK:STDOUT: - filename: fail_only_fn_and_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon deleted file mode 100644 index dc423b057bf36..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_repeated_fn_and_semi.carbon - -// CHECK:STDERR: fail_repeated_fn_and_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn fn; -// CHECK:STDERR: ^~ -// CHECK:STDERR: -fn fn; - -// CHECK:STDOUT: - filename: fail_repeated_fn_and_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: 'fn', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon b/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon deleted file mode 100644 index cc936397bd217..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon +++ /dev/null @@ -1,32 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_until_outdent.carbon - - // CHECK:STDERR: fail_skip_indented_newline_until_outdent.carbon:[[@LINE+4]]:6: error: `fn` introducer should be followed by a name [ExpectedDeclName] - // CHECK:STDERR: fn (x, - // CHECK:STDERR: ^ - // CHECK:STDERR: - fn (x, - y, - z) -fn F(); - -// CHECK:STDOUT: - filename: fail_skip_indented_newline_until_outdent.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon deleted file mode 100644 index 5d739de8f0a68..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon +++ /dev/null @@ -1,32 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_with_semi.carbon - -// CHECK:STDERR: fail_skip_indented_newline_with_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn (x, -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn (x, - y, - z); -fn F(); - -// CHECK:STDOUT: - filename: fail_skip_indented_newline_with_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon deleted file mode 100644 index 783b03fef6481..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon +++ /dev/null @@ -1,32 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_skip_indented_newline_without_semi.carbon - -// CHECK:STDERR: fail_skip_indented_newline_without_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn (x, -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn (x, - y, - z) -fn F(); - -// CHECK:STDOUT: - filename: fail_skip_indented_newline_without_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon b/toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon deleted file mode 100644 index 14821be29e69a..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon +++ /dev/null @@ -1,30 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_skip_to_newline_without_semi.carbon - -// CHECK:STDERR: fail_skip_to_newline_without_semi.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn () -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn () -fn F(); - -// CHECK:STDOUT: - filename: fail_skip_to_newline_without_semi.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ')', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon b/toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon deleted file mode 100644 index 8ce3ec91dbffb..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon - -// CHECK:STDERR: fail_skip_without_semi_to_curly.carbon:[[@LINE+4]]:1: error: unrecognized declaration introducer [UnrecognizedDecl] -// CHECK:STDERR: struct X { fn () } -// CHECK:STDERR: ^~~~~~ -// CHECK:STDERR: -struct X { fn () } -fn F(); - -// CHECK:STDOUT: - filename: fail_skip_without_semi_to_curly.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'InvalidParseStart', text: 'struct', has_error: yes}, -// CHECK:STDOUT: {kind: 'InvalidParseSubtree', text: '}', has_error: yes, subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon b/toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon deleted file mode 100644 index a893f88c19394..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_with_identifier_as_param.carbon - -// CHECK:STDERR: fail_with_identifier_as_param.carbon:[[@LINE+4]]:11: error: expected `:` or `:!` in binding pattern [ExpectedBindingPattern] -// CHECK:STDERR: fn foo(bar); -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn foo(bar); - -// CHECK:STDOUT: - filename: fail_with_identifier_as_param.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'bar'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: ')', has_error: yes}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: 'bar', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', has_error: yes, subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon b/toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon deleted file mode 100644 index d7c17fa26c575..0000000000000 --- a/toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/fail_without_name_and_many_tokens_in_params.carbon - -// CHECK:STDERR: fail_without_name_and_many_tokens_in_params.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] -// CHECK:STDERR: fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z); -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z); - -// CHECK:STDOUT: - filename: fail_without_name_and_many_tokens_in_params.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/impl_fn.carbon b/toolchain/parse/testdata/function/declaration/impl_fn.carbon deleted file mode 100644 index 1af6fba26eab0..0000000000000 --- a/toolchain/parse/testdata/function/declaration/impl_fn.carbon +++ /dev/null @@ -1,48 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/impl_fn.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/impl_fn.carbon - -impl fn F(); -abstract impl fn G(); -impl abstract fn H(); -private impl default fn I(); - -// CHECK:STDOUT: - filename: impl_fn.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'}, -// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'PrivateModifier', text: 'private'}, -// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'I'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/implicit_empty.carbon b/toolchain/parse/testdata/function/declaration/implicit_empty.carbon deleted file mode 100644 index 576404c24db4a..0000000000000 --- a/toolchain/parse/testdata/function/declaration/implicit_empty.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/implicit_empty.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/implicit_empty.carbon - -fn foo[](); - -// CHECK:STDOUT: - filename: implicit_empty.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['}, -// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/implicit_params.carbon b/toolchain/parse/testdata/function/declaration/implicit_params.carbon deleted file mode 100644 index ac40a3e2fd1d1..0000000000000 --- a/toolchain/parse/testdata/function/declaration/implicit_params.carbon +++ /dev/null @@ -1,31 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/implicit_params.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/implicit_params.carbon - -fn foo[a: i32, b: i32](); - -// CHECK:STDOUT: - filename: implicit_params.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'b'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/no_params.carbon b/toolchain/parse/testdata/function/declaration/no_params.carbon deleted file mode 100644 index eff50acad90d0..0000000000000 --- a/toolchain/parse/testdata/function/declaration/no_params.carbon +++ /dev/null @@ -1,21 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/no_params.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/no_params.carbon - -fn foo {} - -// CHECK:STDOUT: - filename: no_params.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/params.carbon b/toolchain/parse/testdata/function/declaration/params.carbon deleted file mode 100644 index ee7a81bffe3fa..0000000000000 --- a/toolchain/parse/testdata/function/declaration/params.carbon +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/params.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/params.carbon - -fn foo(a: i32, b: i32); - -// CHECK:STDOUT: - filename: params.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'b'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/with_return_type.carbon b/toolchain/parse/testdata/function/declaration/with_return_type.carbon deleted file mode 100644 index a90faf67aea7c..0000000000000 --- a/toolchain/parse/testdata/function/declaration/with_return_type.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/with_return_type.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/with_return_type.carbon - -fn foo() -> u32; - -// CHECK:STDOUT: - filename: with_return_type.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'UnsignedIntTypeLiteral', text: 'u32'}, -// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition.carbon b/toolchain/parse/testdata/function/definition.carbon new file mode 100644 index 0000000000000..a9c12011bbb83 --- /dev/null +++ b/toolchain/parse/testdata/function/definition.carbon @@ -0,0 +1,240 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition.carbon + +// --- basic.carbon + +fn F() {} + +// --- with_params.carbon + +fn foo(bar: i64, baz: i64) { + foo(baz, bar + baz); +} + +// --- with_return_type.carbon + +fn foo() -> f64 { + return 42; +} + +// --- fail_identifier_in_statements.carbon + +fn F() { + // Note: this might become valid depending on the expression syntax. This test + // shouldn't be taken as a sign it should remain invalid. + bar +// CHECK:STDERR: fail_identifier_in_statements.carbon:[[@LINE+4]]:1: error: expected `;` after expression statement [ExpectedExprSemi] +// CHECK:STDERR: } +// CHECK:STDERR: ^ +// CHECK:STDERR: +} + +// --- nested.carbon + +fn F() { + fn NamedParams(a: i32) {} + fn PositionalParams {} +} + +// --- builtin.carbon + +fn F() = "builtin"; + +// --- builtin_nested.carbon + +impl T as I { + fn Op() = "builtin"; +} + +// --- fail_builtin_identifier.carbon + +// CHECK:STDERR: fail_builtin_identifier.carbon:[[@LINE+4]]:18: error: expected builtin function name after `=` [ExpectedBuiltinName] +// CHECK:STDERR: fn NotString() = banana; +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: +fn NotString() = banana; + +// --- fail_builtin_two_strings.carbon + +// CHECK:STDERR: fail_builtin_two_strings.carbon:[[@LINE+4]]:32: error: `fn` declarations must end with a `;` [ExpectedDeclSemi] +// CHECK:STDERR: fn JunkAfterString() = "hello" "world"; +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: +fn JunkAfterString() = "hello" "world"; + +// --- fail_builtin_spurious_equals.carbon + +// CHECK:STDERR: fail_builtin_spurious_equals.carbon:[[@LINE+4]]:23: error: expected builtin function name after `=` [ExpectedBuiltinName] +// CHECK:STDERR: fn SpuriousEquals() = { } +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn SpuriousEquals() = { } +fn TestRecoveryFromSpuriousEquals(); + +// CHECK:STDOUT: - filename: basic.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: with_params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'bar'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i64'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'baz'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i64'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'foo'}, +// CHECK:STDOUT: {kind: 'CallExprStart', text: '(', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'baz'}, +// CHECK:STDOUT: {kind: 'CallExprComma', text: ','}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'baz'}, +// CHECK:STDOUT: {kind: 'InfixOperatorPlus', text: '+', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'CallExpr', text: ')', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: with_return_type.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'}, +// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '42'}, +// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_identifier_in_statements.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'}, +// CHECK:STDOUT: {kind: 'ExprStatement', text: 'bar', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: nested.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'NamedParams'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'PositionalParams'}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 19}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: builtin.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'BuiltinName', text: '"builtin"'}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: builtin_nested.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'}, +// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'}, +// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'Op'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'BuiltinName', text: '"builtin"'}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 13}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_builtin_identifier.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'NotString'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_builtin_two_strings.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'JunkAfterString'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'BuiltinName', text: '"hello"'}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', has_error: yes, subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_builtin_spurious_equals.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'SpuriousEquals'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: '}', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'TestRecoveryFromSpuriousEquals'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/basic.carbon b/toolchain/parse/testdata/function/definition/basic.carbon deleted file mode 100644 index 5ee20ab221e6e..0000000000000 --- a/toolchain/parse/testdata/function/definition/basic.carbon +++ /dev/null @@ -1,23 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/basic.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/basic.carbon - -fn F() {} - -// CHECK:STDOUT: - filename: basic.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/builtin.carbon b/toolchain/parse/testdata/function/definition/builtin.carbon deleted file mode 100644 index 4f1c1d5f31ce1..0000000000000 --- a/toolchain/parse/testdata/function/definition/builtin.carbon +++ /dev/null @@ -1,41 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/builtin.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/builtin.carbon - -fn F() = "builtin"; - -impl T as I { - fn Op() = "builtin"; -} - -// CHECK:STDOUT: - filename: builtin.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'BuiltinName', text: '"builtin"'}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'}, -// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'}, -// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'Op'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'BuiltinName', text: '"builtin"'}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 13}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/extern.carbon b/toolchain/parse/testdata/function/definition/extern.carbon deleted file mode 100644 index 396fa3e97c95d..0000000000000 --- a/toolchain/parse/testdata/function/definition/extern.carbon +++ /dev/null @@ -1,44 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/extern.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/extern.carbon - -// --- extern.carbon - -extern fn G() {} - -// --- library.carbon - -extern library "foo" fn G() {} - -// CHECK:STDOUT: - filename: extern.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'ExternModifier', text: 'extern'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] -// CHECK:STDOUT: - filename: library.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'LibraryName', text: '"foo"'}, -// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ExternModifierWithLibrary', text: 'extern', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/fail_builtin.carbon b/toolchain/parse/testdata/function/definition/fail_builtin.carbon deleted file mode 100644 index 678a64c13afcf..0000000000000 --- a/toolchain/parse/testdata/function/definition/fail_builtin.carbon +++ /dev/null @@ -1,57 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/fail_builtin.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/fail_builtin.carbon - -// CHECK:STDERR: fail_builtin.carbon:[[@LINE+4]]:18: error: expected builtin function name after `=` [ExpectedBuiltinName] -// CHECK:STDERR: fn NotString() = banana; -// CHECK:STDERR: ^~~~~~ -// CHECK:STDERR: -fn NotString() = banana; -// CHECK:STDERR: fail_builtin.carbon:[[@LINE+4]]:32: error: `fn` declarations must end with a `;` [ExpectedDeclSemi] -// CHECK:STDERR: fn JunkAfterString() = "hello" "world"; -// CHECK:STDERR: ^~~~~~~ -// CHECK:STDERR: -fn JunkAfterString() = "hello" "world"; - -// CHECK:STDERR: fail_builtin.carbon:[[@LINE+4]]:23: error: expected builtin function name after `=` [ExpectedBuiltinName] -// CHECK:STDERR: fn SpuriousEquals() = { } -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn SpuriousEquals() = { } -fn TestRecoveryFromSpuriousEquals(); - -// CHECK:STDOUT: - filename: fail_builtin.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'NotString'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', has_error: yes, subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'JunkAfterString'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'BuiltinName', text: '"hello"'}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: ';', has_error: yes, subtree_size: 7}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'SpuriousEquals'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinitionStart', text: '=', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'BuiltinFunctionDefinition', text: '}', has_error: yes, subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'TestRecoveryFromSpuriousEquals'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon b/toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon deleted file mode 100644 index 405f0bd370607..0000000000000 --- a/toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon +++ /dev/null @@ -1,33 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/fail_identifier_in_statements.carbon - -fn F() { - // Note: this might become valid depending on the expression syntax. This test - // shouldn't be taken as a sign it should remain invalid. - bar -// CHECK:STDERR: fail_identifier_in_statements.carbon:[[@LINE+4]]:1: error: expected `;` after expression statement [ExpectedExprSemi] -// CHECK:STDERR: } -// CHECK:STDERR: ^ -// CHECK:STDERR: -} - -// CHECK:STDOUT: - filename: fail_identifier_in_statements.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'}, -// CHECK:STDOUT: {kind: 'ExprStatement', text: 'bar', has_error: yes, subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/nested.carbon b/toolchain/parse/testdata/function/definition/nested.carbon deleted file mode 100644 index 9e32b32c2e22c..0000000000000 --- a/toolchain/parse/testdata/function/definition/nested.carbon +++ /dev/null @@ -1,39 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/nested.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/nested.carbon - -fn F() { - fn NamedParams(a: i32) {} - fn PositionalParams {} -} - -// CHECK:STDOUT: - filename: nested.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'NamedParams'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'a'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'PositionalParams'}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 19}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/with_params.carbon b/toolchain/parse/testdata/function/definition/with_params.carbon deleted file mode 100644 index 77a7d44e4d3fd..0000000000000 --- a/toolchain/parse/testdata/function/definition/with_params.carbon +++ /dev/null @@ -1,41 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/with_params.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/with_params.carbon - -fn foo(bar: i64, baz: i64) { - foo(baz, bar + baz); -} - -// CHECK:STDOUT: - filename: with_params.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'bar'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i64'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'PatternListComma', text: ','}, -// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'baz'}, -// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i64'}, -// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'foo'}, -// CHECK:STDOUT: {kind: 'CallExprStart', text: '(', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'baz'}, -// CHECK:STDOUT: {kind: 'CallExprComma', text: ','}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'}, -// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'baz'}, -// CHECK:STDOUT: {kind: 'InfixOperatorPlus', text: '+', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'CallExpr', text: ')', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/definition/with_return_type.carbon b/toolchain/parse/testdata/function/definition/with_return_type.carbon deleted file mode 100644 index 0de1644ebd19e..0000000000000 --- a/toolchain/parse/testdata/function/definition/with_return_type.carbon +++ /dev/null @@ -1,30 +0,0 @@ -// 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 -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/definition/with_return_type.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/definition/with_return_type.carbon - -fn foo() -> f64 { - return 42; -} - -// CHECK:STDOUT: - filename: with_return_type.carbon -// CHECK:STDOUT: parse_tree: [ -// CHECK:STDOUT: {kind: 'FileStart', text: ''}, -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'}, -// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'}, -// CHECK:STDOUT: {kind: 'IntLiteral', text: '42'}, -// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 11}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/function/declaration/extern.carbon b/toolchain/parse/testdata/function/extern.carbon similarity index 73% rename from toolchain/parse/testdata/function/declaration/extern.carbon rename to toolchain/parse/testdata/function/extern.carbon index a3c6eff6f3098..85d0a0bd48bf2 100644 --- a/toolchain/parse/testdata/function/declaration/extern.carbon +++ b/toolchain/parse/testdata/function/extern.carbon @@ -4,9 +4,9 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/declaration/extern.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/extern.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/declaration/extern.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/extern.carbon // --- extern.carbon @@ -40,6 +40,14 @@ extern library fn G(); // CHECK:STDERR: extern library foo fn G(); +// --- extern_def.carbon + +extern fn G() {} + +// --- library_def.carbon + +extern library "foo" fn G() {} + // CHECK:STDOUT: - filename: extern.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, @@ -100,3 +108,29 @@ extern library foo fn G(); // CHECK:STDOUT: {kind: 'InvalidParseSubtree', text: ';', has_error: yes, subtree_size: 5}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: extern_def.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'ExternModifier', text: 'extern'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: library_def.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"foo"'}, +// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ExternModifierWithLibrary', text: 'extern', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] From f7e0b61c3a97d0b9656b771d6c50ca9a3ce6b392 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 28 Feb 2025 12:06:06 -0800 Subject: [PATCH 45/56] Refactor HandleIdentifierName away (#5044) Most of the logic is actually in `GetIdentifierName`. I'm moving the `CHECK` there for better sharing, also with `IdentifierNameExprId`. Note this PR is mainly motivated by #5045, which would make this the only place that needs `AnyNonExprIdentifierNameId` in specific (other places need to deal with both identifiers and keywords). --- toolchain/check/handle_name.cpp | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index be10cf5f4e4e1..39760d7878f2b 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -92,12 +92,10 @@ auto HandleParseNode(Context& context, Parse::PointerMemberAccessExprId node_id) } static auto GetIdentifierAsName(Context& context, Parse::NodeId node_id) - -> std::optional { + -> SemIR::NameId { + CARBON_CHECK(!context.parse_tree().node_has_error(node_id), + "TODO: Support checking error parse nodes"); auto token = context.parse_tree().node_token(node_id); - if (context.tokens().GetKind(token) != Lex::TokenKind::Identifier) { - CARBON_CHECK(context.parse_tree().node_has_error(node_id)); - return std::nullopt; - } return SemIR::NameId::ForIdentifier(context.tokens().GetIdentifier(token)); } @@ -128,20 +126,11 @@ static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id, {.type_id = type_id, .name_id = name_id, .value_id = inst_id}); } -static auto HandleIdentifierName(Context& context, - Parse::AnyNonExprIdentifierNameId node_id) - -> bool { - // The parent is responsible for binding the name. - auto name_id = GetIdentifierAsName(context, node_id); - CARBON_CHECK(name_id, - "Unreachable until we support checking error parse nodes"); - context.node_stack().Push(node_id, *name_id); - return true; -} - auto HandleParseNode(Context& context, Parse::IdentifierNameNotBeforeParamsId node_id) -> bool { - return HandleIdentifierName(context, node_id); + // The parent is responsible for binding the name. + context.node_stack().Push(node_id, GetIdentifierAsName(context, node_id)); + return true; } auto HandleParseNode(Context& context, @@ -150,16 +139,16 @@ auto HandleParseNode(Context& context, context.pattern_block_stack().Push(); context.full_pattern_stack().PushFullPattern( FullPatternStack::Kind::ImplicitParamList); - return HandleIdentifierName(context, node_id); + // The parent is responsible for binding the name. + context.node_stack().Push(node_id, GetIdentifierAsName(context, node_id)); + return true; } auto HandleParseNode(Context& context, Parse::IdentifierNameExprId node_id) -> bool { auto name_id = GetIdentifierAsName(context, node_id); - CARBON_CHECK(name_id, - "Unreachable until we support checking error parse nodes"); context.node_stack().Push(node_id, - HandleNameAsExpr(context, node_id, *name_id)); + HandleNameAsExpr(context, node_id, name_id)); return true; } From fc5dcfe95772d12fafa73dd7bc273427abc3cd9c Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Fri, 28 Feb 2025 22:10:37 +0100 Subject: [PATCH 46/56] Add a test for the case that `impl` function is poisoned (#4950) This adds missing coverage. Part of #4622. --- .../no_prelude/name_poisoning.carbon | 3 +- .../impl/no_prelude/name_poisoning.carbon | 148 ++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) diff --git a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon index 4962c6109d4e7..efd997ce12cf6 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon @@ -94,6 +94,7 @@ alias N.F2 = F1; fn N.F1(); // Failure: `N.F1` used after declaration failed. +// TODO: #4622 - Allow defining a poisoned name so it would be found if used after it's declared. // CHECK:STDERR: fail_use_declaration_after_poison.carbon:[[@LINE+4]]:14: error: member name `F1` not found in `N` [MemberNameNotFoundInScope] // CHECK:STDERR: alias N.F3 = N.F1; // CHECK:STDERR: ^~~~ @@ -414,7 +415,7 @@ fn F1() { // CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] // CHECK:STDOUT: %F1.decl.loc18: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} // CHECK:STDOUT: %N.ref: = name_ref N, %N [concrete = %N] -// CHECK:STDOUT: %F1.ref.loc25: = name_ref F1, [concrete = ] +// CHECK:STDOUT: %F1.ref.loc26: = name_ref F1, [concrete = ] // CHECK:STDOUT: %F3: = bind_alias F3, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon index 31bdb33974c60..32d1b3f61b854 100644 --- a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -23,6 +23,37 @@ class N.C { } } +// --- fail_impl_function_poisoned.carbon + +library "[[@TEST_NAME]]"; + +interface I { + fn A(x: Self); + fn B(); +} + +class B { + impl as I { + // CHECK:STDERR: fail_impl_function_poisoned.carbon:[[@LINE+3]]:13: error: name `B` used before it was declared [NameUseBeforeDecl] + // CHECK:STDERR: fn A(x: B); + // CHECK:STDERR: ^ + fn A(x: B); + // TODO: Avoid ImplMissingFunction for functions that were declared after they were poisoned. + // CHECK:STDERR: fail_impl_function_poisoned.carbon:[[@LINE+11]]:8: note: declared here [NameUseBeforeDeclNote] + // CHECK:STDERR: fn B(); + // CHECK:STDERR: ^ + // CHECK:STDERR: + // CHECK:STDERR: fail_impl_function_poisoned.carbon:[[@LINE-10]]:3: error: missing implementation of B in impl of interface I [ImplMissingFunction] + // CHECK:STDERR: impl as I { + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: fail_impl_function_poisoned.carbon:[[@LINE-17]]:3: note: associated function B declared here [AssociatedFunctionHere] + // CHECK:STDERR: fn B(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn B(); + } +} + // CHECK:STDOUT: --- using_poisoned_name_in_impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -100,3 +131,120 @@ class N.C { // CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- fail_impl_function_poisoned.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] +// CHECK:STDOUT: %A.type.edf: type = fn_type @A.1 [concrete] +// CHECK:STDOUT: %A.ab0: %A.type.edf = struct_value () [concrete] +// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [concrete] +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%A.decl [concrete] +// CHECK:STDOUT: %B.type.785: type = fn_type @B.1 [concrete] +// CHECK:STDOUT: %B.6d4: %B.type.785 = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, @I.%B.decl [concrete] +// CHECK:STDOUT: %B.fa3: type = class_type @B.3 [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%A.decl, ) [concrete] +// CHECK:STDOUT: %A.type.9b9: type = fn_type @A.2 [concrete] +// CHECK:STDOUT: %A.71f: %A.type.9b9 = struct_value () [concrete] +// CHECK:STDOUT: %B.type.52d: type = fn_type @B.2 [concrete] +// CHECK:STDOUT: %B.30a: %B.type.52d = struct_value () [concrete] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %B.fa3, %impl_witness [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %B.decl: type = class_decl @B.3 [concrete = constants.%B.fa3] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %A.decl: %A.type.edf = fn_decl @A.1 [concrete = constants.%A.ab0] { +// CHECK:STDOUT: %x.patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc5_11.1: type = splice_block %.loc5_11.2 [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type.loc5_11.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %.loc5_11.2: type = converted %Self.ref, %Self.as_type.loc5_11.2 [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %A.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: %B.decl: %B.type.785 = fn_decl @B.1 [concrete = constants.%B.6d4] {} {} +// CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, %B.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .A = %assoc0 +// CHECK:STDOUT: .B = %assoc1 +// CHECK:STDOUT: witness = (%A.decl, %B.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl: %Self.ref as %I.ref { +// CHECK:STDOUT: %A.decl: %A.type.9b9 = fn_decl @A.2 [concrete = constants.%A.71f] { +// CHECK:STDOUT: %x.patt: %B.fa3 = binding_pattern x +// CHECK:STDOUT: %x.param_patt: %B.fa3 = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %x.param: %B.fa3 = value_param runtime_param0 +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.fa3] +// CHECK:STDOUT: %x: %B.fa3 = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: %B.type.52d = fn_decl @B.2 [concrete = constants.%B.30a] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .B = +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: witness = @B.3.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @B.3 { +// CHECK:STDOUT: impl_decl @impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B.fa3 [concrete = constants.%B.fa3] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%A.decl, ) [concrete = constants.%impl_witness] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%B.fa3 +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .B = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.1(@I.%Self: %I.type) { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type.loc5_11.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param_patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @B.1(@I.%Self: %I.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @A.2(%x.param_patt: %B.fa3); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.2(); +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.1(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.as_type.loc5_11.1 => constants.%Self.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @B.1(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.1(constants.%I.facet) { +// CHECK:STDOUT: %Self => constants.%I.facet +// CHECK:STDOUT: %Self.as_type.loc5_11.1 => constants.%B.fa3 +// CHECK:STDOUT: } +// CHECK:STDOUT: From 6d6987dce4a0fbae0dcee736a1e783501adf0d2c Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 28 Feb 2025 13:25:15 -0800 Subject: [PATCH 47/56] Narrow the CRC scope in file_test (#5043) This narrows the scope of the CRC to try to get better behavior around mutex lock releasing on crash. Closes #5042. This breaks apart `ProcessTestFileAndRun` because we need to process the test file for `SET-CAPTURE-CONSOLE-OUTPUT`. The test file processing should more reliably not crash than the core `Run` logic though, so should be reasonably safe to put outside the CRC. Also support --threads=1 for disabling threading. This is the flipside for me of reducing how much is in the CRC: make it easier to run on a single thread if the CRC gets in the way of debugging. This also means a typical copy-paste execution of a single test will be single-threaded. --------- Co-authored-by: Geoff Romer --- explorer/file_test.cpp | 17 +- testing/file_test/file_test_base.cpp | 183 ++++++++++++++-------- testing/file_test/file_test_base.h | 13 +- testing/file_test/file_test_base_test.cpp | 12 +- testing/file_test/run_test.cpp | 32 ++-- testing/file_test/run_test.h | 8 +- toolchain/testing/file_test.cpp | 31 ++-- 7 files changed, 172 insertions(+), 124 deletions(-) diff --git a/explorer/file_test.cpp b/explorer/file_test.cpp index 210bf4518340f..b743e7ef86e30 100644 --- a/explorer/file_test.cpp +++ b/explorer/file_test.cpp @@ -35,7 +35,7 @@ class ExplorerFileTest : public FileTestBase { auto Run(const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* /*input_stream*/, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr override { // Add the prelude. llvm::ErrorOr> prelude = @@ -58,21 +58,22 @@ class ExplorerFileTest : public FileTestBase { args.push_back(arg.data()); } + RawStringOstream trace_stream; int exit_code = ExplorerMain(args.size(), args.data(), /*install_path=*/"", PreludePath, output_stream, error_stream, - check_trace_output() ? output_stream : trace_stream_, *fs); + check_trace_output() ? output_stream : trace_stream, *fs); // Skip trace test check as they use stdout stream instead of // trace_stream_ostream - if (absl::GetFlag(FLAGS_trace) && trace_stream_.TakeStr().empty()) { + if (absl::GetFlag(FLAGS_trace) && trace_stream.TakeStr().empty()) { return Error("Tracing should always do something"); } return {{.success = exit_code == EXIT_SUCCESS}}; } - auto GetDefaultArgs() -> llvm::SmallVector override { + auto GetDefaultArgs() const -> llvm::SmallVector override { llvm::SmallVector args; if (absl::GetFlag(FLAGS_trace)) { args.push_back("--trace_file=-"); @@ -83,14 +84,15 @@ class ExplorerFileTest : public FileTestBase { } auto GetLineNumberReplacements(llvm::ArrayRef filenames) - -> llvm::SmallVector override { + const -> llvm::SmallVector override { if (check_trace_output()) { return {}; } return FileTestBase::GetLineNumberReplacements(filenames); } - auto DoExtraCheckReplacements(std::string& check_line) -> void override { + auto DoExtraCheckReplacements(std::string& check_line) const + -> void override { // Ignore the resulting column of EndOfFile because it's often the end of // the CHECK comment. RE2::GlobalReplace(&check_line, prelude_line_re_, @@ -106,11 +108,10 @@ class ExplorerFileTest : public FileTestBase { private: // Trace output is directly checked for a few tests. - auto check_trace_output() -> bool { + auto check_trace_output() const -> bool { return test_name().find("/trace/") != std::string::npos; } - RawStringOstream trace_stream_; RE2 prelude_line_re_; RE2 timing_re_; }; diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index 607353df09500..701ce6de99b22 100644 --- a/testing/file_test/file_test_base.cpp +++ b/testing/file_test/file_test_base.cpp @@ -268,7 +268,7 @@ auto FileTestCase::TestBody() -> void { } auto FileTestBase::GetLineNumberReplacements( - llvm::ArrayRef filenames) + llvm::ArrayRef filenames) const -> llvm::SmallVector { return {{.has_file = true, .re = std::make_shared( @@ -329,88 +329,147 @@ class FileTestEventListener : public testing::EmptyTestEventListener { llvm::MutableArrayRef tests_; }; +// Returns true if the main thread should be used to run tests. This is if +// either --dump_output is specified, or only 1 thread is needed to run tests. +static auto SingleThreaded(llvm::ArrayRef tests) -> bool { + if (absl::GetFlag(FLAGS_dump_output) || absl::GetFlag(FLAGS_threads) == 1) { + return true; + } + + bool found_test_to_run = false; + for (const auto& test : tests) { + if (!test.registered_test->should_run()) { + continue; + } + if (found_test_to_run) { + // At least two tests will run, so multi-threaded. + return false; + } + // Found the first test to run. + found_test_to_run = true; + } + // 0 or 1 test will be run, so single-threaded. + return false; +} + +// Runs the test in the section that would be inside a lock, possibly inside a +// CrashRecoveryContext. +static auto RunSingleTestHelper(FileTestInfo& test, FileTestBase& test_instance) + -> void { + // Add a crash trace entry with the single-file test command. + std::string test_command = GetBazelCommand(BazelMode::Test, test.test_name); + llvm::PrettyStackTraceString stack_trace_entry(test_command.c_str()); + + if (auto err = RunTestFile(test_instance, absl::GetFlag(FLAGS_dump_output), + **test.test_result); + !err.ok()) { + test.test_result = std::move(err).error(); + } +} + +// Runs a single test. Uses a CrashRecoveryContext, and returns false on a +// crash. +static auto RunSingleTest(FileTestInfo& test, bool single_threaded, + std::mutex& output_mutex) -> bool { + std::unique_ptr test_instance(test.factory_fn()); + + if (absl::GetFlag(FLAGS_dump_output)) { + std::unique_lock lock(output_mutex); + llvm::errs() << "\n--- Dumping: " << test.test_name << "\n\n"; + } + + // Load expected output. + test.test_result = ProcessTestFile(test_instance->test_name(), + absl::GetFlag(FLAGS_autoupdate)); + if (test.test_result->ok()) { + // Execution must be serialized for either serial tests or console + // output. + std::unique_lock output_lock; + + if ((*test.test_result)->capture_console_output || + !test_instance->AllowParallelRun()) { + output_lock = std::unique_lock(output_mutex); + } + + if (single_threaded) { + RunSingleTestHelper(test, *test_instance); + } else { + // Use a crash recovery context to try to get a stack trace when + // multiple threads may crash in parallel, which otherwise leads to the + // program aborting without printing a stack trace. + llvm::CrashRecoveryContext crc; + crc.DumpStackAndCleanupOnFailure = true; + if (!crc.RunSafely([&] { RunSingleTestHelper(test, *test_instance); })) { + return false; + } + } + } + + if (!test.test_result->ok()) { + std::unique_lock lock(output_mutex); + llvm::errs() << "\n" << test.test_result->error().message() << "\n"; + return true; + } + + test.autoupdate_differs = + RunAutoupdater(test_instance.get(), **test.test_result, + /*dry_run=*/!absl::GetFlag(FLAGS_autoupdate)); + + std::unique_lock lock(output_mutex); + if (absl::GetFlag(FLAGS_dump_output)) { + llvm::outs().flush(); + const TestFile& test_file = **test.test_result; + llvm::errs() << "\n--- Exit with success: " + << (test_file.run_result.success ? "true" : "false") + << "\n--- Autoupdate differs: " + << (test.autoupdate_differs ? "true" : "false") << "\n"; + } else { + llvm::errs() << (test.autoupdate_differs ? "!" : "."); + } + + return true; +} + auto FileTestEventListener::OnTestProgramStart( const testing::UnitTest& /*unit_test*/) -> void { - llvm::CrashRecoveryContext::Enable(); - llvm::DefaultThreadPool pool( - {.ThreadsRequested = absl::GetFlag(FLAGS_dump_output) - ? 1 - : absl::GetFlag(FLAGS_threads)}); + bool single_threaded = SingleThreaded(tests_); + + std::unique_ptr pool; + if (single_threaded) { + pool = std::make_unique(); + } else { + // Enable the CRC for use in `RunSingleTest`. + llvm::CrashRecoveryContext::Enable(); + pool = std::make_unique(llvm::ThreadPoolStrategy{ + .ThreadsRequested = absl::GetFlag(FLAGS_threads)}); + } if (!absl::GetFlag(FLAGS_dump_output)) { - llvm::errs() << "Running tests with " << pool.getMaxConcurrency() + llvm::errs() << "Running tests with " << pool->getMaxConcurrency() << " thread(s)\n"; } - // Guard access to both `llvm::errs` and `crashed`. - bool crashed = false; + // Guard access to output (stdout and stderr). std::mutex output_mutex; + std::atomic crashed = false; for (auto& test : tests_) { if (!test.registered_test->should_run()) { continue; } - pool.async([&output_mutex, &crashed, &test] { + pool->async([&] { // If any thread crashed, don't try running more. - { - std::unique_lock lock(output_mutex); - if (crashed) { - return; - } + if (crashed) { + return; } - // Use a crash recovery context to try to get a stack trace when - // multiple threads may crash in parallel, which otherwise leads to the - // program aborting without printing a stack trace. - llvm::CrashRecoveryContext crc; - crc.DumpStackAndCleanupOnFailure = true; - bool thread_crashed = !crc.RunSafely([&] { - std::unique_ptr test_instance(test.factory_fn()); - - // Add a crash trace entry with the single-file test command. - std::string test_command = - GetBazelCommand(BazelMode::Test, test.test_name); - llvm::PrettyStackTraceString stack_trace_entry(test_command.c_str()); - - if (absl::GetFlag(FLAGS_dump_output)) { - std::unique_lock lock(output_mutex); - llvm::errs() << "\n--- Dumping: " << test.test_name << "\n\n"; - } - - test.test_result = ProcessTestFileAndRun( - test_instance.get(), &output_mutex, - absl::GetFlag(FLAGS_dump_output), absl::GetFlag(FLAGS_autoupdate)); - - if (!test.test_result->ok()) { - std::unique_lock lock(output_mutex); - llvm::errs() << "\n" << test.test_result->error().message() << "\n"; - return; - } - - test.autoupdate_differs = - RunAutoupdater(test_instance.get(), **test.test_result, - /*dry_run=*/!absl::GetFlag(FLAGS_autoupdate)); - - std::unique_lock lock(output_mutex); - if (absl::GetFlag(FLAGS_dump_output)) { - llvm::outs().flush(); - const TestFile& test_file = **test.test_result; - llvm::errs() << "\n--- Exit with success: " - << (test_file.run_result.success ? "true" : "false") - << "\n--- Autoupdate differs: " - << (test.autoupdate_differs ? "true" : "false") << "\n"; - } else { - llvm::errs() << (test.autoupdate_differs ? "!" : "."); - } - }); - if (thread_crashed) { - std::unique_lock lock(output_mutex); + if (!RunSingleTest(test, single_threaded, output_mutex)) { crashed = true; } }); } - pool.wait(); + pool->wait(); if (crashed) { // Abort rather than returning so that we don't get a LeakSanitizer report. // We expect to have leaked memory if one or more of our tests crashed. diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index 4cd6d064e7025..7782de5343a2c 100644 --- a/testing/file_test/file_test_base.h +++ b/testing/file_test/file_test_base.h @@ -71,15 +71,15 @@ class FileTestBase { virtual auto Run(const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* input_stream, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr = 0; // Returns default arguments. Only called when a file doesn't set ARGS. - virtual auto GetDefaultArgs() -> llvm::SmallVector = 0; + virtual auto GetDefaultArgs() const -> llvm::SmallVector = 0; // Returns a map of string replacements to implement `%{key}` -> `value` in // arguments. - virtual auto GetArgReplacements() -> llvm::StringMap { + virtual auto GetArgReplacements() const -> llvm::StringMap { return {}; } @@ -87,18 +87,19 @@ class FileTestBase { // May return nullptr if unused. If GetLineNumberReplacements returns an entry // with has_file=false, this is required. virtual auto GetDefaultFileRE(llvm::ArrayRef /*filenames*/) - -> std::optional { + const -> std::optional { return std::nullopt; } // Returns replacement information for line numbers. See LineReplacement for // construction. virtual auto GetLineNumberReplacements( - llvm::ArrayRef filenames) + llvm::ArrayRef filenames) const -> llvm::SmallVector; // Optionally allows children to provide extra replacements for autoupdate. - virtual auto DoExtraCheckReplacements(std::string& /*check_line*/) -> void {} + virtual auto DoExtraCheckReplacements(std::string& /*check_line*/) const + -> void {} // Whether to allow running the test in parallel, particularly for autoupdate. // This can be overridden to force some tests to be run serially. At any given diff --git a/testing/file_test/file_test_base_test.cpp b/testing/file_test/file_test_base_test.cpp index 5a4ae5edaca8c..8fd0c9e3a5709 100644 --- a/testing/file_test/file_test_base_test.cpp +++ b/testing/file_test/file_test_base_test.cpp @@ -23,25 +23,25 @@ class FileTestBaseTest : public FileTestBase { auto Run(const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* input_stream, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr override; - auto GetArgReplacements() -> llvm::StringMap override { + auto GetArgReplacements() const -> llvm::StringMap override { return {{"replacement", "replaced"}}; } - auto GetDefaultArgs() -> llvm::SmallVector override { + auto GetDefaultArgs() const -> llvm::SmallVector override { return {"default_args", "%s"}; } - auto GetDefaultFileRE(llvm::ArrayRef filenames) + auto GetDefaultFileRE(llvm::ArrayRef filenames) const -> std::optional override { return std::make_optional( llvm::formatv(R"(file: ({0}))", llvm::join(filenames, "|"))); } auto GetLineNumberReplacements(llvm::ArrayRef filenames) - -> llvm::SmallVector override { + const -> llvm::SmallVector override { auto replacements = FileTestBase::GetLineNumberReplacements(filenames); auto filename = std::filesystem::path(test_name().str()).filename(); if (llvm::StringRef(filename).starts_with("file_only_re_")) { @@ -260,7 +260,7 @@ auto FileTestBaseTest::Run( const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* input_stream, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) -> ErrorOr { + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr { PrintArgs(test_args, output_stream); auto filename = std::filesystem::path(test_name().str()).filename(); diff --git a/testing/file_test/run_test.cpp b/testing/file_test/run_test.cpp index 9adc0ddb0da7c..ffb83a46113ed 100644 --- a/testing/file_test/run_test.cpp +++ b/testing/file_test/run_test.cpp @@ -27,7 +27,6 @@ static constexpr llvm::StringLiteral StdinFilename = "STDIN"; // Does replacements in ARGS for %s and %t. static auto DoArgReplacements( - llvm::SmallVector& test_args, const llvm::StringMap& replacements, const llvm::SmallVector& split_files) -> ErrorOr { @@ -87,21 +86,15 @@ static auto DoArgReplacements( return Success(); } -auto ProcessTestFileAndRun(FileTestBase* test_base, std::mutex* output_mutex, - bool dump_output, bool running_autoupdate) - -> ErrorOr { - // Load expected output. - CARBON_ASSIGN_OR_RETURN( - TestFile test_file, - ProcessTestFile(test_base->test_name(), running_autoupdate)); - +auto RunTestFile(const FileTestBase& test_base, bool dump_output, + TestFile& test_file) -> ErrorOr { // Process arguments. if (test_file.test_args.empty()) { - test_file.test_args = test_base->GetDefaultArgs(); + test_file.test_args = test_base.GetDefaultArgs(); test_file.test_args.append(test_file.extra_args); } CARBON_RETURN_IF_ERROR(DoArgReplacements(test_file.test_args, - test_base->GetArgReplacements(), + test_base.GetArgReplacements(), test_file.file_splits)); // stdin needs to exist on-disk for compatibility. We'll use a pointer for it. @@ -147,13 +140,6 @@ auto ProcessTestFileAndRun(FileTestBase* test_base, std::mutex* output_mutex, llvm::PrettyStackTraceProgram stack_trace_entry( test_argv_for_stack_trace.size() - 1, test_argv_for_stack_trace.data()); - // Execution must be serialized for either serial tests or console output. - std::unique_lock output_lock; - if (output_mutex && - (test_file.capture_console_output || !test_base->AllowParallelRun())) { - output_lock = std::unique_lock(*output_mutex); - } - // Conditionally capture console output. We use a scope exit to ensure the // captures terminate even on run failures. if (test_file.capture_console_output) { @@ -168,10 +154,10 @@ auto ProcessTestFileAndRun(FileTestBase* test_base, std::mutex* output_mutex, llvm::raw_svector_ostream error_stream(test_file.actual_stderr); ErrorOr run_result = - dump_output ? test_base->Run(test_args_ref, fs, input_stream, - llvm::outs(), llvm::errs()) - : test_base->Run(test_args_ref, fs, input_stream, - output_stream, error_stream); + dump_output ? test_base.Run(test_args_ref, fs, input_stream, llvm::outs(), + llvm::errs()) + : test_base.Run(test_args_ref, fs, input_stream, + output_stream, error_stream); // Ensure stdout/stderr are always fetched, even when discarded on error. if (test_file.capture_console_output) { @@ -185,7 +171,7 @@ auto ProcessTestFileAndRun(FileTestBase* test_base, std::mutex* output_mutex, return std::move(run_result).error(); } test_file.run_result = std::move(*run_result); - return test_file; + return Success(); } } // namespace Carbon::Testing diff --git a/testing/file_test/run_test.h b/testing/file_test/run_test.h index d6025511ef139..1eb0545179d71 100644 --- a/testing/file_test/run_test.h +++ b/testing/file_test/run_test.h @@ -11,11 +11,9 @@ namespace Carbon::Testing { -// Processes the test file and runs the test. Returns an error if something -// went wrong. -auto ProcessTestFileAndRun(FileTestBase* test_base, std::mutex* output_mutex, - bool dump_output, bool running_autoupdate) - -> ErrorOr; +// Runs the test, updating `test_file`. +auto RunTestFile(const FileTestBase& test_base, bool dump_output, + TestFile& test_file) -> ErrorOr; } // namespace Carbon::Testing diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 77f44eea40c5e..bfc5316fc3709 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -27,29 +27,29 @@ class ToolchainFileTest : public FileTestBase { llvm::StringRef test_name); // Adds a replacement for `core_package_dir`. - auto GetArgReplacements() -> llvm::StringMap override; + auto GetArgReplacements() const -> llvm::StringMap override; // Loads files into the VFS and runs the driver. auto Run(const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* input_stream, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr override; // Sets different default flags based on the component being tested. - auto GetDefaultArgs() -> llvm::SmallVector override; + auto GetDefaultArgs() const -> llvm::SmallVector override; // Generally uses the parent implementation, with special handling for lex. - auto GetDefaultFileRE(llvm::ArrayRef filenames) + auto GetDefaultFileRE(llvm::ArrayRef filenames) const -> std::optional override; // Generally uses the parent implementation, with special handling for lex. auto GetLineNumberReplacements(llvm::ArrayRef filenames) - -> llvm::SmallVector override; + const -> llvm::SmallVector override; // Generally uses the parent implementation, with special handling for lex and // driver. - auto DoExtraCheckReplacements(std::string& check_line) -> void override; + auto DoExtraCheckReplacements(std::string& check_line) const -> void override; // Most tests can be run in parallel, but clangd has a global for its logging // system so we need language-server tests to be run in serial. @@ -59,7 +59,7 @@ class ToolchainFileTest : public FileTestBase { private: // Adds a file to the fs. - auto AddFile(llvm::vfs::InMemoryFileSystem& fs, llvm::StringRef path) + auto AddFile(llvm::vfs::InMemoryFileSystem& fs, llvm::StringRef path) const -> ErrorOr; // Controls whether `Run()` includes the prelude. @@ -94,7 +94,8 @@ ToolchainFileTest::ToolchainFileTest(llvm::StringRef exe_path, component_(GetComponent(test_name)), installation_(InstallPaths::MakeForBazelRunfiles(exe_path)) {} -auto ToolchainFileTest::GetArgReplacements() -> llvm::StringMap { +auto ToolchainFileTest::GetArgReplacements() const + -> llvm::StringMap { return {{"core_package_dir", installation_.core_package()}}; } @@ -102,7 +103,7 @@ auto ToolchainFileTest::Run( const llvm::SmallVector& test_args, llvm::IntrusiveRefCntPtr& fs, FILE* input_stream, llvm::raw_pwrite_stream& output_stream, - llvm::raw_pwrite_stream& error_stream) -> ErrorOr { + llvm::raw_pwrite_stream& error_stream) const -> ErrorOr { CARBON_ASSIGN_OR_RETURN(auto prelude, installation_.ReadPreludeManifest()); if (!is_no_prelude()) { for (const auto& file : prelude) { @@ -141,7 +142,8 @@ auto ToolchainFileTest::Run( return result; } -auto ToolchainFileTest::GetDefaultArgs() -> llvm::SmallVector { +auto ToolchainFileTest::GetDefaultArgs() const + -> llvm::SmallVector { llvm::SmallVector args = {"--include-diagnostic-kind"}; if (component_ == "format") { @@ -180,7 +182,7 @@ auto ToolchainFileTest::GetDefaultArgs() -> llvm::SmallVector { } auto ToolchainFileTest::GetDefaultFileRE( - llvm::ArrayRef filenames) -> std::optional { + llvm::ArrayRef filenames) const -> std::optional { if (component_ == "lex") { return std::make_optional( llvm::formatv(R"(^- filename: ({0})$)", llvm::join(filenames, "|"))); @@ -189,7 +191,7 @@ auto ToolchainFileTest::GetDefaultFileRE( } auto ToolchainFileTest::GetLineNumberReplacements( - llvm::ArrayRef filenames) + llvm::ArrayRef filenames) const -> llvm::SmallVector { auto replacements = FileTestBase::GetLineNumberReplacements(filenames); if (component_ == "lex") { @@ -201,7 +203,7 @@ auto ToolchainFileTest::GetLineNumberReplacements( return replacements; } -auto ToolchainFileTest::DoExtraCheckReplacements(std::string& check_line) +auto ToolchainFileTest::DoExtraCheckReplacements(std::string& check_line) const -> void { if (component_ == "driver") { // TODO: Disable token output, it's not interesting for these tests. @@ -221,7 +223,8 @@ auto ToolchainFileTest::DoExtraCheckReplacements(std::string& check_line) } auto ToolchainFileTest::AddFile(llvm::vfs::InMemoryFileSystem& fs, - llvm::StringRef path) -> ErrorOr { + llvm::StringRef path) const + -> ErrorOr { llvm::ErrorOr> file = llvm::MemoryBuffer::getFile(path); if (file.getError()) { From dc0c2622acc5ef54b8e6e15fc625ec57a801879c Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 28 Feb 2025 15:04:07 -0800 Subject: [PATCH 48/56] Fix multiline incremental sync. (#5046) Previously the start index was incorrect. Adding comments where I was double-checking things along the way. --- .../language_server/handle_text_document.cpp | 45 ++--- .../text_document/incremental_sync.carbon | 40 ++++ .../incremental_sync_multiline.carbon | 183 ++++++++++++++++++ 3 files changed, 246 insertions(+), 22 deletions(-) create mode 100644 toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon diff --git a/toolchain/language_server/handle_text_document.cpp b/toolchain/language_server/handle_text_document.cpp index 99f3009629815..ea59770765c4d 100644 --- a/toolchain/language_server/handle_text_document.cpp +++ b/toolchain/language_server/handle_text_document.cpp @@ -6,6 +6,8 @@ namespace Carbon::LanguageServer { +// Implements `textDocument/didOpen`: +// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didOpen auto HandleDidOpenTextDocument( Context& context, const clang::clangd::DidOpenTextDocumentParams& params) -> void { @@ -26,36 +28,31 @@ auto HandleDidOpenTextDocument( } } +// Returns the result of moving from `cursor_index` past `line_count` lines. +static auto GetNthLineIndex(llvm::StringRef contents, size_t cursor_index, + size_t line_count) -> size_t { + for ([[maybe_unused]] auto _ : llvm::seq(line_count)) { + const size_t newline_index = contents.find('\n', cursor_index); + CARBON_CHECK(newline_index != std::string::npos, + "Line number greater than number of lines in the file"); + cursor_index = newline_index + 1; + } + return cursor_index; +} + // Takes start and end positions and returns a tuple with start and end // offsets. Positions are based on row and column numbers in the source // code. We often need to know the offsets when modifying strings, so // this function helps us calculate the offsets. It assumes that the start // position comes before the end position. -static auto PositionToIndex(const std::string& contents, +static auto PositionToIndex(llvm::StringRef contents, const clang::clangd::Position& start, const clang::clangd::Position& end) -> std::tuple { - size_t start_index = 0; - size_t end_index = 0; - - for (auto line_number : llvm::seq(end.line)) { - const size_t newline_index = contents.find('\n', end_index); - - CARBON_CHECK(newline_index != std::string::npos, - "Line number greater than number of lines in the file"); - - end_index = newline_index + 1; - - // This condition won't be met if start.line == end.line - // so we need to also check this outside the loop. - if (line_number == start.line) { - start_index = end_index; - } - } - - if (start.line == end.line) { - start_index = end_index; - } + size_t start_index = + GetNthLineIndex(contents, /*cursor_index=*/0, start.line); + size_t end_index = GetNthLineIndex(contents, /*cursor_index=*/start_index, + end.line - start.line); start_index += start.character; end_index += end.character; @@ -94,6 +91,8 @@ static auto ApplyChanges( } } +// Implements `textDocument/didChange`: +// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didChange auto HandleDidChangeTextDocument( Context& context, const clang::clangd::DidChangeTextDocumentParams& params) -> void { @@ -112,6 +111,8 @@ auto HandleDidChangeTextDocument( } } +// Implements `textDocument/didClose`: +// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didClose auto HandleDidCloseTextDocument( Context& context, const clang::clangd::DidCloseTextDocumentParams& params) -> void { diff --git a/toolchain/language_server/testdata/text_document/incremental_sync.carbon b/toolchain/language_server/testdata/text_document/incremental_sync.carbon index 7b7f989254e91..74d876d968233 100644 --- a/toolchain/language_server/testdata/text_document/incremental_sync.carbon +++ b/toolchain/language_server/testdata/text_document/incremental_sync.carbon @@ -2,6 +2,46 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// Content after `didOpen`: +// +// ``` +// fn SecondFunCTIonNNN() {} +// +// fn ThirdFn() {} +// ``` +// +// After first `didChange`: +// +// ``` +// fn SecondFunction() {} +// +// fn ThirdFunction() {} +// ``` +// +// After second `didChange`: +// +// ``` +// fn SecondFunction() {} +// +// fn ThirdFunction() {} +// +// fn FourthFunction() {} +// ``` +// +// After third `didChange`: +// +// ``` +// fn FirstFunction() {} +// +// fn SecondFunction() {} +// +// fn ThirdFunction() {} +// +// fn FourthFunction() {} +// ``` +// +// Fourth `didChange` replaces full content. + // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/language_server/testdata/text_document/incremental_sync.carbon diff --git a/toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon b/toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon new file mode 100644 index 0000000000000..d37ced7889ed0 --- /dev/null +++ b/toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon @@ -0,0 +1,183 @@ +// 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 +// +// The `didChange` here deletes the full middle line. +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/incremental_sync_multiline.carbon + +// --- STDIN +[[@LSP-CALL:initialize]] +[[@LSP-NOTIFY:textDocument/didOpen: + "textDocument": {"uri": "file:/test.carbon", "languageId": "carbon", + "text": "fn F() {}\n// Test\nfn Bar() {}\n"} +]] +[[@LSP-CALL:textDocument/documentSymbol: + "textDocument": {"uri": "file:/test.carbon"} +]] +[[@LSP-NOTIFY:textDocument/didChange: + "textDocument": {"uri": "file:/test.carbon"}, + "contentChanges": [ + {"range": {"start": {"line": 1, "character": 0}, + "end": {"line": 2, "character": 0}}, + "text": ""} + ] +]] +[[@LSP-CALL:textDocument/documentSymbol: + "textDocument": {"uri": "file:/test.carbon"} +]] +[[@LSP-CALL:shutdown]] +[[@LSP-NOTIFY:exit]] + +// --- AUTOUPDATE-SPLIT + +// CHECK:STDOUT: Content-Length: 146{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "id": 1, +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "result": { +// CHECK:STDOUT: "capabilities": { +// CHECK:STDOUT: "documentSymbolProvider": true, +// CHECK:STDOUT: "textDocumentSync": 2 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: }Content-Length: 144{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "method": "textDocument/publishDiagnostics", +// CHECK:STDOUT: "params": { +// CHECK:STDOUT: "diagnostics": [], +// CHECK:STDOUT: "uri": "file:///test.carbon" +// CHECK:STDOUT: } +// CHECK:STDOUT: }Content-Length: 870{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "id": 2, +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "result": [ +// CHECK:STDOUT: { +// CHECK:STDOUT: "kind": 12, +// CHECK:STDOUT: "name": "F", +// CHECK:STDOUT: "range": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 9, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 0, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: "selectionRange": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 4, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 3, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: { +// CHECK:STDOUT: "kind": 12, +// CHECK:STDOUT: "name": "Bar", +// CHECK:STDOUT: "range": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 11, +// CHECK:STDOUT: "line": 2 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 0, +// CHECK:STDOUT: "line": 2 +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: "selectionRange": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 6, +// CHECK:STDOUT: "line": 2 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 3, +// CHECK:STDOUT: "line": 2 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: ] +// CHECK:STDOUT: }Content-Length: 144{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "method": "textDocument/publishDiagnostics", +// CHECK:STDOUT: "params": { +// CHECK:STDOUT: "diagnostics": [], +// CHECK:STDOUT: "uri": "file:///test.carbon" +// CHECK:STDOUT: } +// CHECK:STDOUT: }Content-Length: 870{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "id": 3, +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "result": [ +// CHECK:STDOUT: { +// CHECK:STDOUT: "kind": 12, +// CHECK:STDOUT: "name": "F", +// CHECK:STDOUT: "range": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 9, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 0, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: "selectionRange": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 4, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 3, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: { +// CHECK:STDOUT: "kind": 12, +// CHECK:STDOUT: "name": "Bar", +// CHECK:STDOUT: "range": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 11, +// CHECK:STDOUT: "line": 1 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 0, +// CHECK:STDOUT: "line": 1 +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: "selectionRange": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 6, +// CHECK:STDOUT: "line": 1 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 3, +// CHECK:STDOUT: "line": 1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: ] +// CHECK:STDOUT: }Content-Length: 51{{\r}} +// CHECK:STDOUT: {{\r}} +// CHECK:STDOUT: { +// CHECK:STDOUT: "id": 4, +// CHECK:STDOUT: "jsonrpc": "2.0", +// CHECK:STDOUT: "result": null +// CHECK:STDOUT: } From 5574ad361d7df6b8aba78eed54a2217e4ffc1410 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 28 Feb 2025 23:56:04 -0800 Subject: [PATCH 49/56] Add more empty stack verification (#5020) --- toolchain/check/check_unit.cpp | 7 +++++++ toolchain/check/context.cpp | 18 +++++++++--------- toolchain/check/decl_introducer_state.h | 7 +++++++ toolchain/check/decl_name_stack.h | 7 +++++++ toolchain/check/generic_region_stack.h | 7 +++++++ toolchain/check/region_stack.h | 6 ++++++ 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index 5854a5091ed8b..0e1525acbc84c 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -65,6 +65,10 @@ auto CheckUnit::Run() -> void { // Add a block for the file. context_.inst_block_stack().Push(); + // TODO: Remove this and the pop in `FinishRun` once we properly push and pop + // in the right places. + context_.generic_region_stack().Push(); + InitPackageScopeAndImports(); // Eagerly import the impls declared in the api file to prepare to redeclare @@ -491,6 +495,9 @@ auto CheckUnit::CheckRequiredDefinitions() -> void { } auto CheckUnit::FinishRun() -> void { + // TODO: Remove this once we properly push and pop in the right places. + context_.generic_region_stack().Pop(); + CheckRequiredDeclarations(); CheckRequiredDefinitions(); diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 4ab257f3331fa..075c638a6f0a6 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -31,10 +31,6 @@ Context::Context(DiagnosticEmitter* emitter, import_irs().Reserve(imported_ir_count); import_ir_constant_values_.reserve(imported_ir_count); check_ir_map_.resize(total_ir_count, SemIR::ImportIRId::None); - - // TODO: Remove this and add a `VerifyOnFinish` once we properly push and pop - // in the right places. - generic_region_stack().Push(); } auto Context::TODO(SemIRLoc loc, std::string label) -> bool { @@ -46,17 +42,21 @@ auto Context::TODO(SemIRLoc loc, std::string label) -> bool { auto Context::VerifyOnFinish() const -> void { // Information in all the various context objects should be cleaned up as // various pieces of context go out of scope. At this point, nothing should - // remain. - // node_stack_ will still contain top-level entities. + // remain, so we verify stacks are empty. `node_stack_` is an exception + // because it ends containing all top-level entities. 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_. + CARBON_CHECK(field_decls_stack_.empty()); + decl_name_stack_.VerifyOnFinish(); + decl_introducer_state_stack_.VerifyOnFinish(); scope_stack_.VerifyOnFinish(); - // TODO: Add verification for generic_region_stack_. + generic_region_stack_.VerifyOnFinish(); + vtable_stack_.VerifyOnFinish(); + region_stack_.VerifyOnFinish(); + CARBON_CHECK(impl_lookup_stack_.empty()); #ifndef NDEBUG if (auto verify = sem_ir_->Verify(); !verify.ok()) { diff --git a/toolchain/check/decl_introducer_state.h b/toolchain/check/decl_introducer_state.h index c9ed679ea59ac..e901072490a1b 100644 --- a/toolchain/check/decl_introducer_state.h +++ b/toolchain/check/decl_introducer_state.h @@ -78,6 +78,13 @@ class DeclIntroducerStateStack { return stack_.pop_back_val(); } + // Runs verification that the processing cleanly finished. + auto VerifyOnFinish() const -> void { + CARBON_CHECK(stack_.empty(), + "decl_introduce_state_stack still has {0} entries", + stack_.size()); + } + private: llvm::SmallVector stack_; }; diff --git a/toolchain/check/decl_name_stack.h b/toolchain/check/decl_name_stack.h index a7988d714414b..2e3a1434f0a83 100644 --- a/toolchain/check/decl_name_stack.h +++ b/toolchain/check/decl_name_stack.h @@ -252,6 +252,13 @@ class DeclNameStack { SemIR::AccessKind access_kind) -> SemIR::ScopeLookupResult; + // Runs verification that the processing cleanly finished. + auto VerifyOnFinish() const -> void { + CARBON_CHECK(decl_name_stack_.empty(), + "decl_name_stack still has {0} entries", + decl_name_stack_.size()); + } + private: // Returns a name context corresponding to an empty name. auto MakeEmptyNameContext() -> NameContext; diff --git a/toolchain/check/generic_region_stack.h b/toolchain/check/generic_region_stack.h index 38450acdbd9d3..0eb7238ced1d9 100644 --- a/toolchain/check/generic_region_stack.h +++ b/toolchain/check/generic_region_stack.h @@ -58,6 +58,13 @@ class GenericRegionStack { // Returns the list of dependent instructions in the current generic region. auto PeekDependentInsts() -> llvm::ArrayRef; + // Runs verification that the processing cleanly finished. + auto VerifyOnFinish() const -> void { + CARBON_CHECK(dependent_insts_stack_.empty(), + "generic_region_stack still has {0} entries", + dependent_insts_stack_.all_values_size()); + } + private: // A stack of symbolic constants for enclosing generic regions. ArrayStack dependent_insts_stack_; diff --git a/toolchain/check/region_stack.h b/toolchain/check/region_stack.h index faf2a374a3837..57dda5009f316 100644 --- a/toolchain/check/region_stack.h +++ b/toolchain/check/region_stack.h @@ -68,6 +68,12 @@ class RegionStack { return stack_.PeekArray(); } + // Runs verification that the processing cleanly finished. + auto VerifyOnFinish() const -> void { + CARBON_CHECK(stack_.empty(), "region_stack still has {0} entries", + stack_.all_values_size()); + } + // Returns true if any regions have been added. auto empty() -> bool { return stack_.empty(); } From f0403dadab0348dd2c82ddbceee2bc6dfa992e9f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Sat, 1 Mar 2025 00:00:17 -0800 Subject: [PATCH 50/56] Move None to IdBase (#5030) Use CRTP to eliminate per-type declarations of `None`. Note this adds `None` to a few that may not need it, but eliminates a lot off boilerplate. Note this leaves `GenericInstIndex::None` because it has a more complex construction. Also fix `InstId::InitTombstone` to be `NoneIndex - 1` --- toolchain/base/index_base.h | 10 +++ toolchain/check/scope_index.h | 2 - toolchain/parse/tree.h | 5 -- toolchain/sem_ir/ids.h | 132 +--------------------------------- 4 files changed, 11 insertions(+), 138 deletions(-) diff --git a/toolchain/base/index_base.h b/toolchain/base/index_base.h index c1e8051358427..46ba96a7f0188 100644 --- a/toolchain/base/index_base.h +++ b/toolchain/base/index_base.h @@ -48,6 +48,13 @@ template struct IdBase : public AnyIdBase, public Printable { using AnyIdBase::AnyIdBase; + // Provide a standard `None` mapping to `NoneIndex`. + // + // This uses a `&` to trigger slightly different instantiation behaviors in + // Clang. For context on why this is needed, see http://wg21.link/CWG2800. + // NOLINTNEXTLINE(readability-identifier-naming) + static const IdT& None; + auto Print(llvm::raw_ostream& out) const -> void { out << IdT::Label; if (has_value()) { @@ -63,6 +70,9 @@ struct IdBase : public AnyIdBase, public Printable { } }; +template +constexpr const IdT& IdBase::None = IdT(NoneIndex); + // A lightweight handle to an item that behaves like an index. // // Unlike IdBase, classes derived from IndexBase are not completely opaque, and diff --git a/toolchain/check/scope_index.h b/toolchain/check/scope_index.h index 0d8a99fd83cf3..d8d71b5cd3709 100644 --- a/toolchain/check/scope_index.h +++ b/toolchain/check/scope_index.h @@ -20,13 +20,11 @@ namespace Carbon::Check { struct ScopeIndex : public IndexBase { static constexpr llvm::StringLiteral Label = "scope"; static const ScopeIndex Package; - static const ScopeIndex None; using IndexBase::IndexBase; }; constexpr ScopeIndex ScopeIndex::Package = ScopeIndex(0); -constexpr ScopeIndex ScopeIndex::None = ScopeIndex(NoneIndex); } // namespace Carbon::Check diff --git a/toolchain/parse/tree.h b/toolchain/parse/tree.h index dfc94fc606db7..6221561686fb1 100644 --- a/toolchain/parse/tree.h +++ b/toolchain/parse/tree.h @@ -29,14 +29,9 @@ struct DeferredDefinitionIndex : public IndexBase { static constexpr llvm::StringLiteral Label = "deferred_def"; using ValueType = DeferredDefinition; - static const DeferredDefinitionIndex None; - using IndexBase::IndexBase; }; -constexpr DeferredDefinitionIndex DeferredDefinitionIndex::None = - DeferredDefinitionIndex(NoneIndex); - // A function whose definition is deferred because it is defined inline in a // class or similar scope. // diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index b1a949d2c8b6c..3c820c5ecf700 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -40,9 +40,6 @@ struct InstId : public IdBase { static constexpr llvm::StringLiteral Label = "inst"; using ValueType = Inst; - // An ID with no value. - static const InstId None; - // Represents the result of a name lookup that is temporarily disallowed // because the name is currently being initialized. static const InstId InitTombstone; @@ -52,8 +49,7 @@ struct InstId : public IdBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr InstId InstId::None = InstId(NoneIndex); -constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 2); +constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 1); // An ID of an instruction that is referenced absolutely by another instruction. // This should only be used as the type of a field within a typed instruction @@ -113,8 +109,6 @@ struct ConstantId : public IdBase { // An ID for an expression that is not constant. static const ConstantId NotConstant; - // An ID with no value. - static const ConstantId None; // Returns the constant ID corresponding to a concrete constant, which should // either be in the `constants` block in the file or should be known to be @@ -180,36 +174,24 @@ struct ConstantId : public IdBase { }; constexpr ConstantId ConstantId::NotConstant = ConstantId(NotConstantIndex); -constexpr ConstantId ConstantId::None = ConstantId(NoneIndex); // The ID of a EntityName. struct EntityNameId : public IdBase { static constexpr llvm::StringLiteral Label = "entity_name"; using ValueType = EntityName; - // An ID with no value. - static const EntityNameId None; - using IdBase::IdBase; }; -constexpr EntityNameId EntityNameId::None = EntityNameId(NoneIndex); - // The index of a compile-time binding. This is the de Bruijn level for the // binding -- that is, this is the number of other compile time bindings whose // scope encloses this binding. struct CompileTimeBindIndex : public IndexBase { static constexpr llvm::StringLiteral Label = "comp_time_bind"; - // An index with no value. - static const CompileTimeBindIndex None; - using IndexBase::IndexBase; }; -constexpr CompileTimeBindIndex CompileTimeBindIndex::None = - CompileTimeBindIndex(NoneIndex); - // The index of a runtime parameter in a function. These are allocated // sequentially, left-to-right, to the function parameters that will have // arguments passed to them at runtime. In a `call` instruction, a runtime @@ -220,9 +202,6 @@ constexpr CompileTimeBindIndex CompileTimeBindIndex::None = struct RuntimeParamIndex : public IndexBase { static constexpr llvm::StringLiteral Label = "runtime_param"; - // An index with no value. - static const RuntimeParamIndex None; - // An placeholder for index whose value is not yet known. static const RuntimeParamIndex Unknown; @@ -231,9 +210,6 @@ struct RuntimeParamIndex : public IndexBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr RuntimeParamIndex RuntimeParamIndex::None = - RuntimeParamIndex(NoneIndex); - constexpr RuntimeParamIndex RuntimeParamIndex::Unknown = RuntimeParamIndex(NoneIndex - 1); @@ -242,14 +218,9 @@ struct FunctionId : public IdBase { static constexpr llvm::StringLiteral Label = "function"; using ValueType = Function; - // An ID with no value. - static const FunctionId None; - using IdBase::IdBase; }; -constexpr FunctionId FunctionId::None = FunctionId(NoneIndex); - // The ID of an IR within the set of all IRs being evaluated in the current // check execution. struct CheckIRId : public IdBase { @@ -262,109 +233,66 @@ struct ClassId : public IdBase { static constexpr llvm::StringLiteral Label = "class"; using ValueType = Class; - // An ID with no value. - static const ClassId None; - using IdBase::IdBase; }; -constexpr ClassId ClassId::None = ClassId(NoneIndex); - // The ID of an interface. struct InterfaceId : public IdBase { static constexpr llvm::StringLiteral Label = "interface"; using ValueType = Interface; - // An ID with no value. - static const InterfaceId None; - using IdBase::IdBase; }; -constexpr InterfaceId InterfaceId::None = InterfaceId(NoneIndex); - // The ID of an associated constant. struct AssociatedConstantId : public IdBase { static constexpr llvm::StringLiteral Label = "assoc_const"; using ValueType = AssociatedConstant; - // An ID with no value. - static const AssociatedConstantId None; - using IdBase::IdBase; }; -constexpr AssociatedConstantId AssociatedConstantId::None = - AssociatedConstantId(NoneIndex); - // The ID of an facet type value. struct FacetTypeId : public IdBase { static constexpr llvm::StringLiteral Label = "facet_type"; using ValueType = FacetTypeInfo; - // An ID with no value. - static const FacetTypeId None; - using IdBase::IdBase; }; -constexpr FacetTypeId FacetTypeId::None = FacetTypeId(NoneIndex); - // The ID of an resolved facet type value. struct CompleteFacetTypeId : public IdBase { static constexpr llvm::StringLiteral Label = "complete_facet_type"; using ValueType = CompleteFacetType; - // An ID with no value. - static const CompleteFacetTypeId None; - using IdBase::IdBase; }; -constexpr CompleteFacetTypeId CompleteFacetTypeId::None = - CompleteFacetTypeId(NoneIndex); - // The ID of an impl. struct ImplId : public IdBase { static constexpr llvm::StringLiteral Label = "impl"; using ValueType = Impl; - // An ID with no value. - static const ImplId None; - using IdBase::IdBase; }; -constexpr ImplId ImplId::None = ImplId(NoneIndex); - // The ID of a generic. struct GenericId : public IdBase { static constexpr llvm::StringLiteral Label = "generic"; using ValueType = Generic; - // An ID with no value. - static const GenericId None; - using IdBase::IdBase; }; -constexpr GenericId GenericId::None = GenericId(NoneIndex); - // The ID of a specific, which is the result of specifying the generic arguments // for a generic. struct SpecificId : public IdBase { static constexpr llvm::StringLiteral Label = "specific"; using ValueType = Specific; - // An ID with no value. This is typically used to represent a non-generic - // entity. - static const SpecificId None; - using IdBase::IdBase; }; -constexpr SpecificId SpecificId::None = SpecificId(NoneIndex); - // The index of an instruction that depends on generic parameters within a // region of a generic. A corresponding specific version of the instruction can // be found in each specific corresponding to that generic. This is a pair of a @@ -419,22 +347,14 @@ struct ImportCppId : public IdBase { static constexpr llvm::StringLiteral Label = "import_cpp"; using ValueType = ImportCpp; - // An ID with no value. - static const ImportCppId None; - using IdBase::IdBase; }; -constexpr ImportCppId ImportCppId::None = ImportCppId(NoneIndex); - // The ID of an IR within the set of imported IRs, both direct and indirect. struct ImportIRId : public IdBase { static constexpr llvm::StringLiteral Label = "ir"; using ValueType = ImportIR; - // An ID with no value. - static const ImportIRId None; - // The implicit `api` import, for an `impl` file. A null entry is added if // there is none, as in an `api`, in which case this ID should not show up in // instructions. @@ -443,7 +363,6 @@ struct ImportIRId : public IdBase { using IdBase::IdBase; }; -constexpr ImportIRId ImportIRId::None = ImportIRId(NoneIndex); constexpr ImportIRId ImportIRId::ApiForImpl = ImportIRId(0); // A boolean value. @@ -536,9 +455,6 @@ struct NameId : public IdBase { // names().GetFormatted() is used for diagnostics. using DiagnosticType = DiagnosticTypeInfo; - // An ID with no value. - static const NameId None; - // An enum of special names. enum class SpecialNameId : uint8_t { #define CARBON_SPECIAL_NAME_ID_FOR_ENUM(Name) Name, @@ -582,8 +498,6 @@ struct NameId : public IdBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr NameId NameId::None = NameId(NoneIndex); - // Define the special `static const NameId` values. #define CARBON_SPECIAL_NAME_ID_FOR_DEF(Name) \ constexpr NameId NameId::Name = \ @@ -602,15 +516,12 @@ struct NameScopeId : public IdBase { static constexpr llvm::StringLiteral Label = "name_scope"; using ValueType = NameScope; - // An ID with no value. - static const NameScopeId None; // The package (or file) name scope, guaranteed to be the first added. static const NameScopeId Package; using IdBase::IdBase; }; -constexpr NameScopeId NameScopeId::None = NameScopeId(NoneIndex); constexpr NameScopeId NameScopeId::Package = NameScopeId(0); // The ID of an instruction block. @@ -637,9 +548,6 @@ struct InstBlockId : public IdBase { // be inserted into it. static const InstBlockId GlobalInit; - // An ID with no value. - static const InstBlockId None; - // An ID for unreachable code. static const InstBlockId Unreachable; @@ -651,7 +559,6 @@ constexpr InstBlockId InstBlockId::Empty = InstBlockId(0); constexpr InstBlockId InstBlockId::Exports = InstBlockId(1); constexpr InstBlockId InstBlockId::ImportRefs = InstBlockId(2); constexpr InstBlockId InstBlockId::GlobalInit = InstBlockId(3); -constexpr InstBlockId InstBlockId::None = InstBlockId(NoneIndex); constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(NoneIndex - 1); // An ID of an instruction block that is referenced absolutely by an @@ -704,14 +611,9 @@ struct ExprRegionId : public IdBase { static constexpr llvm::StringLiteral Label = "region"; using ValueType = ExprRegion; - // An ID with no value. - static const ExprRegionId None; - using IdBase::IdBase; }; -constexpr ExprRegionId ExprRegionId::None = ExprRegionId(NoneIndex); - // The ID of a struct type field block. struct StructTypeFieldsId : public IdBase { static constexpr llvm::StringLiteral Label = "struct_type_fields"; @@ -719,9 +621,6 @@ struct StructTypeFieldsId : public IdBase { using ElementType = StructTypeField; using ValueType = llvm::MutableArrayRef; - // An ID with no value. - static const StructTypeFieldsId None; - // The canonical empty block, reused to avoid allocating empty vectors. Always // the 0-index block. static const StructTypeFieldsId Empty; @@ -729,8 +628,6 @@ struct StructTypeFieldsId : public IdBase { using IdBase::IdBase; }; -constexpr StructTypeFieldsId StructTypeFieldsId::None = - StructTypeFieldsId(NoneIndex); constexpr StructTypeFieldsId StructTypeFieldsId::Empty = StructTypeFieldsId(0); // The ID of a type. @@ -742,9 +639,6 @@ struct TypeId : public IdBase { // `InstIdAsType` or `TypeOfInstId` as the diagnostic argument type. using DiagnosticType = DiagnosticTypeInfo; - // An ID with no value. - static const TypeId None; - using IdBase::IdBase; // Returns the ID of the type corresponding to the constant `const_id`, which @@ -765,8 +659,6 @@ struct TypeId : public IdBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr TypeId TypeId::None = TypeId(NoneIndex); - // The ID of a type block. struct TypeBlockId : public IdBase { static constexpr llvm::StringLiteral Label = "type_block"; @@ -774,9 +666,6 @@ struct TypeBlockId : public IdBase { using ElementType = TypeId; using ValueType = llvm::MutableArrayRef; - // An ID with no value. - static const TypeBlockId None; - // The canonical empty block, reused to avoid allocating empty vectors. Always // the 0-index block. static const TypeBlockId Empty; @@ -784,27 +673,19 @@ struct TypeBlockId : public IdBase { using IdBase::IdBase; }; -constexpr TypeBlockId TypeBlockId::None = TypeBlockId(NoneIndex); constexpr TypeBlockId TypeBlockId::Empty = TypeBlockId(0); // An index for element access, for structs, tuples, and classes. struct ElementIndex : public IndexBase { static constexpr llvm::StringLiteral Label = "element"; using IndexBase::IndexBase; - - // An ID with no value. - static const ElementIndex None; }; -constexpr ElementIndex ElementIndex::None = ElementIndex(NoneIndex); - // The ID of a library name. This is either a string literal or `default`. struct LibraryNameId : public IdBase { static constexpr llvm::StringLiteral Label = "library_name"; using DiagnosticType = DiagnosticTypeInfo; - // An ID with no value. - static const LibraryNameId None; // The name of `default`. static const LibraryNameId Default; // Track cases where the library name was set, but has been diagnosed and @@ -825,7 +706,6 @@ struct LibraryNameId : public IdBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr LibraryNameId LibraryNameId::None = LibraryNameId(NoneIndex); constexpr LibraryNameId LibraryNameId::Default = LibraryNameId(NoneIndex - 1); constexpr LibraryNameId LibraryNameId::Error = LibraryNameId(NoneIndex - 2); @@ -834,14 +714,9 @@ struct ImportIRInstId : public IdBase { static constexpr llvm::StringLiteral Label = "import_ir_inst"; using ValueType = ImportIRInst; - // An ID with no value. - static const ImportIRInstId None; - using IdBase::IdBase; }; -constexpr ImportIRInstId ImportIRInstId::None = ImportIRInstId(NoneIndex); - // A SemIR location used as the location of instructions. // // Contents: @@ -855,9 +730,6 @@ struct LocId : public IdBase { // operations performed implicitly. static const int32_t ImplicitBit = 1 << 30; - // An ID with no value. - static const LocId None; - using IdBase::IdBase; // NOLINTNEXTLINE(google-explicit-constructor) @@ -909,8 +781,6 @@ struct LocId : public IdBase { auto Print(llvm::raw_ostream& out) const -> void; }; -constexpr LocId LocId::None = LocId(Parse::NodeId::None); - // Polymorphic id for fields in `Any[...]` typed instruction category. Used for // fields where the specific instruction structs have different field types in // that position or do not have a field in that position at all. Allows From 87b9cab7b1c6a239bef2c22a8ba0fe5cad17f639 Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Mon, 3 Mar 2025 11:38:19 +0100 Subject: [PATCH 51/56] Add support for importing a trivial global C++ function (#5033) ASTUnit is owned by `CompileSubcommand`, passed through `Unit` to be populated in `ImportCppFiles()` and used via `SemIR::File`. When generating the AST, pass `-x c++` args to compile C++ (temporary until we pass args properly). `Cpp` namespace is marked as a special namespace and has dedicated logic in `LookupNameInExactScope()`. The logic for importing declarations from C++ to Carbon is in `import_cpp.cpp`, but we're likely to want to refactor this signfiicantly over time as it grows (perhaps a dedicated directory?). Part of #4666. --- toolchain/check/BUILD | 1 + toolchain/check/check.h | 3 + toolchain/check/check_unit.cpp | 12 +- toolchain/check/import_cpp.cpp | 170 +++++- toolchain/check/import_cpp.h | 14 +- toolchain/check/name_lookup.cpp | 14 + .../cpp/no_prelude/function_decl.carbon | 489 +++++++++++++++++- toolchain/diagnostics/diagnostic_kind.def | 1 + toolchain/driver/compile_subcommand.cpp | 4 +- toolchain/sem_ir/BUILD | 1 + toolchain/sem_ir/file.h | 9 + toolchain/sem_ir/name_scope.h | 9 + 12 files changed, 714 insertions(+), 13 deletions(-) diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index d31dc1a013726..efd7bae3895fa 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -112,6 +112,7 @@ cc_library( "//toolchain/sem_ir:inst", "//toolchain/sem_ir:typed_insts", "@llvm-project//clang:frontend", + "@llvm-project//clang:sema", "@llvm-project//clang:tooling", "@llvm-project//llvm:Support", ], diff --git a/toolchain/check/check.h b/toolchain/check/check.h index f876c681ae453..50d60e8240443 100644 --- a/toolchain/check/check.h +++ b/toolchain/check/check.h @@ -27,6 +27,9 @@ struct Unit { // The unit's SemIR, provided as empty and filled in by CheckParseTrees. SemIR::File* sem_ir; + + // The Clang AST owned by `CompileSubcommand`. + std::unique_ptr* cpp_ast = nullptr; }; // Checks a group of parse trees. This will use imports to decide the order of diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index 0e1525acbc84c..d1cdcbcafbd98 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -135,8 +135,16 @@ auto CheckUnit::InitPackageScopeAndImports() -> void { ImportCurrentPackage(package_inst_id, namespace_type_id); CARBON_CHECK(context_.scope_stack().PeekIndex() == ScopeIndex::Package); ImportOtherPackages(namespace_type_id); - ImportCppFiles(context_, unit_and_imports_->unit->sem_ir->filename(), - unit_and_imports_->cpp_import_names, fs_); + + const auto& cpp_import_names = unit_and_imports_->cpp_import_names; + if (!cpp_import_names.empty()) { + auto* cpp_ast = unit_and_imports_->unit->cpp_ast; + CARBON_CHECK(cpp_ast); + CARBON_CHECK(!cpp_ast->get()); + *cpp_ast = + ImportCppFiles(context_, unit_and_imports_->unit->sem_ir->filename(), + cpp_import_names, fs_); + } } auto CheckUnit::CollectDirectImports( diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index 8cdd79ffb6281..7aa5f8275076c 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -9,6 +9,7 @@ #include #include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Sema/Lookup.h" #include "clang/Tooling/Tooling.h" #include "common/raw_string_ostream.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -21,6 +22,7 @@ #include "toolchain/check/type.h" #include "toolchain/diagnostics/diagnostic.h" #include "toolchain/diagnostics/format_providers.h" +#include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/name_scope.h" namespace Carbon::Check { @@ -61,9 +63,10 @@ static auto GenerateAst(Context& context, llvm::StringRef importing_file_path, diagnostic_options.get()); // TODO: Share compilation flags with ClangRunner. auto ast = clang::tooling::buildASTFromCodeWithArgs( - GenerateCppIncludesHeaderCode(context, imports), {}, - (importing_file_path + ".generated.cpp_imports.h").str(), "clang-tool", - std::make_shared(), + GenerateCppIncludesHeaderCode(context, imports), + // Parse C++ (and not C) + {"-x", "c++"}, (importing_file_path + ".generated.cpp_imports.h").str(), + "clang-tool", std::make_shared(), clang::tooling::getClangStripDependencyFileAdjuster(), clang::tooling::FileContentMappings(), &diagnostics_consumer, fs); // TODO: Implement and use a DynamicRecursiveASTVisitor to traverse the AST. @@ -115,12 +118,14 @@ static auto AddNamespace(Context& context, PackageNameId cpp_package_id, auto ImportCppFiles(Context& context, llvm::StringRef importing_file_path, llvm::ArrayRef imports, llvm::IntrusiveRefCntPtr fs) - -> void { + -> std::unique_ptr { if (imports.empty()) { - return; + return nullptr; } - auto [ast, ast_has_error] = + CARBON_CHECK(!context.sem_ir().cpp_ast()); + + auto [generated_ast, ast_has_error] = GenerateAst(context, importing_file_path, imports, fs); PackageNameId package_id = imports.front().package_id; @@ -131,10 +136,163 @@ auto ImportCppFiles(Context& context, llvm::StringRef importing_file_path, auto name_scope_id = AddNamespace(context, package_id, imports); SemIR::NameScope& name_scope = context.name_scopes().Get(name_scope_id); name_scope.set_is_closed_import(true); + name_scope.set_is_cpp_scope(true); + + context.sem_ir().set_cpp_ast(generated_ast.get()); if (ast_has_error) { name_scope.set_has_error(); } + + return std::move(generated_ast); +} + +// Look ups the given name in the Clang AST. Returns the lookup result if lookup +// was successful. +static auto ClangLookup(Context& context, SemIR::LocId loc_id, + SemIR::NameId name_id) + -> std::optional { + std::optional name = + context.names().GetAsStringIfIdentifier(name_id); + if (!name) { + // Special names never exist in C++ code. + return std::nullopt; + } + + clang::ASTUnit* ast = context.sem_ir().cpp_ast(); + CARBON_CHECK(ast); + clang::Sema& sema = ast->getSema(); + + clang::LookupResult lookup( + sema, + clang::DeclarationNameInfo( + clang::DeclarationName( + sema.getPreprocessor().getIdentifierInfo(*name)), + clang::SourceLocation()), + clang::Sema::LookupNameKind::LookupOrdinaryName); + + bool found = sema.LookupQualifiedName( + lookup, ast->getASTContext().getTranslationUnitDecl()); + + if (lookup.isClassLookup()) { + // TODO: To support class lookup, also return the AccessKind for storage. + context.TODO(loc_id, "Unsupported: Lookup in Class"); + return std::nullopt; + } + + if (!found) { + return std::nullopt; + } + + return lookup; +} + +// Imports a function declaration from Clang to Carbon. If successful, returns +// the new Carbon function declaration `InstId`. +static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id, + SemIR::NameScopeId scope_id, + SemIR::NameId name_id, + const clang::FunctionDecl* clang_decl) + -> SemIR::InstId { + if (clang_decl->isVariadic()) { + context.TODO(loc_id, "Unsupported: Variadic function"); + return SemIR::ErrorInst::SingletonInstId; + } + if (!clang_decl->isGlobal()) { + context.TODO(loc_id, "Unsupported: Non-global function"); + return SemIR::ErrorInst::SingletonInstId; + } + if (clang_decl->getTemplatedKind() != clang::FunctionDecl::TK_NonTemplate) { + context.TODO(loc_id, "Unsupported: Template function"); + return SemIR::ErrorInst::SingletonInstId; + } + if (!clang_decl->param_empty()) { + context.TODO(loc_id, "Unsupported: Function with parameters"); + return SemIR::ErrorInst::SingletonInstId; + } + if (!clang_decl->getReturnType()->isVoidType()) { + context.TODO(loc_id, "Unsupported: Function with non-void return type"); + return SemIR::ErrorInst::SingletonInstId; + } + + auto function_decl = SemIR::FunctionDecl{ + SemIR::TypeId::None, SemIR::FunctionId::None, SemIR::InstBlockId::Empty}; + auto decl_id = AddPlaceholderInst( + context, SemIR::LocIdAndInst(Parse::NodeId::None, function_decl)); + + auto function_info = SemIR::Function{ + {.name_id = name_id, + .parent_scope_id = scope_id, + .generic_id = SemIR::GenericId::None, + .first_param_node_id = Parse::NodeId::None, + .last_param_node_id = Parse::NodeId::None, + .pattern_block_id = SemIR::InstBlockId::Empty, + .implicit_param_patterns_id = SemIR::InstBlockId::Empty, + .param_patterns_id = SemIR::InstBlockId::Empty, + .call_params_id = SemIR::InstBlockId::Empty, + .is_extern = false, + .extern_library_id = SemIR::LibraryNameId::None, + .non_owning_decl_id = SemIR::InstId::None, + .first_owning_decl_id = decl_id, + .definition_id = SemIR::InstId::None}, + {.return_slot_pattern_id = SemIR::InstId::None, + .virtual_modifier = SemIR::FunctionFields::VirtualModifier::None, + .self_param_id = SemIR::InstId::None}}; + + function_decl.function_id = context.functions().Add(function_info); + + function_decl.type_id = GetFunctionType(context, function_decl.function_id, + SemIR::SpecificId::None); + + ReplaceInstBeforeConstantUse(context, decl_id, function_decl); + + return decl_id; +} + +// Imports a declaration from Clang to Carbon. If successful, returns the +// instruction for the new Carbon declaration. +static auto ImportNameDecl(Context& context, SemIR::LocId loc_id, + SemIR::NameScopeId scope_id, SemIR::NameId name_id, + const clang::NamedDecl* clang_decl) + -> SemIR::InstId { + if (const auto* clang_function_decl = + clang::dyn_cast(clang_decl)) { + return ImportFunctionDecl(context, loc_id, scope_id, name_id, + clang_function_decl); + } + + context.TODO(loc_id, llvm::formatv("Unsupported: Declaration type {0}", + clang_decl->getDeclKindName()) + .str()); + return SemIR::InstId::None; +} + +auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id, + SemIR::NameScopeId scope_id, SemIR::NameId name_id) + -> SemIR::InstId { + auto lookup = ClangLookup(context, loc_id, name_id); + if (!lookup) { + return SemIR::InstId::None; + } + + DiagnosticAnnotationScope annotate_diagnostics( + &context.emitter(), [&](auto& builder) { + CARBON_DIAGNOSTIC(InCppNameLookup, Note, + "in `Cpp` name lookup for `{0}`", SemIR::NameId); + builder.Note(loc_id, InCppNameLookup, name_id); + }); + + if (!lookup->isSingleResult()) { + context.TODO(loc_id, + llvm::formatv("Unsupported: Lookup succeeded but couldn't " + "find a single result; LookupResultKind: {0}", + lookup->getResultKind()) + .str()); + return SemIR::ErrorInst::SingletonInstId; + } + + return ImportNameDecl(context, loc_id, scope_id, name_id, + lookup->getFoundDecl()); } } // namespace Carbon::Check diff --git a/toolchain/check/import_cpp.h b/toolchain/check/import_cpp.h index 886a983f0a5e6..b9303c6569fe6 100644 --- a/toolchain/check/import_cpp.h +++ b/toolchain/check/import_cpp.h @@ -11,11 +11,19 @@ namespace Carbon::Check { -// Generates a C++ header that includes the imported cpp files, parses it and -// report errors and warnings. If successful, adds a `Cpp` namespace. +// Generates a C++ header that includes the imported cpp files, parses it, +// generates the AST from it and links `SemIR::File` to it. Report C++ errors +// and warnings. If successful, adds a `Cpp` namespace and returns the AST. auto ImportCppFiles(Context& context, llvm::StringRef importing_file_path, llvm::ArrayRef imports, - llvm::IntrusiveRefCntPtr fs) -> void; + llvm::IntrusiveRefCntPtr fs) + -> std::unique_ptr; + +// Looks up the given name in the Clang AST generated when importing C++ code. +// If successful, generates the instruction and returns the new `InstId`. +auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id, + SemIR::NameScopeId scope_id, SemIR::NameId name_id) + -> SemIR::InstId; } // namespace Carbon::Check diff --git a/toolchain/check/name_lookup.cpp b/toolchain/check/name_lookup.cpp index 2662355cf5736..7482e952ee8af 100644 --- a/toolchain/check/name_lookup.cpp +++ b/toolchain/check/name_lookup.cpp @@ -6,9 +6,11 @@ #include "toolchain/check/generic.h" #include "toolchain/check/import.h" +#include "toolchain/check/import_cpp.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/type_completion.h" #include "toolchain/diagnostics/format_providers.h" +#include "toolchain/sem_ir/name_scope.h" namespace Carbon::Check { @@ -150,6 +152,18 @@ auto LookupNameInExactScope(Context& context, SemIR::LocId loc_id, scope.import_ir_scopes(), name_id), SemIR::AccessKind::Public); } + + if (scope.is_cpp_scope()) { + SemIR::InstId imported_inst_id = + ImportNameFromCpp(context, loc_id, scope_id, name_id); + if (imported_inst_id.has_value()) { + SemIR::ScopeLookupResult result = SemIR::ScopeLookupResult::MakeFound( + imported_inst_id, SemIR::AccessKind::Public); + scope.AddRequired({.name_id = name_id, .result = result}); + return result; + } + } + return SemIR::ScopeLookupResult::MakeNotFound(); } diff --git a/toolchain/check/testdata/interop/cpp/no_prelude/function_decl.carbon b/toolchain/check/testdata/interop/cpp/no_prelude/function_decl.carbon index f4deda52baaaf..1b8e5e60441e8 100644 --- a/toolchain/check/testdata/interop/cpp/no_prelude/function_decl.carbon +++ b/toolchain/check/testdata/interop/cpp/no_prelude/function_decl.carbon @@ -18,18 +18,505 @@ library "[[@TEST_NAME]]"; import Cpp library "function_decl.h"; +fn MyF() { + Cpp.foo(); +} + +// --- fail_import_function_decl_use_different_name.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "function_decl.h"; + +fn MyF() { + // CHECK:STDERR: fail_import_function_decl_use_different_name.carbon:[[@LINE+4]]:3: error: member name `bar` not found in `Cpp` [MemberNameNotFoundInScope] + // CHECK:STDERR: Cpp.bar(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.bar(); +} + +// --- function_special_name_decl.h + +void base(); + +// --- fail_import_function_special_name_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "function_special_name_decl.h"; + +fn MyF() { + // CHECK:STDERR: fail_import_function_special_name_decl.carbon:[[@LINE+4]]:3: error: member name `base` not found in `Cpp` [MemberNameNotFoundInScope] + // CHECK:STDERR: Cpp.base(); + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + Cpp.base(); +} + +// --- import_function_escaped_special_name_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "function_special_name_decl.h"; + +fn MyF() { + Cpp.r#base(); +} + +// --- overloaded_function_decl.h + +void foo(); +void foo(int value); + +// --- fail_import_overloaded_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "overloaded_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_overloaded_function_decl.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Lookup succeeded but couldn't find a single result; LookupResultKind: 3` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_overloaded_function_decl.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + +// --- variadic_function_decl.h + +void foo(int...); + +// --- fail_import_variadic_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "variadic_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_variadic_function_decl.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Variadic function` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_variadic_function_decl.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + +// --- non_global_function_decl.h + +static void foo(); + +// --- fail_import_non_global_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "non_global_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_non_global_function_decl.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Non-global function` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_non_global_function_decl.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + +// TODO: Test that template functions are unsupported. +// This is not tested because template functions are not considered a single result when doing lookup. + +// --- parameterized_function_decl.h + +void foo(int); + +// --- fail_import_parameterized_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "parameterized_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_parameterized_function_decl.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Function with parameters` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_parameterized_function_decl.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + +// --- non_void_return_function_decl.h + +int foo(); + +// --- fail_import_non_void_return_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "non_void_return_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_non_void_return_function_decl.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Function with non-void return type` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_non_void_return_function_decl.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + +// --- non_function_decl.h + +class foo; + +// --- fail_import_non_function_decl.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "non_function_decl.h"; + +fn F() { + // CHECK:STDERR: fail_import_non_function_decl.carbon:[[@LINE+11]]:3: error: semantics TODO: `Unsupported: Declaration type CXXRecord` [SemanticsTodo] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_import_non_function_decl.carbon:[[@LINE+8]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_non_function_decl.carbon:[[@LINE+4]]:3: error: member name `foo` not found in `Cpp` [MemberNameNotFoundInScope] + // CHECK:STDERR: Cpp.foo(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + Cpp.foo(); +} + // CHECK:STDOUT: --- import_function_decl.carbon // CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete] +// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] +// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] {} +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = @MyF.%foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .MyF = %MyF.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @MyF() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {} {} +// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, %foo.decl [concrete = constants.%foo] +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @foo[](); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_function_decl_use_different_name.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete] +// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .bar = +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { // CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .MyF = %MyF.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Cpp.import_cpp = import_cpp { // CHECK:STDOUT: import Cpp "function_decl.h" // CHECK:STDOUT: } +// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @MyF() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %bar.ref: = name_ref bar, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_function_special_name_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete] +// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .MyF = %MyF.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "function_special_name_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @MyF() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %base.ref: = name_ref base, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- import_function_escaped_special_name_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete] +// CHECK:STDOUT: %base.type: type = fn_type @base [concrete] +// CHECK:STDOUT: %base: %base.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .r#base = @MyF.%base.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .MyF = %MyF.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "function_special_name_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @MyF() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %base.decl: %base.type = fn_decl @base [concrete = constants.%base] {} {} +// CHECK:STDOUT: %base.ref: %base.type = name_ref r#base, %base.decl [concrete = constants.%base] +// CHECK:STDOUT: %base.call: init %empty_tuple.type = call %base.ref() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @base[](); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_overloaded_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "overloaded_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_variadic_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "variadic_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_non_global_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "non_global_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_parameterized_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "parameterized_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_non_void_return_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "non_void_return_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_non_function_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "non_function_decl.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index d5e72449730a5..b44b7165fb74c 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -318,6 +318,7 @@ CARBON_DIAGNOSTIC_KIND(QualifiedDeclInUndefinedInterfaceScope) // Name lookup. CARBON_DIAGNOSTIC_KIND(FromExtendHere) +CARBON_DIAGNOSTIC_KIND(InCppNameLookup) CARBON_DIAGNOSTIC_KIND(InNameLookup) CARBON_DIAGNOSTIC_KIND(NameAmbiguousDueToExtend) CARBON_DIAGNOSTIC_KIND(NameNotFound) diff --git a/toolchain/driver/compile_subcommand.cpp b/toolchain/driver/compile_subcommand.cpp index 6743f38491f1c..de9909854b1ee 100644 --- a/toolchain/driver/compile_subcommand.cpp +++ b/toolchain/driver/compile_subcommand.cpp @@ -412,6 +412,7 @@ class CompilationUnit { std::optionalconst Parse::TreeAndSubtrees&>> tree_and_subtrees_getter_; std::optional sem_ir_; + std::unique_ptr cpp_ast_; std::unique_ptr llvm_context_; std::unique_ptr module_; }; @@ -509,7 +510,8 @@ auto CompilationUnit::GetCheckUnit(SemIR::CheckIRId check_ir_id) .value_stores = &value_stores_, .timings = timings_ ? &*timings_ : nullptr, .tree_and_subtrees_getter = *tree_and_subtrees_getter_, - .sem_ir = &*sem_ir_}; + .sem_ir = &*sem_ir_, + .cpp_ast = &cpp_ast_}; } auto CompilationUnit::PostCheck() -> void { diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 7043592ac9f83..48f34e4cedfb3 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -126,6 +126,7 @@ cc_library( "//toolchain/lex:token_kind", "//toolchain/parse:node_kind", "//toolchain/parse:tree", + "@llvm-project//clang:frontend", "@llvm-project//llvm:Support", ], ) diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 257b04fc602f3..dd63814a9189c 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -5,6 +5,7 @@ #ifndef CARBON_TOOLCHAIN_SEM_IR_FILE_H_ #define CARBON_TOOLCHAIN_SEM_IR_FILE_H_ +#include "clang/Frontend/ASTUnit.h" #include "common/error.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" @@ -186,6 +187,10 @@ class File : public Printable { auto import_cpps() const -> const ValueStore& { return import_cpps_; } + auto cpp_ast() -> clang::ASTUnit* { return cpp_ast_; } + // TODO: When the AST can be created before creating `File`, initialize the + // pointer in the constructor and remove this function. + auto set_cpp_ast(clang::ASTUnit* cpp_ast) -> void { cpp_ast_ = cpp_ast; } auto names() const -> NameStoreWrapper { return NameStoreWrapper(&identifiers()); } @@ -301,6 +306,10 @@ class File : public Printable { // List of Cpp imports. ValueStore import_cpps_; + // The Clang AST to use when looking up `Cpp` names. Null if there are no + // `Cpp` imports. + clang::ASTUnit* cpp_ast_ = nullptr; + // Type blocks within the IR. These reference entries in types_. Storage for // the data is provided by allocator_. BlockValueStore type_blocks_; diff --git a/toolchain/sem_ir/name_scope.h b/toolchain/sem_ir/name_scope.h index 0c757d06d3521..c8fff30407330 100644 --- a/toolchain/sem_ir/name_scope.h +++ b/toolchain/sem_ir/name_scope.h @@ -212,6 +212,12 @@ class NameScope : public Printable { is_closed_import_ = is_closed_import; } + auto is_cpp_scope() const -> bool { return is_cpp_scope_; } + + auto set_is_cpp_scope(bool is_cpp_scope) -> void { + is_cpp_scope_ = is_cpp_scope; + } + // Returns true if this name scope describes an imported package. auto is_imported_package() const -> bool { return is_closed_import() && parent_scope_id() == NameScopeId::Package; @@ -272,6 +278,9 @@ class NameScope : public Printable { // True if this is a closed namespace created by importing a package. bool is_closed_import_ = false; + // True if this is the `Cpp` namescope used when importing C++ code. + bool is_cpp_scope_ = false; + // Imported IR scopes that compose this namespace. This will be empty for // scopes that correspond to the current package. llvm::SmallVector, 0> import_ir_scopes_; From 437d3b9af6514c8f4d521a24cf6e242e6fe065c7 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 3 Mar 2025 08:14:06 -0800 Subject: [PATCH 52/56] Factor out fuzzing disablement in the driver (#5048) We end up needing to do this in any driver subcommand that reaches into external code that may not be fully fuzz-clean. No need to grow multiple different diagnostics for each, we can use a common diagnostic. --- toolchain/diagnostics/diagnostic_kind.def | 3 +- toolchain/driver/BUILD | 1 + toolchain/driver/clang_subcommand.cpp | 6 +--- toolchain/driver/driver_subcommand.cpp | 29 +++++++++++++++++++ toolchain/driver/driver_subcommand.h | 9 ++++++ toolchain/driver/lld_subcommand.cpp | 6 +--- .../driver/testdata/fail_clang_fuzzing.cpp | 2 +- .../driver/testdata/fail_lld_fuzzing.carbon | 2 +- 8 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 toolchain/driver/driver_subcommand.cpp diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index b44b7165fb74c..5484ba01fb5b6 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -23,13 +23,12 @@ CARBON_DIAGNOSTIC_KIND(DriverInstallInvalid) CARBON_DIAGNOSTIC_KIND(DriverCommandLineParseFailed) -CARBON_DIAGNOSTIC_KIND(ClangFuzzingDisallowed) CARBON_DIAGNOSTIC_KIND(CompilePhaseFlagConflict) CARBON_DIAGNOSTIC_KIND(CompilePreludeManifestError) CARBON_DIAGNOSTIC_KIND(CompileInputNotRegularFile) CARBON_DIAGNOSTIC_KIND(CompileOutputFileOpenError) CARBON_DIAGNOSTIC_KIND(FormatMultipleFilesToOneOutput) -CARBON_DIAGNOSTIC_KIND(LLDFuzzingDisallowed) +CARBON_DIAGNOSTIC_KIND(ToolFuzzingDisallowed) // ============================================================================ // SourceBuffer diagnostics diff --git a/toolchain/driver/BUILD b/toolchain/driver/BUILD index d845a46a186ff..375312692146b 100644 --- a/toolchain/driver/BUILD +++ b/toolchain/driver/BUILD @@ -95,6 +95,7 @@ cc_library( "compile_subcommand.h", "driver.cpp", "driver_env.h", + "driver_subcommand.cpp", "format_subcommand.cpp", "format_subcommand.h", "language_server_subcommand.cpp", diff --git a/toolchain/driver/clang_subcommand.cpp b/toolchain/driver/clang_subcommand.cpp index a1291637887a4..4e663568f448a 100644 --- a/toolchain/driver/clang_subcommand.cpp +++ b/toolchain/driver/clang_subcommand.cpp @@ -50,11 +50,7 @@ auto ClangSubcommand::Run(DriverEnv& driver_env) -> DriverResult { // Don't run Clang when fuzzing, it is known to not be reliable under fuzzing // due to many unfixed issues. - if (driver_env.fuzzing) { - CARBON_DIAGNOSTIC( - ClangFuzzingDisallowed, Error, - "preventing fuzzing of `clang` subcommand due to library crashes"); - driver_env.emitter.Emit(ClangFuzzingDisallowed); + if (!DisableFuzzingExternalLibraries(driver_env, "clang")) { return {.success = false}; } diff --git a/toolchain/driver/driver_subcommand.cpp b/toolchain/driver/driver_subcommand.cpp new file mode 100644 index 0000000000000..a1edf2a9970ff --- /dev/null +++ b/toolchain/driver/driver_subcommand.cpp @@ -0,0 +1,29 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/driver/driver_subcommand.h" + +#include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/Triple.h" +#include "toolchain/driver/lld_runner.h" + +namespace Carbon { + +auto DriverSubcommand::DisableFuzzingExternalLibraries(DriverEnv& driver_env, + llvm::StringRef name) + -> bool { + // Only need to do anything when fuzzing. + if (!driver_env.fuzzing) { + return true; + } + + CARBON_DIAGNOSTIC( + ToolFuzzingDisallowed, Error, + "preventing fuzzing of `{0}` subcommand due to external library", + std::string); + driver_env.emitter.Emit(ToolFuzzingDisallowed, name.str()); + return false; +} + +} // namespace Carbon diff --git a/toolchain/driver/driver_subcommand.h b/toolchain/driver/driver_subcommand.h index 9c90f9594157c..e9d6ff2df3a8f 100644 --- a/toolchain/driver/driver_subcommand.h +++ b/toolchain/driver/driver_subcommand.h @@ -45,6 +45,15 @@ class DriverSubcommand { // Runs the command. virtual auto Run(DriverEnv& driver_env) -> DriverResult = 0; + protected: + // Diagnoses and returns false if currently fuzzing. + // + // This should be used in subcommands to check and diagnose rather than + // entering them during fuzzing when they use external libraries that we can't + // keep fuzz-clean. + auto DisableFuzzingExternalLibraries(DriverEnv& driver_env, + llvm::StringRef name) -> bool; + private: // Subcommand information. CommandLine::CommandInfo info_; diff --git a/toolchain/driver/lld_subcommand.cpp b/toolchain/driver/lld_subcommand.cpp index 3c082fbdf31bc..f397ec4a6a2da 100644 --- a/toolchain/driver/lld_subcommand.cpp +++ b/toolchain/driver/lld_subcommand.cpp @@ -93,11 +93,7 @@ auto LldSubcommand::Run(DriverEnv& driver_env) -> DriverResult { // Don't run LLD when fuzzing, as we're not currently in a good position to // debug and fix fuzzer-found bugs within LLD. - if (driver_env.fuzzing) { - CARBON_DIAGNOSTIC( - LLDFuzzingDisallowed, Error, - "preventing fuzzing of `lld` subcommand due to external library"); - driver_env.emitter.Emit(LLDFuzzingDisallowed); + if (!DisableFuzzingExternalLibraries(driver_env, "lld")) { return {.success = false}; } diff --git a/toolchain/driver/testdata/fail_clang_fuzzing.cpp b/toolchain/driver/testdata/fail_clang_fuzzing.cpp index 8843dd462778e..9f99079c3e513 100644 --- a/toolchain/driver/testdata/fail_clang_fuzzing.cpp +++ b/toolchain/driver/testdata/fail_clang_fuzzing.cpp @@ -11,5 +11,5 @@ // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_clang_fuzzing.cpp // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/driver/testdata/fail_clang_fuzzing.cpp -// CHECK:STDERR: error: preventing fuzzing of `clang` subcommand due to library crashes [ClangFuzzingDisallowed] +// CHECK:STDERR: error: preventing fuzzing of `clang` subcommand due to external library [ToolFuzzingDisallowed] // CHECK:STDERR: diff --git a/toolchain/driver/testdata/fail_lld_fuzzing.carbon b/toolchain/driver/testdata/fail_lld_fuzzing.carbon index b1e144c75344e..4d923479d0ef0 100644 --- a/toolchain/driver/testdata/fail_lld_fuzzing.carbon +++ b/toolchain/driver/testdata/fail_lld_fuzzing.carbon @@ -11,5 +11,5 @@ // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_lld_fuzzing.carbon // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/driver/testdata/fail_lld_fuzzing.carbon -// CHECK:STDERR: error: preventing fuzzing of `lld` subcommand due to external library [LLDFuzzingDisallowed] +// CHECK:STDERR: error: preventing fuzzing of `lld` subcommand due to external library [ToolFuzzingDisallowed] // CHECK:STDERR: From c44e688e5d400e62082ec1bc693fe806eb7ce02f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 3 Mar 2025 09:37:10 -0800 Subject: [PATCH 53/56] Add parsing for 'fn destroy' (#5045) Syntax is proposed in #5017, but has already been discussed with leads. Semantics is left as a TODO. --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/handle_name.cpp | 19 +- toolchain/check/name_component.cpp | 3 +- toolchain/check/node_stack.h | 9 +- .../testdata/class/no_prelude/destroy.carbon | 179 ++++++++++++++++++ toolchain/lex/token_kind.def | 2 +- toolchain/parse/BUILD | 1 + .../parse/handle_decl_name_and_params.cpp | 84 ++++---- toolchain/parse/node_category.h | 2 +- toolchain/parse/node_ids.h | 3 +- toolchain/parse/node_kind.def | 6 +- toolchain/parse/testdata/alias/basic.carbon | 2 +- toolchain/parse/testdata/class/local.carbon | 2 +- .../testdata/function/declaration.carbon | 62 ++++++ .../impl/fail_out_of_line_member.carbon | 2 +- .../namespace/fail_incomplete_name.carbon | 2 +- .../parse/testdata/namespace/nested.carbon | 6 +- .../parse/testdata/packages/export.carbon | 4 +- toolchain/parse/typed_nodes.h | 32 +++- toolchain/parse/typed_nodes_test.cpp | 6 +- 19 files changed, 362 insertions(+), 64 deletions(-) create mode 100644 toolchain/check/testdata/class/no_prelude/destroy.carbon diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index 39760d7878f2b..398d8f7f3aca4 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -152,6 +152,16 @@ auto HandleParseNode(Context& context, Parse::IdentifierNameExprId node_id) return true; } +auto HandleParseNode(Context& context, + Parse::KeywordNameNotBeforeParamsId node_id) -> bool { + return context.TODO(node_id, "KeywordNameNotBeforeParamsId"); +} + +auto HandleParseNode(Context& context, Parse::KeywordNameBeforeParamsId node_id) + -> bool { + return context.TODO(node_id, "KeywordNameBeforeParamsId"); +} + auto HandleParseNode(Context& context, Parse::BaseNameId node_id) -> bool { context.node_stack().Push(node_id, SemIR::NameId::Base); return true; @@ -188,7 +198,8 @@ auto HandleParseNode(Context& context, } auto HandleParseNode(Context& context, - Parse::NameQualifierWithoutParamsId /*node_id*/) -> bool { + Parse::IdentifierNameQualifierWithoutParamsId /*node_id*/) + -> bool { context.decl_name_stack().ApplyNameQualifier(PopNameComponent(context)); return true; } @@ -229,6 +240,12 @@ auto HandleParseNode(Context& context, Parse::DesignatorExprId node_id) return true; } +auto HandleParseNode(Context& context, + Parse::KeywordNameQualifierWithoutParamsId node_id) + -> bool { + return context.TODO(node_id, "KeywordNameQualifierWithoutParamsId"); +} + auto HandleParseNode(Context& context, Parse::PackageExprId node_id) -> bool { AddInstAndPush( context, node_id, diff --git a/toolchain/check/name_component.cpp b/toolchain/check/name_component.cpp index 83679bc18c90b..078abb7983099 100644 --- a/toolchain/check/name_component.cpp +++ b/toolchain/check/name_component.cpp @@ -57,8 +57,7 @@ auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id) } auto [name_loc_id, name_id] = - context.node_stack() - .PopWithNodeId(); + context.node_stack().PopWithNodeId(); return { .name_loc_id = name_loc_id, diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 0dea644ee397e..025b5cc4623d3 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -377,9 +377,9 @@ class NodeStack { Id::KindFor()); set_id_if_category_is(Parse::NodeCategory::Expr, Id::KindFor()); - set_id_if_category_is(Parse::NodeCategory::MemberName | - Parse::NodeCategory::NonExprIdentifierName, - Id::KindFor()); + set_id_if_category_is( + Parse::NodeCategory::MemberName | Parse::NodeCategory::NonExprName, + Id::KindFor()); set_id_if_category_is(Parse::NodeCategory::ImplAs, Id::KindFor()); set_id_if_category_is(Parse::NodeCategory::Decl | @@ -469,11 +469,13 @@ class NodeStack { case Parse::NodeKind::ForHeader: case Parse::NodeKind::ForHeaderStart: case Parse::NodeKind::ForIn: + case Parse::NodeKind::IdentifierNameQualifierWithoutParams: case Parse::NodeKind::IdentifierPackageName: case Parse::NodeKind::IfConditionStart: case Parse::NodeKind::ImportIntroducer: case Parse::NodeKind::IndexExprStart: case Parse::NodeKind::InvalidParseStart: + case Parse::NodeKind::KeywordNameQualifierWithoutParams: case Parse::NodeKind::LibraryIntroducer: case Parse::NodeKind::LibrarySpecifier: case Parse::NodeKind::MatchCase: @@ -494,7 +496,6 @@ class NodeStack { case Parse::NodeKind::NamedConstraintDefinitionStart: case Parse::NodeKind::NamedConstraintIntroducer: case Parse::NodeKind::NameQualifierWithParams: - case Parse::NodeKind::NameQualifierWithoutParams: case Parse::NodeKind::NamespaceStart: case Parse::NodeKind::PackageIntroducer: case Parse::NodeKind::ParenExprStart: diff --git a/toolchain/check/testdata/class/no_prelude/destroy.carbon b/toolchain/check/testdata/class/no_prelude/destroy.carbon new file mode 100644 index 0000000000000..58ffe95a4f3e6 --- /dev/null +++ b/toolchain/check/testdata/class/no_prelude/destroy.carbon @@ -0,0 +1,179 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/destroy.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/destroy.carbon + +// --- fail_todo_basic.carbon + +library "[[@TEST_NAME]]"; + +class C { + // CHECK:STDERR: fail_todo_basic.carbon:[[@LINE+4]]:6: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] + // CHECK:STDERR: fn destroy[self: Self](); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn destroy[self: Self](); +} + +// --- fail_todo_addr.carbon + +library "[[@TEST_NAME]]"; + +class C { + // CHECK:STDERR: fail_todo_addr.carbon:[[@LINE+4]]:6: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] + // CHECK:STDERR: fn destroy[addr self: Self*](); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn destroy[addr self: Self*](); +} + +// --- fail_todo_class_function.carbon + +library "[[@TEST_NAME]]"; + +class C { + // CHECK:STDERR: fail_todo_class_function.carbon:[[@LINE+4]]:6: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] + // CHECK:STDERR: fn destroy(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn destroy(); +} + +// --- fail_todo_destroy_in_namespace.carbon + +library "[[@TEST_NAME]]"; + +namespace NS; + +// CHECK:STDERR: fail_todo_destroy_in_namespace.carbon:[[@LINE+4]]:7: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] +// CHECK:STDERR: fn NS.destroy(); +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: +fn NS.destroy(); + +// --- fail_todo_missing_params.carbon + +library "[[@TEST_NAME]]"; + + +class C { + // CHECK:STDERR: fail_todo_missing_params.carbon:[[@LINE+4]]:6: error: semantics TODO: `KeywordNameNotBeforeParamsId` [SemanticsTodo] + // CHECK:STDERR: fn destroy; + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn destroy; +} + +fn C.destroy {} + +// --- fail_todo_wrong_scope.carbon + +library "[[@TEST_NAME]]"; + + +// CHECK:STDERR: fail_todo_wrong_scope.carbon:[[@LINE+4]]:4: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] +// CHECK:STDERR: fn destroy(); +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: +fn destroy(); + +// --- fail_invalid_qualifier.carbon + +class C { + // CHECK:STDERR: fail_invalid_qualifier.carbon:[[@LINE+4]]:6: error: semantics TODO: `KeywordNameBeforeParamsId` [SemanticsTodo] + // CHECK:STDERR: fn destroy(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + fn destroy(); +} + +fn C.destroy.destroy() {} + +// CHECK:STDOUT: --- fail_todo_basic.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: complete_type_witness = invalid +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: complete_type_witness = invalid +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_class_function.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: complete_type_witness = invalid +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_destroy_in_namespace.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_missing_params.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: complete_type_witness = invalid +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_wrong_scope.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_invalid_qualifier.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file {} +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: complete_type_witness = invalid +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/lex/token_kind.def b/toolchain/lex/token_kind.def index 4699203a7562b..b8752e7e81d6d 100644 --- a/toolchain/lex/token_kind.def +++ b/toolchain/lex/token_kind.def @@ -179,7 +179,7 @@ CARBON_KEYWORD_TOKEN(Const, "const") CARBON_KEYWORD_TOKEN(Continue, "continue") CARBON_KEYWORD_TOKEN(Core, "Core") CARBON_KEYWORD_TOKEN(Default, "default") -CARBON_KEYWORD_TOKEN(Destructor, "destructor") +CARBON_KEYWORD_TOKEN(Destroy, "destroy") CARBON_KEYWORD_TOKEN(Else, "else") CARBON_KEYWORD_TOKEN(Extend, "extend") CARBON_KEYWORD_TOKEN(Extern, "extern") diff --git a/toolchain/parse/BUILD b/toolchain/parse/BUILD index 6f6e1cd3a1006..3b10e24fc7c22 100644 --- a/toolchain/parse/BUILD +++ b/toolchain/parse/BUILD @@ -110,6 +110,7 @@ cc_library( "//toolchain/base:shared_value_stores", "//toolchain/diagnostics:diagnostic_emitter", "//toolchain/diagnostics:format_providers", + "//toolchain/lex:token_index", "//toolchain/lex:token_kind", "//toolchain/lex:tokenized_buffer", ], diff --git a/toolchain/parse/handle_decl_name_and_params.cpp b/toolchain/parse/handle_decl_name_and_params.cpp index 9f8ec8010db09..4fde242e4f01f 100644 --- a/toolchain/parse/handle_decl_name_and_params.cpp +++ b/toolchain/parse/handle_decl_name_and_params.cpp @@ -2,67 +2,87 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include "toolchain/lex/token_index.h" #include "toolchain/parse/context.h" #include "toolchain/parse/handle.h" namespace Carbon::Parse { -auto HandleDeclNameAndParams(Context& context) -> void { - auto state = context.PopState(); - - auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier); - if (!identifier) { - Lex::TokenIndex token = *context.position(); - if (context.tokens().GetKind(token) == Lex::TokenKind::FileEnd) { - // The end of file is an unhelpful diagnostic location. Instead, use the - // introducer token. - token = state.token; - } - if (state.token == *context.position()) { - CARBON_DIAGNOSTIC(ExpectedDeclNameAfterPeriod, Error, - "`.` should be followed by a name"); - context.emitter().Emit(token, ExpectedDeclNameAfterPeriod); - } else { - CARBON_DIAGNOSTIC(ExpectedDeclName, Error, - "`{0}` introducer should be followed by a name", - Lex::TokenKind); - context.emitter().Emit(token, ExpectedDeclName, - context.tokens().GetKind(state.token)); - } - context.ReturnErrorOnState(); - context.AddInvalidParse(*context.position()); - return; - } - +// Adds a leaf node for the name, and updates the state stack for parameter +// handling. +static auto HandleName(Context& context, Context::StateStackEntry state, + Lex::TokenIndex name_token, + NodeKind not_before_params_kind, + NodeKind not_before_params_qualifier_kind, + NodeKind before_params_kind) -> void { switch (context.PositionKind()) { case Lex::TokenKind::Period: - context.AddLeafNode(NodeKind::IdentifierNameNotBeforeParams, *identifier); - context.AddNode(NodeKind::NameQualifierWithoutParams, + context.AddLeafNode(not_before_params_kind, name_token); + context.AddNode(not_before_params_qualifier_kind, context.ConsumeChecked(Lex::TokenKind::Period), state.has_error); context.PushState(State::DeclNameAndParams); break; case Lex::TokenKind::OpenSquareBracket: - context.AddLeafNode(NodeKind::IdentifierNameBeforeParams, *identifier); + context.AddLeafNode(before_params_kind, name_token); state.state = State::DeclNameAndParamsAfterImplicit; context.PushState(state); context.PushState(State::PatternListAsImplicit); break; case Lex::TokenKind::OpenParen: - context.AddLeafNode(NodeKind::IdentifierNameBeforeParams, *identifier); + context.AddLeafNode(before_params_kind, name_token); state.state = State::DeclNameAndParamsAfterParams; context.PushState(state); context.PushState(State::PatternListAsExplicit); break; default: - context.AddLeafNode(NodeKind::IdentifierNameNotBeforeParams, *identifier); + context.AddLeafNode(not_before_params_kind, name_token); break; } } +auto HandleDeclNameAndParams(Context& context) -> void { + auto state = context.PopState(); + + if (auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier)) { + HandleName(context, state, *identifier, + NodeKind::IdentifierNameNotBeforeParams, + NodeKind::IdentifierNameQualifierWithoutParams, + NodeKind::IdentifierNameBeforeParams); + return; + } + + if (auto keyword = context.ConsumeIf(Lex::TokenKind::Destroy)) { + HandleName(context, state, *keyword, NodeKind::KeywordNameNotBeforeParams, + NodeKind::KeywordNameQualifierWithoutParams, + NodeKind::KeywordNameBeforeParams); + return; + } + + Lex::TokenIndex token = *context.position(); + if (context.tokens().GetKind(token) == Lex::TokenKind::FileEnd) { + // The end of file is an unhelpful diagnostic location. Instead, use the + // introducer token. + token = state.token; + } + if (state.token == *context.position()) { + CARBON_DIAGNOSTIC(ExpectedDeclNameAfterPeriod, Error, + "`.` should be followed by a name"); + context.emitter().Emit(token, ExpectedDeclNameAfterPeriod); + } else { + CARBON_DIAGNOSTIC(ExpectedDeclName, Error, + "`{0}` introducer should be followed by a name", + Lex::TokenKind); + context.emitter().Emit(token, ExpectedDeclName, + context.tokens().GetKind(state.token)); + } + context.ReturnErrorOnState(); + context.AddInvalidParse(*context.position()); +} + auto HandleDeclNameAndParamsAfterImplicit(Context& context) -> void { auto state = context.PopState(); diff --git a/toolchain/parse/node_category.h b/toolchain/parse/node_category.h index fb67a4691cefd..cc6d3d7d6f3dd 100644 --- a/toolchain/parse/node_category.h +++ b/toolchain/parse/node_category.h @@ -25,7 +25,7 @@ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); X(MemberExpr) \ X(MemberName) \ X(Modifier) \ - X(NonExprIdentifierName) \ + X(NonExprName) \ X(PackageName) \ X(Pattern) \ X(Requirement) \ diff --git a/toolchain/parse/node_ids.h b/toolchain/parse/node_ids.h index 54977bc4849f8..b66349ae3ef5f 100644 --- a/toolchain/parse/node_ids.h +++ b/toolchain/parse/node_ids.h @@ -79,8 +79,7 @@ using AnyPatternId = NodeIdInCategory; using AnyStatementId = NodeIdInCategory; using AnyRequirementId = NodeIdInCategory; -using AnyNonExprIdentifierNameId = - NodeIdInCategory; +using AnyNonExprNameId = NodeIdInCategory; using AnyPackageNameId = NodeIdInCategory; // NodeId with kind that matches one of the `T::Kind`s. diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index bf54e99969a20..00e5d7cf9e1dc 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -98,6 +98,9 @@ CARBON_PARSE_NODE_KIND(EmptyDecl) CARBON_PARSE_NODE_KIND(IdentifierNameNotBeforeParams) CARBON_PARSE_NODE_KIND(IdentifierNameBeforeParams) +CARBON_PARSE_NODE_KIND(KeywordNameNotBeforeParams) +CARBON_PARSE_NODE_KIND(KeywordNameBeforeParams) + CARBON_PARSE_NODE_KIND(IdentifierNameExpr) CARBON_PARSE_NODE_KIND(SelfValueName) @@ -124,7 +127,8 @@ CARBON_PARSE_NODE_KIND(LibraryDecl) CARBON_PARSE_NODE_KIND(LibrarySpecifier) CARBON_PARSE_NODE_KIND(NameQualifierWithParams) -CARBON_PARSE_NODE_KIND(NameQualifierWithoutParams) +CARBON_PARSE_NODE_KIND(IdentifierNameQualifierWithoutParams) +CARBON_PARSE_NODE_KIND(KeywordNameQualifierWithoutParams) CARBON_PARSE_NODE_KIND(ExportIntroducer) CARBON_PARSE_NODE_KIND(ExportDecl) diff --git a/toolchain/parse/testdata/alias/basic.carbon b/toolchain/parse/testdata/alias/basic.carbon index 9ad0d6812cee6..b4b51ca49cdf9 100644 --- a/toolchain/parse/testdata/alias/basic.carbon +++ b/toolchain/parse/testdata/alias/basic.carbon @@ -44,7 +44,7 @@ fn F() { // CHECK:STDOUT: {kind: 'Alias', text: ';', subtree_size: 7}, // CHECK:STDOUT: {kind: 'AliasIntroducer', text: 'alias'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'NS'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'ns'}, // CHECK:STDOUT: {kind: 'AliasInitializer', text: '='}, // CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'foo'}, diff --git a/toolchain/parse/testdata/class/local.carbon b/toolchain/parse/testdata/class/local.carbon index 95d45a9fcbc4e..8235a63b5953e 100644 --- a/toolchain/parse/testdata/class/local.carbon +++ b/toolchain/parse/testdata/class/local.carbon @@ -41,7 +41,7 @@ fn F() { // CHECK:STDOUT: {kind: 'ClassDefinition', text: '}', subtree_size: 15}, // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'C'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'}, // CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, diff --git a/toolchain/parse/testdata/function/declaration.carbon b/toolchain/parse/testdata/function/declaration.carbon index 6eb8ce089e7be..3a8306458f98e 100644 --- a/toolchain/parse/testdata/function/declaration.carbon +++ b/toolchain/parse/testdata/function/declaration.carbon @@ -36,6 +36,22 @@ fn foo(a: i32, b: i32); fn foo() -> u32; +// --- keyword.carbon + +fn destroy() {} + +// --- keyword_no_params.carbon + +fn destroy {} + +// --- keyword_in_qualified.carbon + +fn MyClass.destroy() {} + +// --- keyword_decl.carbon + +fn destroy.destroy() {} + // --- impl_fn.carbon impl fn F(); @@ -256,6 +272,52 @@ fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z); // CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: keyword.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'KeywordNameBeforeParams', text: 'destroy'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: keyword_no_params.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'KeywordNameNotBeforeParams', text: 'destroy'}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: keyword_in_qualified.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'MyClass'}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'KeywordNameBeforeParams', text: 'destroy'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: keyword_decl.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'KeywordNameNotBeforeParams', text: 'destroy'}, +// CHECK:STDOUT: {kind: 'KeywordNameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'KeywordNameBeforeParams', text: 'destroy'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] // CHECK:STDOUT: - filename: impl_fn.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, diff --git a/toolchain/parse/testdata/generics/impl/fail_out_of_line_member.carbon b/toolchain/parse/testdata/generics/impl/fail_out_of_line_member.carbon index 4855c95564bb7..64b7c5a29e23c 100644 --- a/toolchain/parse/testdata/generics/impl/fail_out_of_line_member.carbon +++ b/toolchain/parse/testdata/generics/impl/fail_out_of_line_member.carbon @@ -79,7 +79,7 @@ fn C.(Self as Interface).F() {} // CHECK:STDOUT: {kind: 'ClassDefinition', text: '}', subtree_size: 15}, // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'C'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, // CHECK:STDOUT: {kind: 'FunctionDecl', text: '}', has_error: yes, subtree_size: 5}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parse/testdata/namespace/fail_incomplete_name.carbon b/toolchain/parse/testdata/namespace/fail_incomplete_name.carbon index bb1be72e9a3b9..c448468e7bcab 100644 --- a/toolchain/parse/testdata/namespace/fail_incomplete_name.carbon +++ b/toolchain/parse/testdata/namespace/fail_incomplete_name.carbon @@ -19,7 +19,7 @@ namespace Foo.; // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'NamespaceStart', text: 'namespace'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, // CHECK:STDOUT: {kind: 'Namespace', text: ';', has_error: yes, subtree_size: 5}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parse/testdata/namespace/nested.carbon b/toolchain/parse/testdata/namespace/nested.carbon index b370fbcb294eb..5ecd562b06687 100644 --- a/toolchain/parse/testdata/namespace/nested.carbon +++ b/toolchain/parse/testdata/namespace/nested.carbon @@ -23,14 +23,14 @@ fn Foo.Bar.Baz() { // CHECK:STDOUT: {kind: 'Namespace', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'NamespaceStart', text: 'namespace'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Bar'}, // CHECK:STDOUT: {kind: 'Namespace', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Bar'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'Baz'}, // CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, // CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, diff --git a/toolchain/parse/testdata/packages/export.carbon b/toolchain/parse/testdata/packages/export.carbon index c3f712a31117b..4f9b17b5ab44b 100644 --- a/toolchain/parse/testdata/packages/export.carbon +++ b/toolchain/parse/testdata/packages/export.carbon @@ -162,7 +162,7 @@ export Foo; // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Bar'}, // CHECK:STDOUT: {kind: 'ExportDecl', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, @@ -230,7 +230,7 @@ export Foo; // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, -// CHECK:STDOUT: {kind: 'NameQualifierWithoutParams', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameQualifierWithoutParams', text: '.', subtree_size: 2}, // CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, // CHECK:STDOUT: {kind: 'ExportDecl', text: ';', has_error: yes, subtree_size: 5}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parse/typed_nodes.h b/toolchain/parse/typed_nodes.h index 915ffc395c736..9ceddcfd327ef 100644 --- a/toolchain/parse/typed_nodes.h +++ b/toolchain/parse/typed_nodes.h @@ -131,13 +131,19 @@ using EmptyDecl = // to be followed by parameters. using IdentifierNameBeforeParams = LeafNode; + NodeCategory::MemberName | NodeCategory::NonExprName>; +using KeywordNameBeforeParams = + LeafNode; // A name in a non-expression context, such as a declaration, that is known // to not be followed by parameters. using IdentifierNameNotBeforeParams = LeafNode; + NodeCategory::MemberName | NodeCategory::NonExprName>; +using KeywordNameNotBeforeParams = + LeafNode; // A name in an expression context. using IdentifierNameExpr = @@ -174,21 +180,31 @@ struct NameQualifierWithParams { }; // A name qualifier without parameters, such as `A.`. -struct NameQualifierWithoutParams { - static constexpr auto Kind = NodeKind::NameQualifierWithoutParams.Define( - {.bracketed_by = IdentifierNameNotBeforeParams::Kind}); +struct IdentifierNameQualifierWithoutParams { + static constexpr auto Kind = + NodeKind::IdentifierNameQualifierWithoutParams.Define( + {.bracketed_by = IdentifierNameNotBeforeParams::Kind}); IdentifierNameNotBeforeParamsId name; Lex::PeriodTokenIndex token; }; +struct KeywordNameQualifierWithoutParams { + static constexpr auto Kind = + NodeKind::KeywordNameQualifierWithoutParams.Define( + {.bracketed_by = KeywordNameNotBeforeParams::Kind}); + + KeywordNameNotBeforeParamsId name; + Lex::PeriodTokenIndex token; +}; // A complete name in a declaration: `A.C(T:! type).F(n: i32)`. // Note that this includes the parameters of the entity itself. struct DeclName { llvm::SmallVector< - NodeIdOneOf> + NodeIdOneOf> qualifiers; - AnyNonExprIdentifierNameId name; + AnyNonExprNameId name; std::optional implicit_params; std::optional params; }; @@ -1157,7 +1173,7 @@ struct ChoiceDefinition { ChoiceDefinitionStartId signature; struct Alternative { - AnyNonExprIdentifierNameId name; + AnyNonExprNameId name; std::optional parameters; }; CommaSeparatedList alternatives; diff --git a/toolchain/parse/typed_nodes_test.cpp b/toolchain/parse/typed_nodes_test.cpp index daf7570401cb6..e9f3445d2103c 100644 --- a/toolchain/parse/typed_nodes_test.cpp +++ b/toolchain/parse/typed_nodes_test.cpp @@ -290,10 +290,10 @@ Optional [^:]*: found Optional [^:]*: begin NodeIdForKind error: wrong kind IdentifierNameBeforeParams, expected ImplicitParamList Optional [^:]*: missing -NodeIdInCategory NonExprIdentifierName: kind IdentifierNameBeforeParams consumed +NodeIdInCategory NonExprName: kind IdentifierNameBeforeParams consumed Vector: begin -NodeIdOneOf NameQualifierWithParams or NameQualifierWithoutParams: NameQualifierWithoutParams consumed -NodeIdOneOf error: wrong kind AbstractModifier, expected NameQualifierWithParams or NameQualifierWithoutParams +NodeIdOneOf NameQualifierWithParams or IdentifierNameQualifierWithoutParams or KeywordNameQualifierWithoutParams: IdentifierNameQualifierWithoutParams consumed +NodeIdOneOf error: wrong kind AbstractModifier, expected NameQualifierWithParams or IdentifierNameQualifierWithoutParams or KeywordNameQualifierWithoutParams Vector: end Aggregate [^:]*: success Vector: begin From 28de6c9b7def90602200b903bb86b2f9a7cbab5d Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Mon, 3 Mar 2025 20:25:55 +0100 Subject: [PATCH 54/56] Add `--no-dump-sem-ir` to all `name_poisoning` tests (#5053) Follow up of previous PR discussions ([#4950](https://github.com/carbon-language/carbon-lang/pull/4950/files/89c2e66dc3190159e2f8d94c31bff31bdd0d81a1..a1650a7d73c8f4013b4b77e4d7d60933f1f6d676#r1972257889), [#4987](https://github.com/carbon-language/carbon-lang/pull/4987/files#r1964105413)). Part of #4622. --- .../class/no_prelude/name_poisoning.carbon | 598 +--------------- .../no_prelude/name_poisoning.carbon | 402 +---------- .../impl/no_prelude/name_poisoning.carbon | 197 +----- .../no_prelude/name_poisoning.carbon | 657 +----------------- .../no_prelude/name_poisoning.carbon | 263 +------ .../no_prelude/core_name_poisoning.carbon | 38 +- 6 files changed, 12 insertions(+), 2143 deletions(-) diff --git a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon index 2a75c4fd5421e..67e289131be84 100644 --- a/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/class/no_prelude/name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/no_prelude/name_poisoning.carbon @@ -263,599 +265,3 @@ class C { // CHECK:STDERR: fn B(); } - -// CHECK:STDOUT: --- no_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] -// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .TestCall = %TestCall.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc8 -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc8: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] -// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { -// CHECK:STDOUT: %x.patt: %C.9f4 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.9f4 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.9f4 = value_param runtime_param0 -// CHECK:STDOUT: %.loc11: type = splice_block %C.ref [concrete = constants.%C.9f4] { -// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc8 [concrete = constants.%C.9f4] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: %C.9f4 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.9f4 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %C.9f4); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @TestCall(%x.param_patt: %C.9f4) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %x.ref: %C.9f4 = name_ref x, %x -// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%x.ref) -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %C = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %x: %C = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %C); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc18: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %C.f79); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %return.patt: %C = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %C = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %return.param: ref %C = out_param runtime_param0 -// CHECK:STDOUT: %return: ref %C = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %return.patt: = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] -// CHECK:STDOUT: %return.param: ref = out_param runtime_param0 -// CHECK:STDOUT: %return: ref = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1() -> %C; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F2() -> ; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc4: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt: %C.f79 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C.f79 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C.f79 = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl.loc4 [concrete = constants.%C.f79] -// CHECK:STDOUT: %x: %C.f79 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc18: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(%x.param_patt: %C.f79); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F2(%x.param_patt: ); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_alias.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] -// CHECK:STDOUT: %C: type = bind_alias C, %C.decl [concrete = constants.%C] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C1.26b: type = class_type @C1.1 [concrete] -// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] -// CHECK:STDOUT: %C3: type = class_type @C3 [concrete] -// CHECK:STDOUT: %C4: type = class_type @C4 [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C1.d8b: type = class_type @C1.2 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C1.a31: type = class_type @C1.3 [concrete] -// CHECK:STDOUT: %C1.f31: type = class_type @C1.4 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C1 = %C1.decl -// CHECK:STDOUT: .C2 = %C2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.1 [concrete = constants.%C1.26b] {} {} -// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2 { -// CHECK:STDOUT: %C3.decl: type = class_decl @C3 [concrete = constants.%C3] {} {} -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.4 [concrete = constants.%C1.f31] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2 -// CHECK:STDOUT: .C3 = %C3.decl -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C3 { -// CHECK:STDOUT: %C4.decl: type = class_decl @C4 [concrete = constants.%C4] {} {} -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.3 [concrete = constants.%C1.a31] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C3 -// CHECK:STDOUT: .C4 = %C4.decl -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C4 { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %C1.26b = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C1.26b = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C1.26b = value_param runtime_param0 -// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1.26b] -// CHECK:STDOUT: %x: %C1.26b = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.2 [concrete = constants.%C1.d8b] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C4 -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.2; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.3; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.4; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %C1.26b); -// CHECK:STDOUT: -// CHECK:STDOUT: --- ignored_poison_in_import.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .C = file.%C.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = imports.%Main.C -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C; -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.C = import_ref Main//poison, C, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .C = file.%C.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = imports.%Main.C -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import.loc2_6.1 = import -// CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C.f79: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %C.9f4: type = class_type @C.2 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .C = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %C.ref: = name_ref C, [concrete = ] -// CHECK:STDOUT: %x: = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl.loc23: type = class_decl @C.1 [concrete = constants.%C.f79] {} {} -// CHECK:STDOUT: %C.decl.loc28: type = class_decl @C.2 [concrete = constants.%C.9f4] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: ); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C1.138: type = class_type @C1.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] -// CHECK:STDOUT: %C2.elem: type = unbound_element_type %C2, %C1.138 [concrete] -// CHECK:STDOUT: %C1.46c: type = class_type @C1.2 [concrete] -// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %C1.138} [concrete] -// CHECK:STDOUT: %complete_type.fb7: = complete_type_witness %struct_type.v [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C1.138 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2 { -// CHECK:STDOUT: %.loc11_10: %C2.elem = field_decl v, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc11_5: %C2.elem = var_pattern %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %C2.elem = var -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.2 [concrete = constants.%C1.46c] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type.fb7] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2 -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: .v = %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1.2; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %C1.decl: type = class_decl @C1.1 [concrete = constants.%C1.138] {} {} -// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_data_member_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C1: type = class_type @C1 [concrete] -// CHECK:STDOUT: %C2.311: type = class_type @C2.1 [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %C2.0a0: type = class_type @C2.2 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C2.elem: type = unbound_element_type %C2.311, %C2.0a0 [concrete] -// CHECK:STDOUT: %struct_type.C1: type = struct_type {.C1: %C2.0a0} [concrete] -// CHECK:STDOUT: %complete_type.979: = complete_type_witness %struct_type.C1 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C1 = %C1.decl -// CHECK:STDOUT: .C2 = %C2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C1.decl: type = class_decl @C1 [concrete = constants.%C1] {} {} -// CHECK:STDOUT: %C2.decl: type = class_decl @C2.1 [concrete = constants.%C2.311] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2.1 { -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: %C1 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C1 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C1 = value_param runtime_param0 -// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1] -// CHECK:STDOUT: %x: %C1 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %C2.decl: type = class_decl @C2.2 [concrete = constants.%C2.0a0] {} {} -// CHECK:STDOUT: %.loc19_9: %C2.elem = field_decl C1, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc19_3: %C2.elem = var_pattern %.loc19_9 -// CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %C2.elem = var -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.C1 [concrete = constants.%complete_type.979] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2.311 -// CHECK:STDOUT: .C1 = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: .C2 = %C2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2.0a0 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: %C1); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_extend_poison_class_members.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %B.fa3: type = class_type @B.2 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B.fa3 [concrete] -// CHECK:STDOUT: %B.type: type = fn_type @B.1 [concrete] -// CHECK:STDOUT: %B.489: %B.type = struct_value () [concrete] -// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B.fa3} [concrete] -// CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .B = %B.decl -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %B.decl: type = class_decl @B.2 [concrete = constants.%B.fa3] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @B.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%B.fa3 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.fa3] -// CHECK:STDOUT: %.loc10: %C.elem = base_decl %B.ref, element0 [concrete] -// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B.1 [concrete = constants.%B.489] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .B = -// CHECK:STDOUT: .base = %.loc10 -// CHECK:STDOUT: extend %B.ref -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @B.1(); -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon index efd997ce12cf6..e20fdadda4258 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/declaration/no_prelude/name_poisoning.carbon @@ -222,403 +224,3 @@ fn F1() { fn F2(); } } - -// CHECK:STDOUT: --- no_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C1: type = class_type @C1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C2: type = class_type @C2 [concrete] -// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] -// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] -// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] -// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C1 = %C1.decl -// CHECK:STDOUT: .C2 = %C2.decl -// CHECK:STDOUT: .F1 = %F1.decl.loc7 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .TestCall = %TestCall.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C1.decl: type = class_decl @C1 [concrete = constants.%C1] {} {} -// CHECK:STDOUT: %C2.decl: type = class_decl @C2 [concrete = constants.%C2] {} {} -// CHECK:STDOUT: %F1.decl.loc7: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] { -// CHECK:STDOUT: %x.patt: %C1 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C1 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C1 = value_param runtime_param0 -// CHECK:STDOUT: %C1.ref: type = name_ref C1, file.%C1.decl [concrete = constants.%C1] -// CHECK:STDOUT: %x: %C1 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .C2 = -// CHECK:STDOUT: .F1 = %F1.decl.loc11 -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl.loc11: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] { -// CHECK:STDOUT: %x.patt: %C2 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C2 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C2 = value_param runtime_param0 -// CHECK:STDOUT: %C2.ref: type = name_ref C2, file.%C2.decl [concrete = constants.%C2] -// CHECK:STDOUT: %x: %C2 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref: %F1.type.fe6 = name_ref F1, %F1.decl.loc11 [concrete = constants.%F1.cc1] -// CHECK:STDOUT: %F2: %F1.type.fe6 = bind_alias F2, %F1.decl.loc11 [concrete = constants.%F1.cc1] -// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { -// CHECK:STDOUT: %x.patt: %C2 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %C2 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %C2 = value_param runtime_param0 -// CHECK:STDOUT: %C2.ref: type = name_ref C2, file.%C2.decl [concrete = constants.%C2] -// CHECK:STDOUT: %x: %C2 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C1 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C2 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.1(%x.param_patt: %C1); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.2(%x.param_patt: %C2); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @TestCall(%x.param_patt: %C2) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F2.ref: %F1.type.fe6 = name_ref F2, file.%F2 [concrete = constants.%F1.cc1] -// CHECK:STDOUT: %x.ref: %C2 = name_ref x, %x -// CHECK:STDOUT: %F1.call: init %empty_tuple.type = call %F2.ref(%x.ref) -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref: %F1.type = name_ref F1, %F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: %F2: %F1.type = bind_alias F2, %F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] -// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] -// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F1.decl.loc18: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.2(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F3 = %F3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref.loc8: %F1.type = name_ref F1, %F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: %F2: %F1.type = bind_alias F2, %F1.decl [concrete = constants.%F1] -// CHECK:STDOUT: %N.ref: = name_ref N, %N [concrete = %N] -// CHECK:STDOUT: %F1.ref.loc14: = name_ref F1, [concrete = ] -// CHECK:STDOUT: %F3: = bind_alias F3, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] -// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] -// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F3 = %F3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref.loc11: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F1.decl.loc18: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} -// CHECK:STDOUT: %N.ref: = name_ref N, %N [concrete = %N] -// CHECK:STDOUT: %F1.ref.loc26: = name_ref F1, [concrete = ] -// CHECK:STDOUT: %F3: = bind_alias F3, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.2(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] -// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.1f8: type = fn_type @F1.2 [concrete] -// CHECK:STDOUT: %F1.19a: %F1.type.1f8 = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.73a: type = fn_type @F1.3 [concrete] -// CHECK:STDOUT: %F1.727: %F1.type.73a = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.fe3: type = fn_type @F1.4 [concrete] -// CHECK:STDOUT: %F1.6a8: %F1.type.fe3 = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl.loc4 -// CHECK:STDOUT: .N1 = %N1 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl.loc4: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} -// CHECK:STDOUT: %N1: = namespace [concrete] { -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N3: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref: %F1.type.75d = name_ref F1, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F2: %F1.type.75d = bind_alias F2, %F1.decl.loc4 [concrete = constants.%F1.afe] -// CHECK:STDOUT: %F1.decl.loc25: %F1.type.1f8 = fn_decl @F1.2 [concrete = constants.%F1.19a] {} {} -// CHECK:STDOUT: %F1.decl.loc33: %F1.type.73a = fn_decl @F1.3 [concrete = constants.%F1.727] {} {} -// CHECK:STDOUT: %F1.decl.loc38: %F1.type.fe3 = fn_decl @F1.4 [concrete = constants.%F1.6a8] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.2(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.3(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.4(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_alias.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F = -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.ref: %F.type = name_ref F, %F.decl [concrete = constants.%F] -// CHECK:STDOUT: %F: %F.type = bind_alias F, %F.decl [concrete = constants.%F] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- ignored_poison_in_import.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.F1 = import_ref Main//poison, F1, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F2 = %Main.F2 -// CHECK:STDOUT: .F1 = file.%F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = imports.%Main.F1 -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.F1 = import_ref Main//poison, F1, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F2 = %Main.F2 -// CHECK:STDOUT: .F1 = file.%F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = imports.%Main.F1 -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import.loc2_6.1 = import -// CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type.75d: type = fn_type @F1.1 [concrete] -// CHECK:STDOUT: %F1.afe: %F1.type.75d = struct_value () [concrete] -// CHECK:STDOUT: %F1.type.fe6: type = fn_type @F1.2 [concrete] -// CHECK:STDOUT: %F1.cc1: %F1.type.fe6 = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .F1 = -// CHECK:STDOUT: .F2 = %F2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.ref: = name_ref F1, [concrete = ] -// CHECK:STDOUT: %F2: = bind_alias F2, [concrete = ] -// CHECK:STDOUT: %F1.decl.loc23: %F1.type.75d = fn_decl @F1.1 [concrete = constants.%F1.afe] {} {} -// CHECK:STDOUT: %F1.decl.loc28: %F1.type.fe6 = fn_decl @F1.2 [concrete = constants.%F1.cc1] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1.2(); -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %F2.type.028: type = fn_type @F2.1 [concrete] -// CHECK:STDOUT: %F2.18a: %F2.type.028 = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %F2.type.c9e: type = fn_type @F2.2 [concrete] -// CHECK:STDOUT: %F2.c1c: %F2.type.c9e = struct_value () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %F2.ref: %F2.type.028 = name_ref F2, @F1.%F2.decl [concrete = constants.%F2.18a] -// CHECK:STDOUT: %F3: %F2.type.028 = bind_alias F3, @F1.%F2.decl [concrete = constants.%F2.18a] -// CHECK:STDOUT: %F2.decl: %F2.type.c9e = fn_decl @F2.2 [concrete = constants.%F2.c1c] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .F2 = -// CHECK:STDOUT: .F3 = %F3 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F1() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %F2.decl: %F2.type.028 = fn_decl @F2.1 [concrete = constants.%F2.18a] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F2.1(); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F2.2(); -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon index 32d1b3f61b854..94048b7c0e48f 100644 --- a/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/no_prelude/name_poisoning.carbon @@ -53,198 +55,3 @@ class B { fn B(); } } - -// CHECK:STDOUT: --- using_poisoned_name_in_impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %Self.ref as %I.ref { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = @C.%impl_witness -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: impl_decl @impl [concrete] {} { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete = constants.%impl_witness] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .I = -// CHECK:STDOUT: extend @impl.%I.ref -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { -// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F1(constants.%x) { -// CHECK:STDOUT: %x.loc8_9.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_impl_function_poisoned.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %A.type.edf: type = fn_type @A.1 [concrete] -// CHECK:STDOUT: %A.ab0: %A.type.edf = struct_value () [concrete] -// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [concrete] -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%A.decl [concrete] -// CHECK:STDOUT: %B.type.785: type = fn_type @B.1 [concrete] -// CHECK:STDOUT: %B.6d4: %B.type.785 = struct_value () [concrete] -// CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, @I.%B.decl [concrete] -// CHECK:STDOUT: %B.fa3: type = class_type @B.3 [concrete] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%A.decl, ) [concrete] -// CHECK:STDOUT: %A.type.9b9: type = fn_type @A.2 [concrete] -// CHECK:STDOUT: %A.71f: %A.type.9b9 = struct_value () [concrete] -// CHECK:STDOUT: %B.type.52d: type = fn_type @B.2 [concrete] -// CHECK:STDOUT: %B.30a: %B.type.52d = struct_value () [concrete] -// CHECK:STDOUT: %I.facet: %I.type = facet_value %B.fa3, %impl_witness [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .B = %B.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %B.decl: type = class_decl @B.3 [concrete = constants.%B.fa3] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %A.decl: %A.type.edf = fn_decl @A.1 [concrete = constants.%A.ab0] { -// CHECK:STDOUT: %x.patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = binding_pattern x -// CHECK:STDOUT: %x.param_patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = value_param runtime_param0 -// CHECK:STDOUT: %.loc5_11.1: type = splice_block %.loc5_11.2 [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_11.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_11.2: type = converted %Self.ref, %Self.as_type.loc5_11.2 [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type) = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %A.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: %B.decl: %B.type.785 = fn_decl @B.1 [concrete = constants.%B.6d4] {} {} -// CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, %B.decl [concrete = constants.%assoc1] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .A = %assoc0 -// CHECK:STDOUT: .B = %assoc1 -// CHECK:STDOUT: witness = (%A.decl, %B.decl) -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %Self.ref as %I.ref { -// CHECK:STDOUT: %A.decl: %A.type.9b9 = fn_decl @A.2 [concrete = constants.%A.71f] { -// CHECK:STDOUT: %x.patt: %B.fa3 = binding_pattern x -// CHECK:STDOUT: %x.param_patt: %B.fa3 = value_param_pattern %x.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %B.fa3 = value_param runtime_param0 -// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.fa3] -// CHECK:STDOUT: %x: %B.fa3 = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %B.decl: %B.type.52d = fn_decl @B.2 [concrete = constants.%B.30a] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .B = -// CHECK:STDOUT: .A = %A.decl -// CHECK:STDOUT: witness = @B.3.%impl_witness -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @B.3 { -// CHECK:STDOUT: impl_decl @impl [concrete] {} { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B.fa3 [concrete = constants.%B.fa3] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%A.decl, ) [concrete = constants.%impl_witness] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%B.fa3 -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .B = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @A.1(@I.%Self: %I.type) { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_11.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_11.1 (constants.%Self.as_type)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: @A.1.%Self.as_type.loc5_11.1 (%Self.as_type)); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @B.1(@I.%Self: %I.type) { -// CHECK:STDOUT: fn(); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @A.2(%x.param_patt: %B.fa3); -// CHECK:STDOUT: -// CHECK:STDOUT: fn @B.2(); -// CHECK:STDOUT: -// CHECK:STDOUT: specific @A.1(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc5_11.1 => constants.%Self.as_type -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @B.1(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @A.1(constants.%I.facet) { -// CHECK:STDOUT: %Self => constants.%I.facet -// CHECK:STDOUT: %Self.as_type.loc5_11.1 => constants.%B.fa3 -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon index 25242e04c8c12..bb426a33453be 100644 --- a/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/no_prelude/name_poisoning.carbon @@ -219,658 +221,3 @@ fn F() { interface I1; } } - -// CHECK:STDOUT: --- no_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %x: %I.type.4da = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %TestCall.type: type = fn_type @TestCall [concrete] -// CHECK:STDOUT: %TestCall: %TestCall.type = struct_value () [concrete] -// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%x) [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .TestCall = %TestCall.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc8 -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc8: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc9_8.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc9_8.1, runtime_param [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: %x.loc9_8.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc9_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %TestCall.decl: %TestCall.type = fn_decl @TestCall [concrete = constants.%TestCall] { -// CHECK:STDOUT: %x.patt.loc11_13.1: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.4da = value_param_pattern %x.patt.loc11_13.1, runtime_param [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.4da = value_param runtime_param -// CHECK:STDOUT: %.loc11: type = splice_block %I.ref [concrete = constants.%I.type.4da] { -// CHECK:STDOUT: %N.ref.loc11: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc8 [concrete = constants.%I.type.4da] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x.loc11_13.1: %I.type.4da = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2 { -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc9_8.1: %I.type.4da) { -// CHECK:STDOUT: %x.loc9_8.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc9_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc9_8.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc9_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @TestCall(%x.loc11_13.1: %I.type.4da) { -// CHECK:STDOUT: %x.loc11_13.2: %I.type.4da = bind_symbolic_name x, 0 [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_13.2: %I.type.4da = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_13.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %F.specific_fn.loc13_4.2: = specific_function constants.%F, @F(%x.loc11_13.2) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.4da) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %N.ref.loc13: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] -// CHECK:STDOUT: %x.ref: %I.type.4da = name_ref x, %x.loc11_13.1 [symbolic = %x.loc11_13.2 (constants.%x)] -// CHECK:STDOUT: %F.specific_fn.loc13_4.1: = specific_function %F.ref, @F(constants.%x) [symbolic = %F.specific_fn.loc13_4.2 (constants.%F.specific_fn)] -// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn.loc13_4.1() -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc9_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc9_8.2 => constants.%x -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @TestCall(constants.%x) { -// CHECK:STDOUT: %x.loc11_13.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_13.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(@TestCall.%x.loc11_13.2) {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc8_8.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_8.1, runtime_param [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %x.loc8_8.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc8_8.1: %I.type) { -// CHECK:STDOUT: %x.loc8_8.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc8_8.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc8_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc8_8.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc11_8.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_8.1, runtime_param [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %x.loc11_8.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_8.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc18: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2 { -// CHECK:STDOUT: %Self: %I.type.4da = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x.loc11_8.1: %I.type.733) { -// CHECK:STDOUT: %x.loc11_8.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_8.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_8.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%x) { -// CHECK:STDOUT: %x.loc11_8.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_8.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %x: %I.type = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt.3ad: %I.type = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt.loc8_9.1: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: %x.param_patt: %I.type = value_param_pattern %x.patt.loc8_9.1, runtime_param [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %x.loc8_9.1: %I.type = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt.loc14_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc14_9.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F1(%x.loc8_9.1: %I.type) { -// CHECK:STDOUT: %x.loc8_9.2: %I.type = bind_symbolic_name x, 0 [symbolic = %x.loc8_9.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc8_9.2: %I.type = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc8_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F2(%x: ) { -// CHECK:STDOUT: %x.patt.loc14_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc14_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F1(constants.%x) { -// CHECK:STDOUT: %x.loc8_9.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc8_9.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F2() { -// CHECK:STDOUT: %x.patt.loc14_9.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %x: %I.type.733 = bind_symbolic_name x, 0 [symbolic] -// CHECK:STDOUT: %x.patt.3ad: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F1.type: type = fn_type @F1 [concrete] -// CHECK:STDOUT: %F1: %F1.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: %x.patt.e01: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F2.type: type = fn_type @F2 [concrete] -// CHECK:STDOUT: %F2: %F2.type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl.loc4 -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc4: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F1 = %F1.decl -// CHECK:STDOUT: .N = -// CHECK:STDOUT: .F2 = %F2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F1.decl: %F1.type = fn_decl @F1 [concrete = constants.%F1] { -// CHECK:STDOUT: %x.patt.loc11_9.1: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: %x.param_patt: %I.type.733 = value_param_pattern %x.patt.loc11_9.1, runtime_param [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I.type.733 = value_param runtime_param -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl.loc4 [concrete = constants.%I.type.733] -// CHECK:STDOUT: %x.loc11_9.1: %I.type.733 = bind_symbolic_name x, 0, %x.param [symbolic = %x.loc11_9.2 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc17: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: %F2.decl: %F2.type = fn_decl @F2 [concrete = constants.%F2] { -// CHECK:STDOUT: %x.patt.loc23_9.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc23_9.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %.1: = splice_block [concrete = ] { -// CHECK:STDOUT: %N.ref: = name_ref N, file.%N [concrete = file.%N] -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F1(%x.loc11_9.1: %I.type.733) { -// CHECK:STDOUT: %x.loc11_9.2: %I.type.733 = bind_symbolic_name x, 0 [symbolic = %x.loc11_9.2 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc11_9.2: %I.type.733 = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc11_9.2 (constants.%x.patt.3ad)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I.type.733); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F2(%x: ) { -// CHECK:STDOUT: %x.patt.loc23_9.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc23_9.2 (constants.%x.patt.e01)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F1(constants.%x) { -// CHECK:STDOUT: %x.loc11_9.2 => constants.%x -// CHECK:STDOUT: %x.patt.loc11_9.2 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F2() { -// CHECK:STDOUT: %x.patt.loc23_9.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_alias.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.ref: type = name_ref I, %I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %I: type = bind_alias I, %I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I1.type.80c: type = facet_type <@I1.1> [concrete] -// CHECK:STDOUT: %I2.type: type = facet_type <@I2> [concrete] -// CHECK:STDOUT: %Self.c7b: %I2.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %I3.type.07a: type = facet_type <@I3> [concrete] -// CHECK:STDOUT: %I3.type.b2f: type = facet_type <@I3, @I3(%Self.c7b)> [symbolic] -// CHECK:STDOUT: %Self.60c: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic] -// CHECK:STDOUT: %I4.type.451: type = facet_type <@I4> [concrete] -// CHECK:STDOUT: %I4.type.78e: type = facet_type <@I4, @I4(%Self.c7b, %Self.60c)> [symbolic] -// CHECK:STDOUT: %Self.a4d: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic] -// CHECK:STDOUT: %x: %I1.type.80c = bind_symbolic_name x, 3 [symbolic] -// CHECK:STDOUT: %x.patt: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.c7b, %Self.60c) [symbolic] -// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic] -// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type %I4.type.78e [symbolic] -// CHECK:STDOUT: %assoc0: %I4.assoc_type = assoc_entity element0, @I4.%F.decl [symbolic] -// CHECK:STDOUT: %I1.type.f4e: type = facet_type <@I1.2> [concrete] -// CHECK:STDOUT: %I1.type.575: type = facet_type <@I1.3> [concrete] -// CHECK:STDOUT: %I1.type.e5b: type = facet_type <@I1.4> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I1 = %I1.decl -// CHECK:STDOUT: .I2 = %I2.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.80c] {} {} -// CHECK:STDOUT: %I2.decl: type = interface_decl @I2 [concrete = constants.%I2.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I2 { -// CHECK:STDOUT: %Self: %I2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.c7b] -// CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [concrete = constants.%I3.type.07a] {} {} -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.4 [concrete = constants.%I1.type.e5b] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .I3 = %I3.decl -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I3(@I2.%Self: %I2.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] -// CHECK:STDOUT: %I3.type: type = facet_type <@I3, @I3(%Self.2)> [symbolic = %I3.type (constants.%I3.type.b2f)] -// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: -// CHECK:STDOUT: interface { -// CHECK:STDOUT: %Self.1: @I3.%I3.type (%I3.type.b2f) = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [concrete = constants.%I4.type.451] {} {} -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.3 [concrete = constants.%I1.type.575] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self.1 -// CHECK:STDOUT: .I4 = %I4.decl -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I4(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self.2: %I2.type = bind_symbolic_name Self, 0 [symbolic = %Self.2 (constants.%Self.c7b)] -// CHECK:STDOUT: %Self.3: %I3.type.b2f = bind_symbolic_name Self, 1 [symbolic = %Self.3 (constants.%Self.60c)] -// CHECK:STDOUT: %I4.type: type = facet_type <@I4, @I4(%Self.2, %Self.3)> [symbolic = %I4.type (constants.%I4.type.78e)] -// CHECK:STDOUT: %Self.4: %I4.type.78e = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] -// CHECK:STDOUT: %F.type: type = fn_type @F, @I4(%Self.2, %Self.3) [symbolic = %F.type (constants.%F.type)] -// CHECK:STDOUT: %F: @I4.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)] -// CHECK:STDOUT: %I4.assoc_type: type = assoc_entity_type @I4.%I4.type (%I4.type.78e) [symbolic = %I4.assoc_type (constants.%I4.assoc_type)] -// CHECK:STDOUT: %assoc0.loc16_19.2: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] -// CHECK:STDOUT: -// CHECK:STDOUT: interface { -// CHECK:STDOUT: %Self.1: @I4.%I4.type (%I4.type.78e) = bind_symbolic_name Self, 2 [symbolic = %Self.4 (constants.%Self.a4d)] -// CHECK:STDOUT: %F.decl: @I4.%F.type (%F.type) = fn_decl @F [symbolic = @I4.%F (constants.%F)] { -// CHECK:STDOUT: %x.patt.loc16_12.2: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: %I1.type.80c = value_param_pattern %x.patt.loc16_12.2, runtime_param [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: %I1.type.80c = value_param runtime_param -// CHECK:STDOUT: %I1.ref: type = name_ref I1, file.%I1.decl [concrete = constants.%I1.type.80c] -// CHECK:STDOUT: %x.loc16_12.2: %I1.type.80c = bind_symbolic_name x, 3, %x.param [symbolic = %x.loc16_12.1 (constants.%x)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc0.loc16_19.1: @I4.%I4.assoc_type (%I4.assoc_type) = assoc_entity element0, %F.decl [symbolic = %assoc0.loc16_19.2 (constants.%assoc0)] -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.f4e] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self.1 -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: .F = %assoc0.loc16_19.1 -// CHECK:STDOUT: witness = (%F.decl) -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.2(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e)) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.3(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f)) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic interface @I1.4(@I2.%Self: %I2.type) { -// CHECK:STDOUT: interface; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(@I2.%Self: %I2.type, @I3.%Self.1: @I3.%I3.type (%I3.type.b2f), @I4.%Self.1: @I4.%I4.type (%I4.type.78e), %x.loc16_12.2: %I1.type.80c) { -// CHECK:STDOUT: %x.loc16_12.1: %I1.type.80c = bind_symbolic_name x, 3 [symbolic = %x.loc16_12.1 (constants.%x)] -// CHECK:STDOUT: %x.patt.loc16_12.1: %I1.type.80c = symbolic_binding_pattern x, 3 [symbolic = %x.patt.loc16_12.1 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: %I1.type.80c); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I3(constants.%Self.c7b) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I4(constants.%Self.c7b, constants.%Self.60c) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d, constants.%x) { -// CHECK:STDOUT: %x.loc16_12.1 => constants.%x -// CHECK:STDOUT: %x.patt.loc16_12.1 => constants.%x -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.2(constants.%Self.c7b, constants.%Self.60c, constants.%Self.a4d) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I4(%Self.2, %Self.3) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.3(constants.%Self.c7b, constants.%Self.60c) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I3(%Self.2) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @I1.4(constants.%Self.c7b) {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- ignored_poison_in_import.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .I = file.%I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = imports.%Main.I -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.I = import_ref Main//poison, I, unloaded -// CHECK:STDOUT: %Main.N: = import_ref Main//poison, N, loaded -// CHECK:STDOUT: %N: = namespace %Main.N, [concrete] { -// CHECK:STDOUT: .F = %Main.F -// CHECK:STDOUT: .I = file.%I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = imports.%Main.I -// CHECK:STDOUT: .N = imports.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import.loc2_6.1 = import -// CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %x.patt: = symbolic_binding_pattern x, 0 [symbolic] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I.type.733: type = facet_type <@I.1> [concrete] -// CHECK:STDOUT: %I.type.4da: type = facet_type <@I.2> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N = %N -// CHECK:STDOUT: .I = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N: = namespace [concrete] { -// CHECK:STDOUT: .I = -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt.loc13_8.1: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt.loc13_8.1, runtime_param [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param -// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] -// CHECK:STDOUT: %x: = bind_symbolic_name x, 0, %x.param [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl.loc23: type = interface_decl @I.1 [concrete = constants.%I.type.733] {} {} -// CHECK:STDOUT: %I.decl.loc28: type = interface_decl @I.2 [concrete = constants.%I.type.4da] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.1; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I.2; -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%x: ) { -// CHECK:STDOUT: %x.patt.loc13_8.2: = symbolic_binding_pattern x, 0 [symbolic = %x.patt.loc13_8.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param_patt: ); -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F() { -// CHECK:STDOUT: %x.patt.loc13_8.2 => -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_with_lexical_result.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %I1.type.06a: type = facet_type <@I1.1> [concrete] -// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I1.type.06a [concrete] -// CHECK:STDOUT: %I1.type.8ea: type = facet_type <@I1.2> [concrete] -// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %I1.type.06a} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.1 { -// CHECK:STDOUT: %Self: %I1.type.06a = bind_symbolic_name Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I1.2; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %.loc11_10: %C.elem = field_decl v, element0 [concrete] -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %.loc11_5: %C.elem = var_pattern %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: %.var: ref %C.elem = var -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.2 [concrete = constants.%I1.type.8ea] {} {} -// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.v [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .I1 = -// CHECK:STDOUT: .v = %.loc11_10 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %I1.decl: type = interface_decl @I1.1 [concrete = constants.%I1.type.06a] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon b/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon index 1effdc4470cd7..2b9e7f14a128a 100644 --- a/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon +++ b/toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/namespace/no_prelude/name_poisoning.carbon @@ -195,264 +197,3 @@ namespace N3; // CHECK:STDERR: ^~ // CHECK:STDERR: namespace N1.N3; - -// CHECK:STDOUT: --- no_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.2a3: type = class_type @C.1 [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %C.0b8: type = class_type @C.2 [concrete] -// CHECK:STDOUT: %TestNamespaces.type: type = fn_type @TestNamespaces [concrete] -// CHECK:STDOUT: %TestNamespaces: %TestNamespaces.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.33b: type = ptr_type %C.2a3 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc4 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: .TestNamespaces = %TestNamespaces.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc4: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc12 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc8 -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc8: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl.loc11 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc8 [concrete = %N1.loc8] -// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc8 [concrete = %N1.loc8] -// CHECK:STDOUT: %C.decl.loc11: type = class_decl @C.1 [concrete = constants.%C.2a3] {} {} -// CHECK:STDOUT: %C.decl.loc12: type = class_decl @C.2 [concrete = constants.%C.0b8] {} {} -// CHECK:STDOUT: %TestNamespaces.decl: %TestNamespaces.type = fn_decl @TestNamespaces [concrete = constants.%TestNamespaces] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.1 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.2a3 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C.2 { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C.0b8 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @TestNamespaces() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %C.2a3 = binding_pattern x -// CHECK:STDOUT: %.loc14_3: %C.2a3 = var_pattern %x.patt -// CHECK:STDOUT: } -// CHECK:STDOUT: %x.var: ref %C.2a3 = var x -// CHECK:STDOUT: %.loc14_15: type = splice_block %C.ref.loc14 [concrete = constants.%C.2a3] { -// CHECK:STDOUT: %N2.ref.loc14: = name_ref N2, file.%N2 [concrete = file.%N2] -// CHECK:STDOUT: %N1.ref: = name_ref N1, file.%N1.loc8 [concrete = file.%N1.loc8] -// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, file.%C.decl.loc11 [concrete = constants.%C.2a3] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: ref %C.2a3 = bind_name x, %x.var -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %y.patt: %ptr.33b = binding_pattern y -// CHECK:STDOUT: %.loc15_3: %ptr.33b = var_pattern %y.patt -// CHECK:STDOUT: } -// CHECK:STDOUT: %y.var: ref %ptr.33b = var y -// CHECK:STDOUT: %x.ref: ref %C.2a3 = name_ref x, %x -// CHECK:STDOUT: %addr: %ptr.33b = addr_of %x.ref -// CHECK:STDOUT: assign %y.var, %addr -// CHECK:STDOUT: %.loc15_17: type = splice_block %ptr [concrete = constants.%ptr.33b] { -// CHECK:STDOUT: %N2.ref.loc15: = name_ref N2, file.%N2 [concrete = file.%N2] -// CHECK:STDOUT: %N3.ref: = name_ref N3, file.%N3 [concrete = file.%N1.loc8] -// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, file.%C.decl.loc11 [concrete = constants.%C.2a3] -// CHECK:STDOUT: %ptr: type = ptr_type %C.2a3 [concrete = constants.%ptr.33b] -// CHECK:STDOUT: } -// CHECK:STDOUT: %y: ref %ptr.33b = bind_name y, %y.var -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1 [concrete = %N1] -// CHECK:STDOUT: %N3: = bind_alias N3, %N1 [concrete = %N1] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declare_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc4 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N1.loc18: = namespace [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: .N2 = -// CHECK:STDOUT: .N4 = %N4 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref.loc8: = name_ref N1, %N1 [concrete = %N1] -// CHECK:STDOUT: %N3: = bind_alias N3, %N1 [concrete = %N1] -// CHECK:STDOUT: %N2.ref: = name_ref N2, %N2 [concrete = %N2] -// CHECK:STDOUT: %N1.ref.loc14: = name_ref N1, [concrete = ] -// CHECK:STDOUT: %N4: = bind_alias N4, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_use_declaration_after_poison.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc4 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: .N2 = -// CHECK:STDOUT: .N4 = %N4 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref.loc11: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N3: = bind_alias N3, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N1.loc18: = namespace [concrete] {} -// CHECK:STDOUT: %N2.ref: = name_ref N2, %N2 [concrete = %N2] -// CHECK:STDOUT: %N1.ref.loc24: = name_ref N1, [concrete = ] -// CHECK:STDOUT: %N4: = bind_alias N4, [concrete = ] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_alias.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc2 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc2: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc2 [concrete = %N1.loc2] -// CHECK:STDOUT: %N1.loc12: = bind_alias N1, %N1.loc2 [concrete = %N1.loc2] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_multiple_scopes.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1.loc4 -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.loc4: = namespace [concrete] {} -// CHECK:STDOUT: %N2: = namespace [concrete] { -// CHECK:STDOUT: .N3 = %N3 -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N3: = namespace [concrete] { -// CHECK:STDOUT: .N4 = %N4 -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N4: = namespace [concrete] { -// CHECK:STDOUT: .N1 = -// CHECK:STDOUT: .N5 = %N5 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1.ref: = name_ref N1, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N5: = bind_alias N5, %N1.loc4 [concrete = %N1.loc4] -// CHECK:STDOUT: %N1.loc24: = namespace [concrete] {} -// CHECK:STDOUT: %N1.loc32: = namespace [concrete] {} -// CHECK:STDOUT: %N1.loc37: = namespace [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- ignored_poison_in_import.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.N1: = import_ref Main//poison, N1, loaded -// CHECK:STDOUT: %N1: = namespace %Main.N1, [concrete] {} -// CHECK:STDOUT: %Main.N2: = import_ref Main//poison, N2, loaded -// CHECK:STDOUT: %N2: = namespace %Main.N2, [concrete] { -// CHECK:STDOUT: .N3 = %Main.N3 -// CHECK:STDOUT: .N1 = file.%N1 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = imports.%N1 -// CHECK:STDOUT: .N2 = imports.%N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %N1: = namespace [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- poison.impl.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Main.N2: = import_ref Main//poison, N2, loaded -// CHECK:STDOUT: %N2: = namespace %Main.N2, [concrete] { -// CHECK:STDOUT: .N3 = %Main.N3 -// CHECK:STDOUT: .N1 = file.%N1 -// CHECK:STDOUT: } -// CHECK:STDOUT: %Main.N1: = import_ref Main//poison, N1, loaded -// CHECK:STDOUT: %N1: = namespace %Main.N1, [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N2 = imports.%N2 -// CHECK:STDOUT: .N1 = imports.%N1 -// CHECK:STDOUT: } -// CHECK:STDOUT: %default.import.loc2_6.1 = import -// CHECK:STDOUT: %default.import.loc2_6.2 = import -// CHECK:STDOUT: %N1: = namespace [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_poison_when_lookup_fails.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .N1 = %N1 -// CHECK:STDOUT: .N3 = -// CHECK:STDOUT: } -// CHECK:STDOUT: %N1: = namespace [concrete] { -// CHECK:STDOUT: .N3 = -// CHECK:STDOUT: .N2 = %N2 -// CHECK:STDOUT: } -// CHECK:STDOUT: %N3.ref: = name_ref N3, [concrete = ] -// CHECK:STDOUT: %N2: = bind_alias N2, [concrete = ] -// CHECK:STDOUT: %N3.loc23: = namespace [concrete] {} -// CHECK:STDOUT: %N3.loc28: = namespace [concrete] {} -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon index f5d455834c4a6..02e68855d6e42 100644 --- a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon +++ b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// EXTRA-ARGS: --no-dump-sem-ir +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon @@ -17,39 +19,3 @@ fn F(x: bool); class r#Core {} - -// CHECK:STDOUT: --- fail_implicitly_poison_core.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %Core: type = class_type @Core [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: .r#Core = %Core.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %x.patt: = binding_pattern x -// CHECK:STDOUT: %x.param_patt: = value_param_pattern %x.patt, runtime_param0 [concrete = ] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %x.param: = value_param runtime_param0 -// CHECK:STDOUT: %x: = bind_name x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.decl: type = class_decl @Core [concrete = constants.%Core] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @Core { -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%Core -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%x.param_patt: ); -// CHECK:STDOUT: From 84b978e40ded6ce921085ee379ada36a35c6a5a6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 14:42:24 -0500 Subject: [PATCH 55/56] Test that `(T as I) as type` recovers its original type (#5057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `T as I` outside of a type position is a facet value, which does not have the interface of its original type. But when used in a type position, or converted explicitly back to `type`, it recovers its original type. See https://docs.carbon-lang.dev/docs/design/generics/details.html#facet-types: > The requirements determine which types may be implicitly converted to > a given facet type. The result of this conversion is a facet. For > example, Point_Inline from the “Inline impl” section implements > Vector, so Point_Inline may be implicitly converted to Vector as > considered as a type. The result is `Point_Inline as Vector`, which > has the members of Vector instead of the members of Point_Inline. If > the facet `Point_Inline as Vector` is used in a type position, it is > implicitly converted back to type type, see. This recovers the > original type for the facet, so `(Point_Inline as Vector) as type` is > `Point_Inline` again. --- ...t_value_as_type_knows_original_type.carbon | 573 ++++++++++++++++++ 1 file changed, 573 insertions(+) create mode 100644 toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon new file mode 100644 index 0000000000000..5c62861f52316 --- /dev/null +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon @@ -0,0 +1,573 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_as_type_knows_original_type.carbon + +// --- core.carbon + +package Core; + +interface As(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +interface ImplicitAs(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +// --- explicit_as_type.carbon + +library "[[@TEST_NAME]]"; + +import Core; + +interface Eats {} +interface Animal {} + +class Goat {} +impl Goat as Animal {} +impl Goat as Eats {} + +fn Feed(e:! Eats) {} + +fn F() { + Feed((Goat as Animal) as type); +} + +// --- facet_type_in_type_position.carbon + +library "[[@TEST_NAME]]"; + +import Core; + +interface Eats { + fn Eat(); +} +interface Animal {} + +class Goat { + fn Bleet() {} + + impl as Animal {} + extend impl as Eats { + fn Eat() {} + } +} + +fn F() { + // `Goat as Animal` in the type position retains/recovers the original type + // Goat, so member lookup can see more than just `Animal`. + + let x: Goat as Animal = {} as Goat; + x.Bleet(); + x.Eat(); + + (({} as Goat) as (Goat as Animal)).Bleet(); + (({} as Goat) as (Goat as Animal)).Eat(); +} + +// CHECK:STDOUT: --- core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic] +// CHECK:STDOUT: %Dest.patt: type = symbolic_binding_pattern Dest, 0 [symbolic] +// CHECK:STDOUT: %As.type.b51: type = generic_interface_type @As [concrete] +// CHECK:STDOUT: %As.generic: %As.type.b51 = struct_value () [concrete] +// CHECK:STDOUT: %As.type.8ba: type = facet_type <@As, @As(%Dest)> [symbolic] +// CHECK:STDOUT: %Self.b4e: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Self.as_type.7f0: type = facet_access_type %Self.b4e [symbolic] +// CHECK:STDOUT: %Convert.type.ad1: type = fn_type @Convert.1, @As(%Dest) [symbolic] +// CHECK:STDOUT: %Convert.0ed: %Convert.type.ad1 = struct_value () [symbolic] +// CHECK:STDOUT: %As.assoc_type: type = assoc_entity_type %As.type.8ba [symbolic] +// CHECK:STDOUT: %assoc0.ac5: %As.assoc_type = assoc_entity element0, @As.%Convert.decl [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.96f: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.96f = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.07f: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic] +// CHECK:STDOUT: %Self.0f3: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Self.as_type.419: type = facet_access_type %Self.0f3 [symbolic] +// CHECK:STDOUT: %Convert.type.4cf: type = fn_type @Convert.2, @ImplicitAs(%Dest) [symbolic] +// CHECK:STDOUT: %Convert.147: %Convert.type.4cf = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type %ImplicitAs.type.07f [symbolic] +// CHECK:STDOUT: %assoc0.a50: %ImplicitAs.assoc_type = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .As = %As.decl +// CHECK:STDOUT: .ImplicitAs = %ImplicitAs.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %As.decl: %As.type.b51 = interface_decl @As [concrete = constants.%As.generic] { +// CHECK:STDOUT: %Dest.patt.loc4_14.1: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc4_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: %Dest.param_patt: type = value_param_pattern %Dest.patt.loc4_14.1, runtime_param [symbolic = %Dest.patt.loc4_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.param: type = value_param runtime_param +// CHECK:STDOUT: %Dest.loc4_14.1: type = bind_symbolic_name Dest, 0, %Dest.param [symbolic = %Dest.loc4_14.2 (constants.%Dest)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %ImplicitAs.decl: %ImplicitAs.type.96f = interface_decl @ImplicitAs [concrete = constants.%ImplicitAs.generic] { +// CHECK:STDOUT: %Dest.patt.loc8_22.1: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc8_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: %Dest.param_patt: type = value_param_pattern %Dest.patt.loc8_22.1, runtime_param [symbolic = %Dest.patt.loc8_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.param: type = value_param runtime_param +// CHECK:STDOUT: %Dest.loc8_22.1: type = bind_symbolic_name Dest, 0, %Dest.param [symbolic = %Dest.loc8_22.2 (constants.%Dest)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @As(%Dest.loc4_14.1: type) { +// CHECK:STDOUT: %Dest.loc4_14.2: type = bind_symbolic_name Dest, 0 [symbolic = %Dest.loc4_14.2 (constants.%Dest)] +// CHECK:STDOUT: %Dest.patt.loc4_14.2: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc4_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %As.type: type = facet_type <@As, @As(%Dest.loc4_14.2)> [symbolic = %As.type (constants.%As.type.8ba)] +// CHECK:STDOUT: %Self.2: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert.1, @As(%Dest.loc4_14.2) [symbolic = %Convert.type (constants.%Convert.type.ad1)] +// CHECK:STDOUT: %Convert: @As.%Convert.type (%Convert.type.ad1) = struct_value () [symbolic = %Convert (constants.%Convert.0ed)] +// CHECK:STDOUT: %As.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.8ba) [symbolic = %As.assoc_type (constants.%As.assoc_type)] +// CHECK:STDOUT: %assoc0.loc5_35.2: @As.%As.assoc_type (%As.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc5_35.2 (constants.%assoc0.ac5)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @As.%As.type (%As.type.8ba) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)] +// CHECK:STDOUT: %Convert.decl: @As.%Convert.type (%Convert.type.ad1) = fn_decl @Convert.1 [symbolic = @As.%Convert (constants.%Convert.0ed)] { +// CHECK:STDOUT: %self.patt: @Convert.1.%Self.as_type.loc5_20.1 (%Self.as_type.7f0) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Convert.1.%Self.as_type.loc5_20.1 (%Self.as_type.7f0) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: @Convert.1.%Dest (%Dest) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Convert.1.%Dest (%Dest) = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.ref: type = name_ref Dest, @As.%Dest.loc4_14.1 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %self.param: @Convert.1.%Self.as_type.loc5_20.1 (%Self.as_type.7f0) = value_param runtime_param0 +// CHECK:STDOUT: %.loc5_20.1: type = splice_block %.loc5_20.3 [symbolic = %Self.as_type.loc5_20.1 (constants.%Self.as_type.7f0)] { +// CHECK:STDOUT: %.loc5_20.2: @Convert.1.%As.type (%As.type.8ba) = specific_constant @As.%Self.1, @As(constants.%Dest) [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.ref: @Convert.1.%As.type (%As.type.8ba) = name_ref Self, %.loc5_20.2 [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.as_type.loc5_20.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: %.loc5_20.3: type = converted %Self.ref, %Self.as_type.loc5_20.2 [symbolic = %Self.as_type.loc5_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Convert.1.%Self.as_type.loc5_20.1 (%Self.as_type.7f0) = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref @Convert.1.%Dest (%Dest) = out_param runtime_param1 +// CHECK:STDOUT: %return: ref @Convert.1.%Dest (%Dest) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc5_35.1: @As.%As.assoc_type (%As.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc5_35.2 (constants.%assoc0.ac5)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .Dest = +// CHECK:STDOUT: .Convert = %assoc0.loc5_35.1 +// CHECK:STDOUT: witness = (%Convert.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @ImplicitAs(%Dest.loc8_22.1: type) { +// CHECK:STDOUT: %Dest.loc8_22.2: type = bind_symbolic_name Dest, 0 [symbolic = %Dest.loc8_22.2 (constants.%Dest)] +// CHECK:STDOUT: %Dest.patt.loc8_22.2: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc8_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest.loc8_22.2)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.07f)] +// CHECK:STDOUT: %Self.2: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert.2, @ImplicitAs(%Dest.loc8_22.2) [symbolic = %Convert.type (constants.%Convert.type.4cf)] +// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.4cf) = struct_value () [symbolic = %Convert (constants.%Convert.147)] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type)] +// CHECK:STDOUT: %assoc0.loc9_35.2: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_35.2 (constants.%assoc0.a50)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)] +// CHECK:STDOUT: %Convert.decl: @ImplicitAs.%Convert.type (%Convert.type.4cf) = fn_decl @Convert.2 [symbolic = @ImplicitAs.%Convert (constants.%Convert.147)] { +// CHECK:STDOUT: %self.patt: @Convert.2.%Self.as_type.loc9_20.1 (%Self.as_type.419) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Convert.2.%Self.as_type.loc9_20.1 (%Self.as_type.419) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: @Convert.2.%Dest (%Dest) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Convert.2.%Dest (%Dest) = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.ref: type = name_ref Dest, @ImplicitAs.%Dest.loc8_22.1 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %self.param: @Convert.2.%Self.as_type.loc9_20.1 (%Self.as_type.419) = value_param runtime_param0 +// CHECK:STDOUT: %.loc9_20.1: type = splice_block %.loc9_20.3 [symbolic = %Self.as_type.loc9_20.1 (constants.%Self.as_type.419)] { +// CHECK:STDOUT: %.loc9_20.2: @Convert.2.%ImplicitAs.type (%ImplicitAs.type.07f) = specific_constant @ImplicitAs.%Self.1, @ImplicitAs(constants.%Dest) [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.ref: @Convert.2.%ImplicitAs.type (%ImplicitAs.type.07f) = name_ref Self, %.loc9_20.2 [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.as_type.loc9_20.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc9_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: %.loc9_20.3: type = converted %Self.ref, %Self.as_type.loc9_20.2 [symbolic = %Self.as_type.loc9_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Convert.2.%Self.as_type.loc9_20.1 (%Self.as_type.419) = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref @Convert.2.%Dest (%Dest) = out_param runtime_param1 +// CHECK:STDOUT: %return: ref @Convert.2.%Dest (%Dest) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc9_35.1: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc9_35.2 (constants.%assoc0.a50)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .Dest = +// CHECK:STDOUT: .Convert = %assoc0.loc9_35.1 +// CHECK:STDOUT: witness = (%Convert.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert.1(@As.%Dest.loc4_14.1: type, @As.%Self.1: @As.%As.type (%As.type.8ba)) { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %As.type: type = facet_type <@As, @As(%Dest)> [symbolic = %As.type (constants.%As.type.8ba)] +// CHECK:STDOUT: %Self: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.as_type.loc5_20.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.1.%Self.as_type.loc5_20.1 (%Self.as_type.7f0)]() -> @Convert.1.%Dest (%Dest); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert.2(@ImplicitAs.%Dest.loc8_22.1: type, @ImplicitAs.%Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f)) { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.07f)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.as_type.loc9_20.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc9_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.2.%Self.as_type.loc9_20.1 (%Self.as_type.419)]() -> @Convert.2.%Dest (%Dest); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(constants.%Dest) { +// CHECK:STDOUT: %Dest.loc4_14.2 => constants.%Dest +// CHECK:STDOUT: %Dest.patt.loc4_14.2 => constants.%Dest +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert.1(constants.%Dest, constants.%Self.b4e) { +// CHECK:STDOUT: %Dest => constants.%Dest +// CHECK:STDOUT: %As.type => constants.%As.type.8ba +// CHECK:STDOUT: %Self => constants.%Self.b4e +// CHECK:STDOUT: %Self.as_type.loc5_20.1 => constants.%Self.as_type.7f0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(@Convert.1.%Dest) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(%Dest.loc4_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%Dest) { +// CHECK:STDOUT: %Dest.loc8_22.2 => constants.%Dest +// CHECK:STDOUT: %Dest.patt.loc8_22.2 => constants.%Dest +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert.2(constants.%Dest, constants.%Self.0f3) { +// CHECK:STDOUT: %Dest => constants.%Dest +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.07f +// CHECK:STDOUT: %Self => constants.%Self.0f3 +// CHECK:STDOUT: %Self.as_type.loc9_20.1 => constants.%Self.as_type.419 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(@Convert.2.%Dest) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(%Dest.loc8_22.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- explicit_as_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Eats.type: type = facet_type <@Eats> [concrete] +// CHECK:STDOUT: %Self.1b5: %Eats.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] +// CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %impl_witness: = impl_witness () [concrete] +// CHECK:STDOUT: %e: %Eats.type = bind_symbolic_name e, 0 [symbolic] +// CHECK:STDOUT: %e.patt: %Eats.type = symbolic_binding_pattern e, 0 [symbolic] +// CHECK:STDOUT: %Feed.type: type = fn_type @Feed [concrete] +// CHECK:STDOUT: %Feed: %Feed.type = struct_value () [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %Goat, %impl_witness [concrete] +// CHECK:STDOUT: %Eats.facet: %Eats.type = facet_value %Goat, %impl_witness [concrete] +// CHECK:STDOUT: %Feed.specific_fn: = specific_function %Feed, @Feed(%Eats.facet) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Eats = %Eats.decl +// CHECK:STDOUT: .Animal = %Animal.decl +// CHECK:STDOUT: .Goat = %Goat.decl +// CHECK:STDOUT: .Feed = %Feed.decl +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Eats.decl: type = interface_decl @Eats [concrete = constants.%Eats.type] {} {} +// CHECK:STDOUT: %Animal.decl: type = interface_decl @Animal [concrete = constants.%Animal.type] {} {} +// CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} +// CHECK:STDOUT: impl_decl @impl.27e [concrete] {} { +// CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness () [concrete = constants.%impl_witness] +// CHECK:STDOUT: impl_decl @impl.b88 [concrete] {} { +// CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc11: = impl_witness () [concrete = constants.%impl_witness] +// CHECK:STDOUT: %Feed.decl: %Feed.type = fn_decl @Feed [concrete = constants.%Feed] { +// CHECK:STDOUT: %e.patt.loc13_9.1: %Eats.type = symbolic_binding_pattern e, 0 [symbolic = %e.patt.loc13_9.2 (constants.%e.patt)] +// CHECK:STDOUT: %e.param_patt: %Eats.type = value_param_pattern %e.patt.loc13_9.1, runtime_param [symbolic = %e.patt.loc13_9.2 (constants.%e.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %e.param: %Eats.type = value_param runtime_param +// CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] +// CHECK:STDOUT: %e.loc13_9.1: %Eats.type = bind_symbolic_name e, 0, %e.param [symbolic = %e.loc13_9.2 (constants.%e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Eats { +// CHECK:STDOUT: %Self: %Eats.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1b5] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Animal { +// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.fd4] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.27e: %Goat.ref as %Animal.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness.loc10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.b88: %Goat.ref as %Eats.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness.loc11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Goat +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Feed(%e.loc13_9.1: %Eats.type) { +// CHECK:STDOUT: %e.loc13_9.2: %Eats.type = bind_symbolic_name e, 0 [symbolic = %e.loc13_9.2 (constants.%e)] +// CHECK:STDOUT: %e.patt.loc13_9.2: %Eats.type = symbolic_binding_pattern e, 0 [symbolic = %e.patt.loc13_9.2 (constants.%e.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%e.param_patt: %Eats.type) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Feed.ref: %Feed.type = name_ref Feed, file.%Feed.decl [concrete = constants.%Feed] +// CHECK:STDOUT: %Goat.ref: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value constants.%Goat, constants.%impl_witness [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc16_14: %Animal.type = converted %Goat.ref, %Animal.facet [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %as_type: type = facet_access_type %.loc16_14 [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc16_25: type = converted %.loc16_14, %as_type [concrete = constants.%Goat] +// CHECK:STDOUT: %Eats.facet: %Eats.type = facet_value constants.%Goat, constants.%impl_witness [concrete = constants.%Eats.facet] +// CHECK:STDOUT: %.loc16_32: %Eats.type = converted %.loc16_25, %Eats.facet [concrete = constants.%Eats.facet] +// CHECK:STDOUT: %Feed.specific_fn: = specific_function %Feed.ref, @Feed(constants.%Eats.facet) [concrete = constants.%Feed.specific_fn] +// CHECK:STDOUT: %Feed.call: init %empty_tuple.type = call %Feed.specific_fn() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Feed(constants.%e) { +// CHECK:STDOUT: %e.loc13_9.2 => constants.%e +// CHECK:STDOUT: %e.patt.loc13_9.2 => constants.%e +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Feed(constants.%Eats.facet) { +// CHECK:STDOUT: %e.loc13_9.2 => constants.%Eats.facet +// CHECK:STDOUT: %e.patt.loc13_9.2 => constants.%Eats.facet +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- facet_type_in_type_position.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Eats.type: type = facet_type <@Eats> [concrete] +// CHECK:STDOUT: %Self.1b5: %Eats.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Eat.type.e5d: type = fn_type @Eat.1 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Eat.7cd: %Eat.type.e5d = struct_value () [concrete] +// CHECK:STDOUT: %Eats.assoc_type: type = assoc_entity_type %Eats.type [concrete] +// CHECK:STDOUT: %assoc0: %Eats.assoc_type = assoc_entity element0, @Eats.%Eat.decl [concrete] +// CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] +// CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Bleet.type: type = fn_type @Bleet [concrete] +// CHECK:STDOUT: %Bleet: %Bleet.type = struct_value () [concrete] +// CHECK:STDOUT: %impl_witness.1bc: = impl_witness () [concrete] +// CHECK:STDOUT: %impl_witness.9a5: = impl_witness (@impl.626.%Eat.decl) [concrete] +// CHECK:STDOUT: %Eat.type.1b3: type = fn_type @Eat.2 [concrete] +// CHECK:STDOUT: %Eat.73e: %Eat.type.1b3 = struct_value () [concrete] +// CHECK:STDOUT: %Eats.facet: %Eats.type = facet_value %Goat, %impl_witness.9a5 [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %Goat, %impl_witness.1bc [concrete] +// CHECK:STDOUT: %Goat.val: %Goat = struct_value () [concrete] +// CHECK:STDOUT: %.e36: type = fn_type_with_self_type %Eat.type.e5d, %Eats.facet [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Eats = %Eats.decl +// CHECK:STDOUT: .Animal = %Animal.decl +// CHECK:STDOUT: .Goat = %Goat.decl +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Eats.decl: type = interface_decl @Eats [concrete = constants.%Eats.type] {} {} +// CHECK:STDOUT: %Animal.decl: type = interface_decl @Animal [concrete = constants.%Animal.type] {} {} +// CHECK:STDOUT: %Goat.decl: type = class_decl @Goat [concrete = constants.%Goat] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Eats { +// CHECK:STDOUT: %Self: %Eats.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1b5] +// CHECK:STDOUT: %Eat.decl: %Eat.type.e5d = fn_decl @Eat.1 [concrete = constants.%Eat.7cd] {} {} +// CHECK:STDOUT: %assoc0: %Eats.assoc_type = assoc_entity element0, %Eat.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Eat = %assoc0 +// CHECK:STDOUT: witness = (%Eat.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Animal { +// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.fd4] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.32f: %Self.ref as %Animal.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = @Goat.%impl_witness.loc14 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.626: %Self.ref as %Eats.ref { +// CHECK:STDOUT: %Eat.decl: %Eat.type.1b3 = fn_decl @Eat.2 [concrete = constants.%Eat.73e] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Eat = %Eat.decl +// CHECK:STDOUT: witness = @Goat.%impl_witness.loc15 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: %Bleet.decl: %Bleet.type = fn_decl @Bleet [concrete = constants.%Bleet] {} {} +// CHECK:STDOUT: impl_decl @impl.32f [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc14: = impl_witness () [concrete = constants.%impl_witness.1bc] +// CHECK:STDOUT: impl_decl @impl.626 [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc15: = impl_witness (@impl.626.%Eat.decl) [concrete = constants.%impl_witness.9a5] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Goat +// CHECK:STDOUT: .Bleet = %Bleet.decl +// CHECK:STDOUT: .Animal = +// CHECK:STDOUT: .Eats = +// CHECK:STDOUT: .Eat = +// CHECK:STDOUT: extend @impl.626.%Eats.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Eat.1(@Eats.%Self: %Eats.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Bleet() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Eat.2() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %Goat = binding_pattern x +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc24_28.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %Goat.ref.loc24_33: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc24_28.2: ref %Goat = temporary_storage +// CHECK:STDOUT: %.loc24_28.3: init %Goat = class_init (), %.loc24_28.2 [concrete = constants.%Goat.val] +// CHECK:STDOUT: %.loc24_28.4: ref %Goat = temporary %.loc24_28.2, %.loc24_28.3 +// CHECK:STDOUT: %.loc24_30: ref %Goat = converted %.loc24_28.1, %.loc24_28.4 +// CHECK:STDOUT: %.loc24_15.1: type = splice_block %.loc24_15.3 [concrete = constants.%Goat] { +// CHECK:STDOUT: %Goat.ref.loc24_10: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref.loc24: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: %Animal.facet.loc24: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc24_15.2: %Animal.type = converted %Goat.ref.loc24_10, %Animal.facet.loc24 [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %as_type.loc24: type = facet_access_type %.loc24_15.2 [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc24_15.3: type = converted %.loc24_15.2, %as_type.loc24 [concrete = constants.%Goat] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: ref %Goat = bind_name x, %.loc24_30 +// CHECK:STDOUT: %x.ref.loc25: ref %Goat = name_ref x, %x +// CHECK:STDOUT: %Bleet.ref.loc25: %Bleet.type = name_ref Bleet, @Goat.%Bleet.decl [concrete = constants.%Bleet] +// CHECK:STDOUT: %Bleet.call.loc25: init %empty_tuple.type = call %Bleet.ref.loc25() +// CHECK:STDOUT: %x.ref.loc26: ref %Goat = name_ref x, %x +// CHECK:STDOUT: %Eat.ref.loc26: %Eats.assoc_type = name_ref Eat, @Eats.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc26: %.e36 = impl_witness_access constants.%impl_witness.9a5, element0 [concrete = constants.%Eat.73e] +// CHECK:STDOUT: %Eat.call.loc26: init %empty_tuple.type = call %impl.elem0.loc26() +// CHECK:STDOUT: %.loc28_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %Goat.ref.loc28_11: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc28_6.2: ref %Goat = temporary_storage +// CHECK:STDOUT: %.loc28_6.3: init %Goat = class_init (), %.loc28_6.2 [concrete = constants.%Goat.val] +// CHECK:STDOUT: %.loc28_6.4: ref %Goat = temporary %.loc28_6.2, %.loc28_6.3 +// CHECK:STDOUT: %.loc28_8: ref %Goat = converted %.loc28_6.1, %.loc28_6.4 +// CHECK:STDOUT: %Goat.ref.loc28_21: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref.loc28: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: %Animal.facet.loc28: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc28_26: %Animal.type = converted %Goat.ref.loc28_21, %Animal.facet.loc28 [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %as_type.loc28: type = facet_access_type %.loc28_26 [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc28_35: type = converted %.loc28_26, %as_type.loc28 [concrete = constants.%Goat] +// CHECK:STDOUT: %Bleet.ref.loc28: %Bleet.type = name_ref Bleet, @Goat.%Bleet.decl [concrete = constants.%Bleet] +// CHECK:STDOUT: %Bleet.call.loc28: init %empty_tuple.type = call %Bleet.ref.loc28() +// CHECK:STDOUT: %.loc29_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %Goat.ref.loc29_11: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc29_6.2: ref %Goat = temporary_storage +// CHECK:STDOUT: %.loc29_6.3: init %Goat = class_init (), %.loc29_6.2 [concrete = constants.%Goat.val] +// CHECK:STDOUT: %.loc29_6.4: ref %Goat = temporary %.loc29_6.2, %.loc29_6.3 +// CHECK:STDOUT: %.loc29_8: ref %Goat = converted %.loc29_6.1, %.loc29_6.4 +// CHECK:STDOUT: %Goat.ref.loc29_21: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] +// CHECK:STDOUT: %Animal.ref.loc29: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] +// CHECK:STDOUT: %Animal.facet.loc29: %Animal.type = facet_value constants.%Goat, constants.%impl_witness.1bc [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %.loc29_26: %Animal.type = converted %Goat.ref.loc29_21, %Animal.facet.loc29 [concrete = constants.%Animal.facet] +// CHECK:STDOUT: %as_type.loc29: type = facet_access_type %.loc29_26 [concrete = constants.%Goat] +// CHECK:STDOUT: %.loc29_35: type = converted %.loc29_26, %as_type.loc29 [concrete = constants.%Goat] +// CHECK:STDOUT: %Eat.ref.loc29: %Eats.assoc_type = name_ref Eat, @Eats.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc29: %.e36 = impl_witness_access constants.%impl_witness.9a5, element0 [concrete = constants.%Eat.73e] +// CHECK:STDOUT: %Eat.call.loc29: init %empty_tuple.type = call %impl.elem0.loc29() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Eat.1(constants.%Self.1b5) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Eat.1(constants.%Eats.facet) {} +// CHECK:STDOUT: From 2d1bfcac2eb435efea2e78e7bdb15a08bd289cd5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 15:17:36 -0500 Subject: [PATCH 56/56] Perform member lookup on FacetAccessType (#5058) The name scope lookup and member name lookup both need to handle the case where the base inst is a FacetAccessType. Then we move from the FacetAccessType to the FacetType which is the type of the instruction inside the FacetAccessType. We do name lookup on FacetType already, so "unwrapping" the FacetAccessType to the FacetType just makes use of that path. Similarly we do member access on FacetType already, so we can reuse that codepath with the FacetType found in the FacetAccessType. --- toolchain/check/member_access.cpp | 15 +- toolchain/check/name_lookup.cpp | 13 ++ .../testdata/facet/no_prelude/access.carbon | 147 +++++++++++++++++- 3 files changed, 164 insertions(+), 11 deletions(-) diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index fc1afe6f78fff..ed94ab4eef8b7 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -287,8 +287,16 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, context.types().TryGetAs(type_id)) { if (lookup_in_type_of_base) { SemIR::TypeId base_type_id = context.insts().Get(base_id).type_id(); - if (base_type_id != SemIR::TypeType::SingletonTypeId && - context.types().IsFacetType(base_type_id)) { + if (auto facet_access_type = + context.types().TryGetAs(base_type_id)) { + // Move from the type of a symbolic facet value up in typish-ness to its + // FacetType to find the type to work with. + base_id = facet_access_type->facet_value_inst_id; + base_type_id = context.insts().Get(base_id).type_id(); + } + + if (auto facet_type = + context.types().TryGetAs(base_type_id)) { // Handles `T.F` when `T` is a non-type facet. auto base_as_type = ExprAsType(context, loc_id, base_id); @@ -301,9 +309,8 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, // First look for `*assoc_interface` in the type of the base. If it is // found, get the witness that the interface is implemented from // `base_id`. - auto facet_type = context.types().GetAs(base_type_id); const auto& facet_type_info = - context.facet_types().Get(facet_type.facet_type_id); + context.facet_types().Get(facet_type->facet_type_id); // Witness that `T` implements the `*assoc_interface`. SemIR::InstId witness_inst_id = SemIR::InstId::None; for (auto base_interface : facet_type_info.impls_constraints) { diff --git a/toolchain/check/name_lookup.cpp b/toolchain/check/name_lookup.cpp index 7482e952ee8af..e84ae392d827d 100644 --- a/toolchain/check/name_lookup.cpp +++ b/toolchain/check/name_lookup.cpp @@ -248,6 +248,19 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id, -> bool { auto base_id = context.constant_values().GetInstId(base_const_id); auto base = context.insts().Get(base_id); + + if (auto base_as_facet_access_type = base.TryAs()) { + // Move from the symbolic facet value up in typish-ness to its FacetType to + // find a lookup scope. + auto facet_type_type_id = + context.insts() + .Get(base_as_facet_access_type->facet_value_inst_id) + .type_id(); + base_const_id = context.types().GetConstantId(facet_type_type_id); + base_id = context.constant_values().GetInstId(base_const_id); + base = context.insts().Get(base_id); + } + if (auto base_as_namespace = base.TryAs()) { scopes->push_back( LookupScope{.name_scope_id = base_as_namespace->name_scope_id, diff --git a/toolchain/check/testdata/facet/no_prelude/access.carbon b/toolchain/check/testdata/facet/no_prelude/access.carbon index de26cc80c6529..a3efc091e98dc 100644 --- a/toolchain/check/testdata/facet/no_prelude/access.carbon +++ b/toolchain/check/testdata/facet/no_prelude/access.carbon @@ -32,7 +32,7 @@ fn Use(T:! I) -> T { return T.Make(); } -// --- fail_todo_access_assoc_method.carbon +// --- access_assoc_method.carbon library "[[@TEST_NAME]]"; @@ -41,13 +41,21 @@ interface I { } fn Use[T:! I](x: T) -> T { - // CHECK:STDERR: fail_todo_access_assoc_method.carbon:[[@LINE+4]]:10: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: return x.Copy(); - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: return x.Copy(); } +// --- access_selfless_method.carbon + +library "[[@TEST_NAME]]"; + +interface I { + fn Hello(); +} + +fn Use[T:! I](x: T){ + x.Hello(); +} + // --- access_assoc_method_indirect.carbon library "[[@TEST_NAME]]"; @@ -270,7 +278,7 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: // CHECK:STDOUT: specific @Make(@Use.%I.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_access_assoc_method.carbon +// CHECK:STDOUT: --- access_assoc_method.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] @@ -286,6 +294,10 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: %Use.type: type = fn_type @Use [concrete] // CHECK:STDOUT: %Use: %Use.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %T.as_wit: = facet_access_witness %T [symbolic] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.4ef: type = fn_type_with_self_type %Copy.type, %I.facet [symbolic] +// CHECK:STDOUT: %impl.elem0: %.4ef = impl_witness_access %T.as_wit, element0 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -363,11 +375,25 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type @Use.%T.as_type.loc8_18.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %T.as_wit.loc9_11.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc9_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc9_11.2 [symbolic = %I.facet (constants.%I.facet)] +// CHECK:STDOUT: %.loc9_11.2: type = fn_type_with_self_type constants.%Copy.type, %I.facet [symbolic = %.loc9_11.2 (constants.%.4ef)] +// CHECK:STDOUT: %impl.elem0.loc9_11.2: @Use.%.loc9_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc9_11.2, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0)] // CHECK:STDOUT: // CHECK:STDOUT: fn[%T.param_patt: %I.type](%x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type)) -> @Use.%T.as_type.loc8_18.2 (%T.as_type) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @Use.%T.as_type.loc8_18.2 (%T.as_type) = name_ref x, %x -// CHECK:STDOUT: return +// CHECK:STDOUT: %Copy.ref: %I.assoc_type = name_ref Copy, @I.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc9: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc9_11.1: type = converted constants.%T, %T.as_type.loc9 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc9_11.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc9_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc9_11.1: @Use.%.loc9_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc9_11.1, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %bound_method: = bound_method %x.ref, %impl.elem0.loc9_11.1 +// CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Copy(constants.%I.facet) +// CHECK:STDOUT: %Copy.call: init @Use.%T.as_type.loc8_18.2 (%T.as_type) = call %specific_fn(%x.ref) +// CHECK:STDOUT: %.loc9_18.1: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_of_initializer %Copy.call +// CHECK:STDOUT: %.loc9_18.2: @Use.%T.as_type.loc8_18.2 (%T.as_type) = converted %Copy.call, %.loc9_18.1 +// CHECK:STDOUT: return %.loc9_18.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -382,6 +408,113 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: %T.as_type.loc8_18.2 => constants.%T.as_type // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Copy(constants.%I.facet) { +// CHECK:STDOUT: %Self => constants.%I.facet +// CHECK:STDOUT: %Self.as_type.loc5_17.1 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- access_selfless_method.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Hello.type: type = fn_type @Hello [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Hello: %Hello.type = struct_value () [concrete] +// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [concrete] +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%Hello.decl [concrete] +// CHECK:STDOUT: %T: %I.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: %I.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %Use.type: type = fn_type @Use [concrete] +// CHECK:STDOUT: %Use: %Use.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %T.as_wit: = facet_access_witness %T [symbolic] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.33b: type = fn_type_with_self_type %Hello.type, %I.facet [symbolic] +// CHECK:STDOUT: %impl.elem0: %.33b = impl_witness_access %T.as_wit, element0 [symbolic] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Hello(%I.facet) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .Use = %Use.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [concrete = constants.%Use] { +// CHECK:STDOUT: %T.patt.loc8_8.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc8_8.1, runtime_param [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %x.patt: @Use.%T.as_type.loc8_18.2 (%T.as_type) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %T.loc8_8.1: %I.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %x.param: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc8_18.1: type = splice_block %.loc8_18.2 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %I.type = name_ref T, %T.loc8_8.1 [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc8_18.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc8_18.2: type = converted %T.ref, %T.as_type.loc8_18.1 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @Use.%T.as_type.loc8_18.2 (%T.as_type) = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Hello.decl: %Hello.type = fn_decl @Hello [concrete = constants.%Hello] {} {} +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %Hello.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Hello = %assoc0 +// CHECK:STDOUT: witness = (%Hello.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Hello(@I.%Self: %I.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Use(%T.loc8_8.1: %I.type) { +// CHECK:STDOUT: %T.loc8_8.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc8_8.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.as_type.loc8_18.2: type = facet_access_type %T.loc8_8.2 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @Use.%T.as_type.loc8_18.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %T.as_wit.loc9_4.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc9_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc9_4.2 [symbolic = %I.facet (constants.%I.facet)] +// CHECK:STDOUT: %.loc9_4.2: type = fn_type_with_self_type constants.%Hello.type, %I.facet [symbolic = %.loc9_4.2 (constants.%.33b)] +// CHECK:STDOUT: %impl.elem0.loc9_4.2: @Use.%.loc9_4.2 (%.33b) = impl_witness_access %T.as_wit.loc9_4.2, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_fn.loc9_4.2: = specific_function %impl.elem0.loc9_4.2, @Hello(%I.facet) [symbolic = %specific_fn.loc9_4.2 (constants.%specific_fn)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %I.type](%x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %x.ref: @Use.%T.as_type.loc8_18.2 (%T.as_type) = name_ref x, %x +// CHECK:STDOUT: %Hello.ref: %I.assoc_type = name_ref Hello, @I.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc9: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc9_4.1: type = converted constants.%T, %T.as_type.loc9 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc9_4.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc9_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc9_4.1: @Use.%.loc9_4.2 (%.33b) = impl_witness_access %T.as_wit.loc9_4.1, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_fn.loc9_4.1: = specific_function %impl.elem0.loc9_4.1, @Hello(constants.%I.facet) [symbolic = %specific_fn.loc9_4.2 (constants.%specific_fn)] +// CHECK:STDOUT: %Hello.call: init %empty_tuple.type = call %specific_fn.loc9_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Use(constants.%T) { +// CHECK:STDOUT: %T.loc8_8.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc8_8.2 => constants.%T +// CHECK:STDOUT: %T.as_type.loc8_18.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(constants.%I.facet) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(@Use.%I.facet) {} +// CHECK:STDOUT: // CHECK:STDOUT: --- access_assoc_method_indirect.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants {