diff --git a/toolchain/check/action.cpp b/toolchain/check/action.cpp index fba914c2fc35..ad8b1540a8ad 100644 --- a/toolchain/check/action.cpp +++ b/toolchain/check/action.cpp @@ -71,7 +71,8 @@ template requires SemIR::Internal::IsIdKindType && SameAsOneOf + SemIR::ElementIndex, SemIR::ClangDeclId, + SemIR::BoolValue> static auto OperandDependence(Context& /*context*/, IdT /*id*/) -> SemIR::ConstantDependence { return SemIR::ConstantDependence::None; @@ -98,6 +99,12 @@ static auto OperandDependence(Context& context, return result; } +static auto OperandDependence(Context& context, + SemIR::MetaInstBlockId inst_block_id) + -> SemIR::ConstantDependence { + return OperandDependence(context, SemIR::InstBlockId{inst_block_id}); +} + static auto OperandDependence(Context& context, SemIR::SpecificId specific_id) -> SemIR::ConstantDependence { auto specific = context.specifics().Get(specific_id); diff --git a/toolchain/check/call.cpp b/toolchain/check/call.cpp index 01031f995da6..a00ac627a91c 100644 --- a/toolchain/check/call.cpp +++ b/toolchain/check/call.cpp @@ -7,6 +7,7 @@ #include #include "toolchain/base/kind_switch.h" +#include "toolchain/check/action.h" #include "toolchain/check/context.h" #include "toolchain/check/control_flow.h" #include "toolchain/check/convert.h" @@ -342,9 +343,28 @@ static auto PerformCallToNonFunction(Context& context, SemIR::LocId loc_id, } } -auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, - llvm::ArrayRef arg_ids, bool is_desugared) - -> SemIR::InstId { +// Determines whether a call can be performed immediately (i.e. whether it is +// non-template-dependent). +static auto IsCallPerformable(Context& context, SemIR::InstId callee_id, + llvm::ArrayRef arg_ids) -> bool { + if (OperandDependence(context, callee_id) == + SemIR::ConstantDependence::Template) { + return false; + } + for (auto arg_id : arg_ids) { + if (OperandDependence(context, arg_id) == + SemIR::ConstantDependence::Template) { + return false; + } + } + return true; +} + +// Common logic for `PerformCall` and `PerformAction`. +static auto PerformCallHelper(Context& context, SemIR::LocId loc_id, + SemIR::InstId callee_id, + llvm::ArrayRef arg_ids, + bool is_desugared) { // Try treating the callee as a function first. auto callee = GetCallee(context.sem_ir(), callee_id); CARBON_KIND_SWITCH(callee) { @@ -367,4 +387,35 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, } } +auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id, + llvm::ArrayRef arg_ids, bool is_desugared) + -> SemIR::InstId { + if (IsCallPerformable(context, callee_id, arg_ids)) { + return PerformCallHelper(context, loc_id, callee_id, arg_ids, is_desugared); + } + + // Pack the callee and args into an inst block. This is an optimization to + // avoid needing a Bundle in the `CallAction`. + llvm::SmallVector inst_ids; + inst_ids.reserve(1 + arg_ids.size()); + inst_ids.push_back(callee_id); + inst_ids.append(arg_ids.begin(), arg_ids.end()); + auto inst_block_id = context.inst_blocks().Add(inst_ids); + + return HandleAction( + context, loc_id, SemIR::TypeInstId::None, + {.type_id = SemIR::InstType::TypeId, + .inst_block_id = inst_block_id, + .is_desugared = SemIR::BoolValue::From(is_desugared)}); +} + +auto PerformAction(Context& context, SemIR::LocId loc_id, + SemIR::CallAction action) -> SemIR::InstId { + auto inst_ids = context.inst_blocks().Get(action.inst_block_id); + auto callee_id = inst_ids[0]; + auto arg_ids = inst_ids.slice(1); + return PerformCallHelper(context, loc_id, callee_id, arg_ids, + action.is_desugared.ToBool()); +} + } // namespace Carbon::Check diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 11c0e44c56c9..a2fa201a0986 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -579,6 +579,19 @@ static auto GetConstantValue(EvalContext& eval_context, return inst_id; } +static auto GetConstantValue(EvalContext& eval_context, + SemIR::MetaInstBlockId inst_block_id, Phase* phase) + -> SemIR::MetaInstBlockId { + auto inst_ids = eval_context.inst_blocks().Get(inst_block_id); + llvm::SmallVector new_inst_ids; + for (auto inst_id : inst_ids) { + new_inst_ids.push_back( + GetConstantValue(eval_context, SemIR::MetaInstId{inst_id}, phase)); + } + + return eval_context.inst_blocks().Add(new_inst_ids); +} + static auto GetConstantValue(EvalContext& eval_context, SemIR::TypeInstId inst_id, Phase* phase) -> SemIR::TypeInstId { @@ -1070,8 +1083,8 @@ template requires SemIR::Internal::IsIdKindType && SameAsOneOf + SemIR::MetaInstId, SemIR::MetaInstBlockId, + SemIR::StructTypeFieldsId, SemIR::TypeInstId> static auto ResolveSpecificDeclForArg(EvalContext& /*eval_context*/, IdT /*id*/) -> void { // These id types have a GetConstantValue() overload but that overload diff --git a/toolchain/check/testdata/array/init_dependent_bound.carbon b/toolchain/check/testdata/array/init_dependent_bound.carbon index 1cba38dd94cb..56a9ae1588ad 100644 --- a/toolchain/check/testdata/array/init_dependent_bound.carbon +++ b/toolchain/check/testdata/array/init_dependent_bound.carbon @@ -46,18 +46,21 @@ library "[[@TEST_NAME]]"; // TODO: This should be valid. fn G(template N: i32) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+8]]:35: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] + // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:35: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] // CHECK:STDERR: var unused arr: array(i32, N) = (1, 2, 3); // CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused arr: array(i32, N) = (1, 2, 3); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: var unused arr: array(i32, N) = (1, 2, 3); //@dump-sem-ir-end } +// CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE+7]]:10: error: unable to monomorphize specific `G(3)` [ResolvingSpecificHere] +// CHECK:STDERR: fn H() { G(3); } +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_todo_init_template_dependent_bound.carbon:[[@LINE-7]]:3: note: value of type `` is not callable [CallToNonCallable] +// CHECK:STDERR: var unused arr: array(i32, N) = (1, 2, 3); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fn H() { G(3); } @@ -180,7 +183,7 @@ fn H() { G(3); } // CHECK:STDOUT: %N.patt.38a: %pattern_type.6b6 = symbolic_binding_pattern N, 0, template [template] // CHECK:STDOUT: %N.37f: %i32 = symbolic_binding N, 0, template [template] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] -// CHECK:STDOUT: %.233: Core.IntLiteral = splice_inst @G.%.loc15_30.2 [template] +// CHECK:STDOUT: %.233: Core.IntLiteral = splice_inst @G.%.loc11_30.2 [template] // CHECK:STDOUT: %array_type.3cc: type = array_type %.233, %i32 [template] // CHECK:STDOUT: %require_complete.2bf: = require_complete_type %array_type.3cc [template] // CHECK:STDOUT: %pattern_type.ed3: type = pattern_type %array_type.3cc [template] @@ -197,8 +200,9 @@ fn H() { G(3); } // CHECK:STDOUT: %Destroy.WithSelf.Op.42b: %Destroy.WithSelf.Op.type.d3e = struct_value () [symbolic] // CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete] // CHECK:STDOUT: %assoc0.ae8: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete] -// CHECK:STDOUT: %.a09: %array_type.3cc = splice_inst @G.%.loc15_3.3 [template] -// CHECK:STDOUT: %.b71: @G.%.loc15_3.6 (@G.%.loc15_3.6) = splice_inst @G.%.loc15_3.5 [template] +// CHECK:STDOUT: %.a09: %array_type.3cc = splice_inst @G.%.loc11_3.4 [template] +// CHECK:STDOUT: %.b71: @G.%.loc11_3.7 (@G.%.loc11_3.7) = splice_inst @G.%.loc11_3.6 [template] +// CHECK:STDOUT: %.098: @G.%.loc11_3.10 (@G.%.loc11_3.10) = splice_inst @G.%.loc11_3.9 [template] // CHECK:STDOUT: %From: Core.IntLiteral = symbolic_binding From, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.7cb: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete] // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.type.48d: type = fn_type @Int.as.ImplicitAs.impl.Convert, @Int.as.ImplicitAs.impl(%From) [symbolic] @@ -231,7 +235,7 @@ fn H() { G(3); } // CHECK:STDOUT: %inst.as_compatible: = inst_value [concrete] { // CHECK:STDOUT: %.723: ref %array_type.dc7 = as_compatible @G.%arr.var // CHECK:STDOUT: } -// CHECK:STDOUT: %Destroy.Op.type.1d8f74.3: type = fn_type @Destroy.Op.loc15_3.3 [concrete] +// CHECK:STDOUT: %Destroy.Op.type.1d8f74.3: type = fn_type @Destroy.Op.loc11_3.3 [concrete] // CHECK:STDOUT: %Destroy.Op.1a2547.3: %Destroy.Op.type.1d8f74.3 = struct_value () [concrete] // CHECK:STDOUT: %custom_witness.df9cc1.3: = custom_witness (%Destroy.Op.1a2547.3), @Destroy [concrete] // CHECK:STDOUT: %Destroy.facet.9a9: %Destroy.type = facet_value %array_type.dc7, (%custom_witness.df9cc1.3) [concrete] @@ -243,6 +247,9 @@ fn H() { G(3); } // CHECK:STDOUT: %bound_method.69b: = bound_method %.723, %impl.elem0.ef2 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %inst.splice_block.edd: = inst_value [concrete] { +// CHECK:STDOUT: %.432: = splice_block [concrete = ] {} +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -255,52 +262,56 @@ fn H() { G(3); } // CHECK:STDOUT: // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc15_30.2: = convert_to_value_action %N.ref, Core.IntLiteral [template] -// CHECK:STDOUT: %.loc15_30.3: Core.IntLiteral = splice_inst %.loc15_30.2 [template = %.loc15_30.3 (constants.%.233)] -// CHECK:STDOUT: %array_type.loc15_31.2: type = array_type %.loc15_30.3, constants.%i32 [template = %array_type.loc15_31.2 (constants.%array_type.3cc)] -// CHECK:STDOUT: %require_complete: = require_complete_type %array_type.loc15_31.2 [template = %require_complete (constants.%require_complete.2bf)] -// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc15_31.2 [template = %pattern_type (constants.%pattern_type.ed3)] -// CHECK:STDOUT: %arr.patt.loc15_17.2: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc15_17.2 (constants.%arr.patt.515)] -// CHECK:STDOUT: %arr.var_patt.loc15_3.2: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc15_17.2 [template = %arr.var_patt.loc15_3.2 (constants.%arr.var_patt.821)] -// CHECK:STDOUT: %.loc15_3.3: = refine_type_action %arr.var, %array_type.loc15_31.2 [template] -// CHECK:STDOUT: %.loc15_3.4: @G.%array_type.loc15_31.2 (%array_type.3cc) = splice_inst %.loc15_3.3 [template = %.loc15_3.4 (constants.%.a09)] -// CHECK:STDOUT: %.loc15_3.5: = compound_member_access_action %.loc15_3.1, constants.%assoc0.ae8 [template] -// CHECK:STDOUT: %.loc15_3.6: type = type_of_inst %.loc15_3.5 [template] -// CHECK:STDOUT: %.loc15_3.7: @G.%.loc15_3.6 (@G.%.loc15_3.6) = splice_inst %.loc15_3.5 [template = %.loc15_3.7 (constants.%.b71)] +// CHECK:STDOUT: %.loc11_30.2: = convert_to_value_action %N.ref, Core.IntLiteral [template] +// CHECK:STDOUT: %.loc11_30.3: Core.IntLiteral = splice_inst %.loc11_30.2 [template = %.loc11_30.3 (constants.%.233)] +// CHECK:STDOUT: %array_type.loc11_31.2: type = array_type %.loc11_30.3, constants.%i32 [template = %array_type.loc11_31.2 (constants.%array_type.3cc)] +// CHECK:STDOUT: %require_complete: = require_complete_type %array_type.loc11_31.2 [template = %require_complete (constants.%require_complete.2bf)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc11_31.2 [template = %pattern_type (constants.%pattern_type.ed3)] +// CHECK:STDOUT: %arr.patt.loc11_17.2: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc11_17.2 (constants.%arr.patt.515)] +// CHECK:STDOUT: %arr.var_patt.loc11_3.2: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc11_17.2 [template = %arr.var_patt.loc11_3.2 (constants.%arr.var_patt.821)] +// CHECK:STDOUT: %.loc11_3.4: = refine_type_action %arr.var, %array_type.loc11_31.2 [template] +// CHECK:STDOUT: %.loc11_3.5: @G.%array_type.loc11_31.2 (%array_type.3cc) = splice_inst %.loc11_3.4 [template = %.loc11_3.5 (constants.%.a09)] +// CHECK:STDOUT: %.loc11_3.6: = compound_member_access_action %.loc11_3.1, constants.%assoc0.ae8 [template] +// CHECK:STDOUT: %.loc11_3.7: type = type_of_inst %.loc11_3.6 [template] +// CHECK:STDOUT: %.loc11_3.8: @G.%.loc11_3.7 (@G.%.loc11_3.7) = splice_inst %.loc11_3.6 [template = %.loc11_3.8 (constants.%.b71)] +// CHECK:STDOUT: %.loc11_3.9: = call_action (%.loc11_3.2), true [template] +// CHECK:STDOUT: %.loc11_3.10: type = type_of_inst %.loc11_3.9 [template] +// CHECK:STDOUT: %.loc11_3.11: @G.%.loc11_3.10 (@G.%.loc11_3.10) = splice_inst %.loc11_3.9 [template = %.loc11_3.11 (constants.%.098)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc15_31.2 (%array_type.3cc) = var_storage %arr.var_patt.loc15_3.1 +// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc11_31.2 (%array_type.3cc) = var_storage %arr.var_patt.loc11_3.1 // 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: %.loc15_43: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) [concrete = constants.%tuple] +// CHECK:STDOUT: %.loc11_43: %tuple.type = tuple_literal (%int_1, %int_2, %int_3) [concrete = constants.%tuple] // CHECK:STDOUT: assign %arr.var, -// CHECK:STDOUT: %.loc15_31: type = splice_block %array_type.loc15_31.1 [template = %array_type.loc15_31.2 (constants.%array_type.3cc)] { -// CHECK:STDOUT: %i32.loc15: type = type_literal constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: %.loc11_31: type = splice_block %array_type.loc11_31.1 [template = %array_type.loc11_31.2 (constants.%array_type.3cc)] { +// CHECK:STDOUT: %i32.loc11: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc5_16.2 [template = %N.loc5_16.1 (constants.%N.37f)] -// CHECK:STDOUT: %.loc15_30.1: Core.IntLiteral = splice_inst %.loc15_30.2 [template = %.loc15_30.3 (constants.%.233)] -// CHECK:STDOUT: %array_type.loc15_31.1: type = array_type %.loc15_30.1, %i32.loc15 [template = %array_type.loc15_31.2 (constants.%array_type.3cc)] +// CHECK:STDOUT: %.loc11_30.1: Core.IntLiteral = splice_inst %.loc11_30.2 [template = %.loc11_30.3 (constants.%.233)] +// CHECK:STDOUT: %array_type.loc11_31.1: type = array_type %.loc11_30.1, %i32.loc11 [template = %array_type.loc11_31.2 (constants.%array_type.3cc)] // CHECK:STDOUT: } -// CHECK:STDOUT: %arr: ref @G.%array_type.loc15_31.2 (%array_type.3cc) = wrapper_binding arr, %arr.var +// CHECK:STDOUT: %arr: ref @G.%array_type.loc11_31.2 (%array_type.3cc) = wrapper_binding arr, %arr.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %arr.patt.loc15_17.1: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc15_17.2 (constants.%arr.patt.515)] -// CHECK:STDOUT: %arr.var_patt.loc15_3.1: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc15_17.1 [template = %arr.var_patt.loc15_3.2 (constants.%arr.var_patt.821)] +// CHECK:STDOUT: %arr.patt.loc11_17.1: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc11_17.2 (constants.%arr.patt.515)] +// CHECK:STDOUT: %arr.var_patt.loc11_3.1: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc11_17.1 [template = %arr.var_patt.loc11_3.2 (constants.%arr.var_patt.821)] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc15_3.1: @G.%array_type.loc15_31.2 (%array_type.3cc) = splice_inst %.loc15_3.3 [template = %.loc15_3.4 (constants.%.a09)] -// CHECK:STDOUT: %.loc15_3.2: @G.%.loc15_3.6 (@G.%.loc15_3.6) = splice_inst %.loc15_3.5 [template = %.loc15_3.7 (constants.%.b71)] +// CHECK:STDOUT: %.loc11_3.1: @G.%array_type.loc11_31.2 (%array_type.3cc) = splice_inst %.loc11_3.4 [template = %.loc11_3.5 (constants.%.a09)] +// CHECK:STDOUT: %.loc11_3.2: @G.%.loc11_3.7 (@G.%.loc11_3.7) = splice_inst %.loc11_3.6 [template = %.loc11_3.8 (constants.%.b71)] +// CHECK:STDOUT: %.loc11_3.3: @G.%.loc11_3.10 (@G.%.loc11_3.10) = splice_inst %.loc11_3.9 [template = %.loc11_3.11 (constants.%.098)] // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc15_3.1(%self.param: ref %i32.builtin) = "no_op"; +// CHECK:STDOUT: fn @Destroy.Op.loc11_3.1(%self.param: ref %i32.builtin) = "no_op"; // CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc15_3.2(%self.param: ref %i32) { +// CHECK:STDOUT: fn @Destroy.Op.loc11_3.2(%self.param: ref %i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc15_3.3(%self.param: ref %array_type.dc7) { +// CHECK:STDOUT: fn @Destroy.Op.loc11_3.3(%self.param: ref %array_type.dc7) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -315,17 +326,20 @@ fn H() { G(3); } // CHECK:STDOUT: %N.loc5_16.1 => constants.%int_3.410 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc15_30.2 => constants.%inst.splice_block.ca0 -// CHECK:STDOUT: %.loc15_30.3 => constants.%int_3.1ba -// CHECK:STDOUT: %array_type.loc15_31.2 => constants.%array_type.dc7 +// CHECK:STDOUT: %.loc11_30.2 => constants.%inst.splice_block.ca0 +// CHECK:STDOUT: %.loc11_30.3 => constants.%int_3.1ba +// CHECK:STDOUT: %array_type.loc11_31.2 => constants.%array_type.dc7 // CHECK:STDOUT: %require_complete => constants.%complete_type.b77 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.771 -// CHECK:STDOUT: %arr.patt.loc15_17.2 => constants.%arr.patt.316 -// CHECK:STDOUT: %arr.var_patt.loc15_3.2 => constants.%arr.var_patt.c63 -// CHECK:STDOUT: %.loc15_3.3 => constants.%inst.as_compatible -// CHECK:STDOUT: %.loc15_3.4 => invalid -// CHECK:STDOUT: %.loc15_3.5 => constants.%inst.splice_block.adf -// CHECK:STDOUT: %.loc15_3.6 => -// CHECK:STDOUT: %.loc15_3.7 => invalid +// CHECK:STDOUT: %arr.patt.loc11_17.2 => constants.%arr.patt.316 +// CHECK:STDOUT: %arr.var_patt.loc11_3.2 => constants.%arr.var_patt.c63 +// CHECK:STDOUT: %.loc11_3.4 => constants.%inst.as_compatible +// CHECK:STDOUT: %.loc11_3.5 => invalid +// CHECK:STDOUT: %.loc11_3.6 => constants.%inst.splice_block.adf +// CHECK:STDOUT: %.loc11_3.7 => +// CHECK:STDOUT: %.loc11_3.8 => invalid +// CHECK:STDOUT: %.loc11_3.9 => constants.%inst.splice_block.edd +// CHECK:STDOUT: %.loc11_3.10 => +// CHECK:STDOUT: %.loc11_3.11 => // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/destroy_calls.carbon b/toolchain/check/testdata/class/destroy_calls.carbon index 1516c1656115..8e76b0a1d156 100644 --- a/toolchain/check/testdata/class/destroy_calls.carbon +++ b/toolchain/check/testdata/class/destroy_calls.carbon @@ -2,7 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/destroy.carbon +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon // // AUTOUPDATE // TIP: To test this file alone, run: @@ -93,14 +93,17 @@ class C(template T: type) {} //@dump-sem-ir-begin fn F(template T: type) { - // CHECK:STDERR: fail_todo_generic_use_inside_template.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: C(T) = {}; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: var unused v: C(T) = {}; } //@dump-sem-ir-end +// CHECK:STDERR: fail_todo_generic_use_inside_template.carbon:[[@LINE+7]]:10: error: unable to monomorphize specific `F({})` [ResolvingSpecificHere] +// CHECK:STDERR: fn G() { F({}); } +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_todo_generic_use_inside_template.carbon:[[@LINE-7]]:3: note: value of type `` is not callable [CallToNonCallable] +// CHECK:STDERR: var unused v: C(T) = {}; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fn G() { F({}); } // CHECK:STDOUT: --- implicit_return.carbon @@ -570,45 +573,80 @@ fn G() { F({}); } // CHECK:STDOUT: %T: type = symbolic_binding T, 0, template [template] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] -// CHECK:STDOUT: %C.1d0: type = class_type @C, @C(%T) [template] // 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: %require_complete: = require_complete_type %C.1d0 [template] -// CHECK:STDOUT: %pattern_type.ebe: type = pattern_type %C.1d0 [template] -// CHECK:STDOUT: %v.patt.f9d: %pattern_type.ebe = ref_binding_pattern v [template] -// CHECK:STDOUT: %v.var_patt.ca3: %pattern_type.ebe = var_pattern %v.patt.f9d [template] +// CHECK:STDOUT: %.d24: @F.%.loc7_20.5 (@F.%.loc7_20.5) = splice_inst @F.%.loc7_20.4 [template] +// CHECK:STDOUT: %.44c: type = splice_inst @F.%.loc7_20.7 [template] +// CHECK:STDOUT: %require_complete: = require_complete_type %.44c [template] +// CHECK:STDOUT: %pattern_type.c25: type = pattern_type %.44c [template] +// CHECK:STDOUT: %v.patt.0c8: %pattern_type.c25 = ref_binding_pattern v [template] +// CHECK:STDOUT: %v.var_patt.7d8: %pattern_type.c25 = var_pattern %v.patt.0c8 [template] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C.val.d4f: %C.1d0 = struct_value () [template] +// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.0ff = struct_value () [concrete] +// CHECK:STDOUT: %.d189f7.1: @F.%.loc7_3.12 (@F.%.loc7_3.12) = splice_inst @F.%.loc7_3.11 [template] +// CHECK:STDOUT: %.269993.1: @F.%.loc7_3.15 (@F.%.loc7_3.15) = splice_inst @F.%.loc7_3.14 [template] +// CHECK:STDOUT: %.0e8: @F.%.loc7_3.18 (@F.%.loc7_3.18) = splice_inst @F.%.loc7_3.17 [template] +// CHECK:STDOUT: %.820: @F.%.loc7_3.21 (@F.%.loc7_3.21) = splice_inst @F.%.loc7_3.20 [template] +// CHECK:STDOUT: %.a9b: %.44c = splice_inst @F.%.loc7_3.23 [template] +// CHECK:STDOUT: %.65c: %.44c = splice_inst @F.%.loc7_3.25 [template] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Self: %Destroy.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d3e: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Self) [symbolic] +// CHECK:STDOUT: %Self.0e7: %Destroy.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d3e: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Self.0e7) [symbolic] // CHECK:STDOUT: %Destroy.WithSelf.Op.42b: %Destroy.WithSelf.Op.type.d3e = struct_value () [symbolic] // CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete] -// CHECK:STDOUT: %assoc0: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete] -// CHECK:STDOUT: %.535: %C.1d0 = splice_inst @F.%.loc11_3.4 [template] -// CHECK:STDOUT: %.38b: @F.%.loc11_3.7 (@F.%.loc11_3.7) = splice_inst @F.%.loc11_3.6 [template] -// CHECK:STDOUT: %C.d8e: type = class_type @C, @C(%empty_struct_type) [concrete] -// CHECK:STDOUT: %pattern_type.2fd: type = pattern_type %C.d8e [concrete] +// CHECK:STDOUT: %assoc0.ae8: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete] +// CHECK:STDOUT: %.0d4: %.44c = splice_inst @F.%.loc7_3.27 [template] +// CHECK:STDOUT: %.e5e: @F.%.loc7_3.30 (@F.%.loc7_3.30) = splice_inst @F.%.loc7_3.29 [template] +// CHECK:STDOUT: %.d90: @F.%.loc7_3.33 (@F.%.loc7_3.33) = splice_inst @F.%.loc7_3.32 [template] +// CHECK:STDOUT: %C.d8efcc.1: type = class_type @C, @C(%empty_struct_type) [concrete] +// CHECK:STDOUT: %inst.class_type: = inst_value [concrete] { +// CHECK:STDOUT: %C.d8efcc.2: type = class_type @C, @C(%empty_struct_type) [concrete = %C.d8efcc.1] +// CHECK:STDOUT: } +// CHECK:STDOUT: %inst.splice_block.1b2: = inst_value [concrete] { +// CHECK:STDOUT: %.6eb: type = splice_block %C.d8efcc.1 [concrete = %C.d8efcc.1] {} +// CHECK:STDOUT: } +// CHECK:STDOUT: %pattern_type.2fd: type = pattern_type %C.d8efcc.1 [concrete] // CHECK:STDOUT: %v.patt.0e7: %pattern_type.2fd = ref_binding_pattern v [concrete] // CHECK:STDOUT: %v.var_patt.259: %pattern_type.2fd = var_pattern %v.patt.0e7 [concrete] -// CHECK:STDOUT: %C.val.58e: %C.d8e = struct_value () [concrete] -// CHECK:STDOUT: %inst.as_compatible: = inst_value [concrete] { -// CHECK:STDOUT: %.a67: ref %C.d8e = as_compatible @F.%v.var +// CHECK:STDOUT: %.690: = call_action (%ImplicitAs.generic, %.44c), false [template] +// CHECK:STDOUT: %.816: type = type_of_inst %.690 [template] +// CHECK:STDOUT: %.d189f7.2: %.816 = splice_inst %.690 [template] +// CHECK:STDOUT: %.7f1: = access_member_action %.d189f7.2, Convert [template] +// CHECK:STDOUT: %.d9e: type = type_of_inst %.7f1 [template] +// CHECK:STDOUT: %.269993.2: %.d9e = splice_inst %.7f1 [template] +// CHECK:STDOUT: %.190: = compound_member_access_action %empty_struct, %.269993.2 [template] +// CHECK:STDOUT: %.46e: type = type_of_inst %.190 [template] +// CHECK:STDOUT: %.27f: %.46e = splice_inst %.190 [template] +// CHECK:STDOUT: %.f03: = call_action (%.27f), true [template] +// CHECK:STDOUT: %.c52: type = type_of_inst %.f03 [template] +// CHECK:STDOUT: %.94d: %.c52 = splice_inst %.f03 [template] +// CHECK:STDOUT: %.2ea: %C.d8efcc.1 = splice_inst %.f03 [template] +// CHECK:STDOUT: %inst.as_compatible.be6: = inst_value [concrete] { +// CHECK:STDOUT: %.cda: %C.d8efcc.1 = as_compatible %.94d [template = %.2ea] // CHECK:STDOUT: } -// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc11_3.2 [concrete] +// CHECK:STDOUT: %.610: = convert_to_category_action %.2ea, element10 [template] +// CHECK:STDOUT: %.47a: %C.d8efcc.1 = splice_inst %.610 [template] +// CHECK:STDOUT: %inst.as_compatible.6fd: = inst_value [concrete] { +// CHECK:STDOUT: %.36e: ref %C.d8efcc.1 = as_compatible @F.%v.var +// CHECK:STDOUT: } +// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc7_3.2 [concrete] // CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete] // CHECK:STDOUT: %custom_witness.df9cc1.2: = custom_witness (%Destroy.Op.1a2547.2), @Destroy [concrete] -// CHECK:STDOUT: %Destroy.facet.da3: %Destroy.type = facet_value %C.d8e, (%custom_witness.df9cc1.2) [concrete] +// CHECK:STDOUT: %Destroy.facet.da3: %Destroy.type = facet_value %C.d8efcc.1, (%custom_witness.df9cc1.2) [concrete] // CHECK:STDOUT: %Destroy.WithSelf.Op.type.294: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet.da3) [concrete] // CHECK:STDOUT: %.98c: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.294, %Destroy.facet.da3 [concrete] -// CHECK:STDOUT: %inst.splice_block: = inst_value [concrete] { -// CHECK:STDOUT: %.136: = splice_block %bound_method { +// CHECK:STDOUT: %inst.splice_block.b81: = inst_value [concrete] { +// CHECK:STDOUT: %.99b: = splice_block %bound_method { // CHECK:STDOUT: %impl.elem0: %.98c = impl_witness_access %custom_witness.df9cc1.2, element0 [concrete = %Destroy.Op.1a2547.2] -// CHECK:STDOUT: %bound_method: = bound_method %.a67, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %.36e, %impl.elem0 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %inst.splice_block.edd: = inst_value [concrete] { +// CHECK:STDOUT: %.432: = splice_block [concrete = ] {} +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -632,44 +670,73 @@ fn G() { F({}); } // CHECK:STDOUT: %T.loc6_16.1: type = symbolic_binding T, 0, template [template = %T.loc6_16.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %C.loc11_20.2: type = class_type @C, @C(%T.loc6_16.1) [template = %C.loc11_20.2 (constants.%C.1d0)] -// CHECK:STDOUT: %require_complete: = require_complete_type %C.loc11_20.2 [template = %require_complete (constants.%require_complete)] -// CHECK:STDOUT: %pattern_type: type = pattern_type %C.loc11_20.2 [template = %pattern_type (constants.%pattern_type.ebe)] -// CHECK:STDOUT: %v.patt.loc11_15.2: @F.%pattern_type (%pattern_type.ebe) = ref_binding_pattern v [template = %v.patt.loc11_15.2 (constants.%v.patt.f9d)] -// CHECK:STDOUT: %v.var_patt.loc11_3.2: @F.%pattern_type (%pattern_type.ebe) = var_pattern %v.patt.loc11_15.2 [template = %v.var_patt.loc11_3.2 (constants.%v.var_patt.ca3)] -// CHECK:STDOUT: %C.val: @F.%C.loc11_20.2 (%C.1d0) = struct_value () [template = %C.val (constants.%C.val.d4f)] -// CHECK:STDOUT: %.loc11_3.4: = refine_type_action %v.var, %C.loc11_20.2 [template] -// CHECK:STDOUT: %.loc11_3.5: @F.%C.loc11_20.2 (%C.1d0) = splice_inst %.loc11_3.4 [template = %.loc11_3.5 (constants.%.535)] -// CHECK:STDOUT: %.loc11_3.6: = compound_member_access_action %.loc11_3.2, constants.%assoc0 [template] -// CHECK:STDOUT: %.loc11_3.7: type = type_of_inst %.loc11_3.6 [template] -// CHECK:STDOUT: %.loc11_3.8: @F.%.loc11_3.7 (@F.%.loc11_3.7) = splice_inst %.loc11_3.6 [template = %.loc11_3.8 (constants.%.38b)] +// CHECK:STDOUT: %.loc7_20.4: = call_action (%C.ref, %T.ref), false [template] +// CHECK:STDOUT: %.loc7_20.5: type = type_of_inst %.loc7_20.4 [template] +// CHECK:STDOUT: %.loc7_20.6: @F.%.loc7_20.5 (@F.%.loc7_20.5) = splice_inst %.loc7_20.4 [template = %.loc7_20.6 (constants.%.d24)] +// CHECK:STDOUT: %.loc7_20.7: = convert_to_value_action %.loc7_20.2, type [template] +// CHECK:STDOUT: %.loc7_20.8: type = splice_inst %.loc7_20.7 [template = %.loc7_20.8 (constants.%.44c)] +// CHECK:STDOUT: %require_complete: = require_complete_type %.loc7_20.8 [template = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %.loc7_20.8 [template = %pattern_type (constants.%pattern_type.c25)] +// CHECK:STDOUT: %v.patt.loc7_15.2: @F.%pattern_type (%pattern_type.c25) = ref_binding_pattern v [template = %v.patt.loc7_15.2 (constants.%v.patt.0c8)] +// CHECK:STDOUT: %v.var_patt.loc7_3.2: @F.%pattern_type (%pattern_type.c25) = var_pattern %v.patt.loc7_15.2 [template = %v.var_patt.loc7_3.2 (constants.%v.var_patt.7d8)] +// CHECK:STDOUT: %.loc7_3.11: = call_action (constants.%ImplicitAs.generic, constants.%.44c), false [template] +// CHECK:STDOUT: %.loc7_3.12: type = type_of_inst %.loc7_3.11 [template] +// CHECK:STDOUT: %.loc7_3.13: @F.%.loc7_3.12 (@F.%.loc7_3.12) = splice_inst %.loc7_3.11 [template = %.loc7_3.13 (constants.%.d189f7.1)] +// CHECK:STDOUT: %.loc7_3.14: = access_member_action %.loc7_3.1, Convert [template] +// CHECK:STDOUT: %.loc7_3.15: type = type_of_inst %.loc7_3.14 [template] +// CHECK:STDOUT: %.loc7_3.16: @F.%.loc7_3.15 (@F.%.loc7_3.15) = splice_inst %.loc7_3.14 [template = %.loc7_3.16 (constants.%.269993.1)] +// CHECK:STDOUT: %.loc7_3.17: = compound_member_access_action %.loc7_25, %.loc7_3.2 [template] +// CHECK:STDOUT: %.loc7_3.18: type = type_of_inst %.loc7_3.17 [template] +// CHECK:STDOUT: %.loc7_3.19: @F.%.loc7_3.18 (@F.%.loc7_3.18) = splice_inst %.loc7_3.17 [template = %.loc7_3.19 (constants.%.0e8)] +// CHECK:STDOUT: %.loc7_3.20: = call_action (%.loc7_3.3), true [template] +// CHECK:STDOUT: %.loc7_3.21: type = type_of_inst %.loc7_3.20 [template] +// CHECK:STDOUT: %.loc7_3.22: @F.%.loc7_3.21 (@F.%.loc7_3.21) = splice_inst %.loc7_3.20 [template = %.loc7_3.22 (constants.%.820)] +// CHECK:STDOUT: %.loc7_3.23: = refine_type_action %.loc7_3.5, %.loc7_20.8 [template] +// CHECK:STDOUT: %.loc7_3.24: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.23 [template = %.loc7_3.24 (constants.%.a9b)] +// CHECK:STDOUT: %.loc7_3.25: = convert_to_category_action %.loc7_3.6, element10 [template] +// CHECK:STDOUT: %.loc7_3.26: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.25 [template = %.loc7_3.26 (constants.%.65c)] +// CHECK:STDOUT: %.loc7_3.27: = refine_type_action %v.var, %.loc7_20.8 [template] +// CHECK:STDOUT: %.loc7_3.28: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.27 [template = %.loc7_3.28 (constants.%.0d4)] +// CHECK:STDOUT: %.loc7_3.29: = compound_member_access_action %.loc7_3.8, constants.%assoc0.ae8 [template] +// CHECK:STDOUT: %.loc7_3.30: type = type_of_inst %.loc7_3.29 [template] +// CHECK:STDOUT: %.loc7_3.31: @F.%.loc7_3.30 (@F.%.loc7_3.30) = splice_inst %.loc7_3.29 [template = %.loc7_3.31 (constants.%.e5e)] +// CHECK:STDOUT: %.loc7_3.32: = call_action (%.loc7_3.9), true [template] +// CHECK:STDOUT: %.loc7_3.33: type = type_of_inst %.loc7_3.32 [template] +// CHECK:STDOUT: %.loc7_3.34: @F.%.loc7_3.33 (@F.%.loc7_3.33) = splice_inst %.loc7_3.32 [template = %.loc7_3.34 (constants.%.d90)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %v.var: ref @F.%C.loc11_20.2 (%C.1d0) = var_storage %v.var_patt.loc11_3.1 -// CHECK:STDOUT: %.loc11_25.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc11_25.2: init @F.%C.loc11_20.2 (%C.1d0) to %v.var = class_init () [template = %C.val (constants.%C.val.d4f)] -// CHECK:STDOUT: %.loc11_3.1: init @F.%C.loc11_20.2 (%C.1d0) = converted %.loc11_25.1, %.loc11_25.2 [template = %C.val (constants.%C.val.d4f)] -// CHECK:STDOUT: assign %v.var, %.loc11_3.1 -// CHECK:STDOUT: %.loc11_20: type = splice_block %C.loc11_20.1 [template = %C.loc11_20.2 (constants.%C.1d0)] { +// CHECK:STDOUT: %v.var: ref @F.%.loc7_20.8 (%.44c) = var_storage %v.var_patt.loc7_3.1 +// CHECK:STDOUT: %.loc7_25: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc7_3.1: @F.%.loc7_3.12 (@F.%.loc7_3.12) = splice_inst %.loc7_3.11 [template = %.loc7_3.13 (constants.%.d189f7.1)] +// CHECK:STDOUT: %.loc7_3.2: @F.%.loc7_3.15 (@F.%.loc7_3.15) = splice_inst %.loc7_3.14 [template = %.loc7_3.16 (constants.%.269993.1)] +// CHECK:STDOUT: %.loc7_3.3: @F.%.loc7_3.18 (@F.%.loc7_3.18) = splice_inst %.loc7_3.17 [template = %.loc7_3.19 (constants.%.0e8)] +// CHECK:STDOUT: %.loc7_3.4: @F.%.loc7_3.21 (@F.%.loc7_3.21) = splice_inst %.loc7_3.20 [template = %.loc7_3.22 (constants.%.820)] +// CHECK:STDOUT: %.loc7_3.5: @F.%.loc7_20.8 (%.44c) = converted %.loc7_25, %.loc7_3.4 [template = %.loc7_3.22 (constants.%.820)] +// CHECK:STDOUT: %.loc7_3.6: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.23 [template = %.loc7_3.24 (constants.%.a9b)] +// CHECK:STDOUT: %.loc7_3.7: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.25 [template = %.loc7_3.26 (constants.%.65c)] +// CHECK:STDOUT: assign %v.var, %.loc7_3.7 +// CHECK:STDOUT: %.loc7_20.1: type = splice_block %.loc7_20.3 [template = %.loc7_20.8 (constants.%.44c)] { // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc6_16.2 [template = %T.loc6_16.1 (constants.%T)] -// CHECK:STDOUT: %C.loc11_20.1: type = class_type @C, @C(constants.%T) [template = %C.loc11_20.2 (constants.%C.1d0)] +// CHECK:STDOUT: %.loc7_20.2: @F.%.loc7_20.5 (@F.%.loc7_20.5) = splice_inst %.loc7_20.4 [template = %.loc7_20.6 (constants.%.d24)] +// CHECK:STDOUT: %.loc7_20.3: type = splice_inst %.loc7_20.7 [template = %.loc7_20.8 (constants.%.44c)] // CHECK:STDOUT: } -// CHECK:STDOUT: %v: ref @F.%C.loc11_20.2 (%C.1d0) = wrapper_binding v, %v.var +// CHECK:STDOUT: %v: ref @F.%.loc7_20.8 (%.44c) = wrapper_binding v, %v.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v.patt.loc11_15.1: @F.%pattern_type (%pattern_type.ebe) = ref_binding_pattern v [template = %v.patt.loc11_15.2 (constants.%v.patt.f9d)] -// CHECK:STDOUT: %v.var_patt.loc11_3.1: @F.%pattern_type (%pattern_type.ebe) = var_pattern %v.patt.loc11_15.1 [template = %v.var_patt.loc11_3.2 (constants.%v.var_patt.ca3)] +// CHECK:STDOUT: %v.patt.loc7_15.1: @F.%pattern_type (%pattern_type.c25) = ref_binding_pattern v [template = %v.patt.loc7_15.2 (constants.%v.patt.0c8)] +// CHECK:STDOUT: %v.var_patt.loc7_3.1: @F.%pattern_type (%pattern_type.c25) = var_pattern %v.patt.loc7_15.1 [template = %v.var_patt.loc7_3.2 (constants.%v.var_patt.7d8)] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc11_3.2: @F.%C.loc11_20.2 (%C.1d0) = splice_inst %.loc11_3.4 [template = %.loc11_3.5 (constants.%.535)] -// CHECK:STDOUT: %.loc11_3.3: @F.%.loc11_3.7 (@F.%.loc11_3.7) = splice_inst %.loc11_3.6 [template = %.loc11_3.8 (constants.%.38b)] +// CHECK:STDOUT: %.loc7_3.8: @F.%.loc7_20.8 (%.44c) = splice_inst %.loc7_3.27 [template = %.loc7_3.28 (constants.%.0d4)] +// CHECK:STDOUT: %.loc7_3.9: @F.%.loc7_3.30 (@F.%.loc7_3.30) = splice_inst %.loc7_3.29 [template = %.loc7_3.31 (constants.%.e5e)] +// CHECK:STDOUT: %.loc7_3.10: @F.%.loc7_3.33 (@F.%.loc7_3.33) = splice_inst %.loc7_3.32 [template = %.loc7_3.34 (constants.%.d90)] // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc11_3.1(%self.param: ref %empty_struct_type) = "no_op"; +// CHECK:STDOUT: fn @Destroy.Op.loc7_3.1(%self.param: ref %empty_struct_type) = "no_op"; // CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc11_3.2(%self.param: ref %C.d8e) { +// CHECK:STDOUT: fn @Destroy.Op.loc7_3.2(%self.param: ref %C.d8efcc.1) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -684,16 +751,38 @@ fn G() { F({}); } // CHECK:STDOUT: %T.loc6_16.1 => constants.%empty_struct_type // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %C.loc11_20.2 => constants.%C.d8e +// CHECK:STDOUT: %.loc7_20.4 => constants.%inst.class_type +// CHECK:STDOUT: %.loc7_20.5 => type +// CHECK:STDOUT: %.loc7_20.6 => constants.%C.d8efcc.1 +// CHECK:STDOUT: %.loc7_20.7 => constants.%inst.splice_block.1b2 +// CHECK:STDOUT: %.loc7_20.8 => constants.%C.d8efcc.1 // CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: %pattern_type => constants.%pattern_type.2fd -// CHECK:STDOUT: %v.patt.loc11_15.2 => constants.%v.patt.0e7 -// CHECK:STDOUT: %v.var_patt.loc11_3.2 => constants.%v.var_patt.259 -// CHECK:STDOUT: %C.val => constants.%C.val.58e -// CHECK:STDOUT: %.loc11_3.4 => constants.%inst.as_compatible -// CHECK:STDOUT: %.loc11_3.5 => invalid -// CHECK:STDOUT: %.loc11_3.6 => constants.%inst.splice_block -// CHECK:STDOUT: %.loc11_3.7 => -// CHECK:STDOUT: %.loc11_3.8 => invalid +// CHECK:STDOUT: %v.patt.loc7_15.2 => constants.%v.patt.0e7 +// CHECK:STDOUT: %v.var_patt.loc7_3.2 => constants.%v.var_patt.259 +// CHECK:STDOUT: %.loc7_3.11 => constants.%.690 +// CHECK:STDOUT: %.loc7_3.12 => constants.%.816 +// CHECK:STDOUT: %.loc7_3.13 => constants.%.d189f7.2 +// CHECK:STDOUT: %.loc7_3.14 => constants.%.7f1 +// CHECK:STDOUT: %.loc7_3.15 => constants.%.d9e +// CHECK:STDOUT: %.loc7_3.16 => constants.%.269993.2 +// CHECK:STDOUT: %.loc7_3.17 => constants.%.190 +// CHECK:STDOUT: %.loc7_3.18 => constants.%.46e +// CHECK:STDOUT: %.loc7_3.19 => constants.%.27f +// CHECK:STDOUT: %.loc7_3.20 => constants.%.f03 +// CHECK:STDOUT: %.loc7_3.21 => constants.%.c52 +// CHECK:STDOUT: %.loc7_3.22 => constants.%.94d +// CHECK:STDOUT: %.loc7_3.23 => constants.%inst.as_compatible.be6 +// CHECK:STDOUT: %.loc7_3.24 => constants.%.2ea +// CHECK:STDOUT: %.loc7_3.25 => constants.%.610 +// CHECK:STDOUT: %.loc7_3.26 => constants.%.47a +// CHECK:STDOUT: %.loc7_3.27 => constants.%inst.as_compatible.6fd +// CHECK:STDOUT: %.loc7_3.28 => invalid +// CHECK:STDOUT: %.loc7_3.29 => constants.%inst.splice_block.b81 +// CHECK:STDOUT: %.loc7_3.30 => +// CHECK:STDOUT: %.loc7_3.31 => invalid +// CHECK:STDOUT: %.loc7_3.32 => constants.%inst.splice_block.edd +// CHECK:STDOUT: %.loc7_3.33 => +// CHECK:STDOUT: %.loc7_3.34 => // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/eval/call.carbon b/toolchain/check/testdata/eval/call.carbon index dd3fbffd37e7..b801be53e85b 100644 --- a/toolchain/check/testdata/eval/call.carbon +++ b/toolchain/check/testdata/eval/call.carbon @@ -72,17 +72,20 @@ library "[[@TEST_NAME]]"; eval fn F(x: i32) -> i32 { return x; } fn G(generic N: i32) { - // CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+8]]:36: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] + // CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+4]]:36: error: cannot initialize array with dependent bound from a list of initializers [ArrayInitDependentBound] // CHECK:STDERR: var unused a: array(i32, F(N)) = (0, 1, 2); // CHECK:STDERR: ^~~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused a: array(i32, F(N)) = (0, 1, 2); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: var unused a: array(i32, F(N)) = (0, 1, 2); } +// CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE+7]]:10: error: unable to monomorphize specific `G(3)` [ResolvingSpecificHere] +// CHECK:STDERR: fn H() { G(3); } +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_todo_dependent_call.carbon:[[@LINE-6]]:3: note: value of type `` is not callable [CallToNonCallable] +// CHECK:STDERR: var unused a: array(i32, F(N)) = (0, 1, 2); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fn H() { G(3); } // --- fail_todo_dependent_call_type.carbon @@ -95,14 +98,6 @@ eval fn F(_: i32) -> type { } fn UseFGenerically(generic X: i32) { - // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+8]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: F(X) = {}; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: F(X) = {}; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: var unused v: F(X) = {}; } @@ -110,7 +105,7 @@ fn UseFSpecifically() { // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE+7]]:3: error: unable to monomorphize specific `UseFGenerically(3)` [ResolvingSpecificHere] // CHECK:STDERR: UseFGenerically(3); // CHECK:STDERR: ^~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE-7]]:3: note: cannot access member of interface `Core.ImplicitAs(C)` in type `{}` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_dependent_call_type.carbon:[[@LINE-7]]:3: note: value of type `` is not callable [CallToNonCallable] // CHECK:STDERR: var unused v: F(X) = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ // CHECK:STDERR: diff --git a/toolchain/check/testdata/generic/template/call.carbon b/toolchain/check/testdata/generic/template/call.carbon new file mode 100644 index 000000000000..4e30714562f5 --- /dev/null +++ b/toolchain/check/testdata/generic/template/call.carbon @@ -0,0 +1,50 @@ +// 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-FILE: toolchain/testing/testdata/min_prelude/none.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/generic/template/call.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/generic/template/call.carbon + +// --- fail_todo_dependent_call_nonconst_arg.carbon +library "[[@TEST_NAME]]"; + +class X {} +class Y {} +fn F[template G: type](H: G, x: X) { + H(x); +} +fn TakeX(unused x: X) {} + +// CHECK:STDERR: fail_todo_dependent_call_nonconst_arg.carbon:[[@LINE+7]]:23: error: expression cannot be used as a value [UseOfNonExprAsValue] +// CHECK:STDERR: fn GoodCall(x: X) { F(TakeX, x); } +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: fail_todo_dependent_call_nonconst_arg.carbon:[[@LINE-8]]:24: note: initializing function parameter [InCallToFunctionParam] +// CHECK:STDERR: fn F[template G: type](H: G, x: X) { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: +fn GoodCall(x: X) { F(TakeX, x); } + +// --- fail_dependent_call_nonconst_arg_wrong_type.carbon +library "[[@TEST_NAME]]"; + +class X {} +class Y {} +fn F[template G: type](H: G, x: X) { + H(x); +} +fn TakeY(unused y: Y) {} + +// TODO: should fail, but not because of UseOfNonExprAsValue +// CHECK:STDERR: fail_dependent_call_nonconst_arg_wrong_type.carbon:[[@LINE+7]]:22: error: expression cannot be used as a value [UseOfNonExprAsValue] +// CHECK:STDERR: fn BadCall(x: X) { F(TakeY, x); } +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: fail_dependent_call_nonconst_arg_wrong_type.carbon:[[@LINE-9]]:24: note: initializing function parameter [InCallToFunctionParam] +// CHECK:STDERR: fn F[template G: type](H: G, x: X) { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: +fn BadCall(x: X) { F(TakeY, x); } diff --git a/toolchain/check/testdata/generic/template/member_access.carbon b/toolchain/check/testdata/generic/template/member_access.carbon index 85e8f28511e3..6bb68d2ed174 100644 --- a/toolchain/check/testdata/generic/template/member_access.carbon +++ b/toolchain/check/testdata/generic/template/member_access.carbon @@ -95,10 +95,6 @@ base class C { //@dump-sem-ir-begin fn F[template T: type](x: T) -> i32 { - // CHECK:STDERR: fail_todo_compound_member_access.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: return x.(C.n); - // CHECK:STDERR: ^~~~~~~~~~~~~~~ - // CHECK:STDERR: return x.(C.n); } //@dump-sem-ir-end @@ -321,8 +317,8 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T [template] -// CHECK:STDOUT: %.b3e: %T = splice_inst @F.%.loc14_11.3 [template] -// CHECK:STDOUT: %.1a3: @F.%.loc14_11.6 (@F.%.loc14_11.6) = splice_inst @F.%.loc14_11.5 [template] +// CHECK:STDOUT: %.b3e: %T = splice_inst @F.%.loc10_11.3 [template] +// CHECK:STDOUT: %.1a3: @F.%.loc10_11.6 (@F.%.loc10_11.6) = splice_inst @F.%.loc10_11.5 [template] // CHECK:STDOUT: %Dest: type = symbolic_binding Dest, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.3aa: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic] // CHECK:STDOUT: %Self.294: %ImplicitAs.type.3aa = symbolic_binding Self, 1 [symbolic] @@ -330,7 +326,9 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.945: %ImplicitAs.WithSelf.Convert.type.97e = struct_value () [symbolic] // CHECK:STDOUT: %ImplicitAs.assoc_type.e23: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%i32) [concrete] // CHECK:STDOUT: %assoc0.368: %ImplicitAs.assoc_type.e23 = assoc_entity element0, imports.%Core.import_ref.cb2 [concrete] -// CHECK:STDOUT: %.d1c: @F.%.loc14_17.4 (@F.%.loc14_17.4) = splice_inst @F.%.loc14_17.3 [template] +// CHECK:STDOUT: %.d1c: @F.%.loc10_17.6 (@F.%.loc10_17.6) = splice_inst @F.%.loc10_17.5 [template] +// CHECK:STDOUT: %.521: @F.%.loc10_17.9 (@F.%.loc10_17.9) = splice_inst @F.%.loc10_17.8 [template] +// CHECK:STDOUT: %.eec: %i32 = splice_inst @F.%.loc10_17.11 [template] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %struct_type.base.085: type = struct_type {.base: %C} [concrete] // CHECK:STDOUT: %complete_type.756: = complete_type_witness %struct_type.base.085 [concrete] @@ -389,25 +387,32 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %T.loc9_16.1 [template = %require_complete (constants.%require_complete.944)] -// CHECK:STDOUT: %.loc14_11.3: = refine_type_action %x.ref, %T.loc9_16.1 [template] -// CHECK:STDOUT: %.loc14_11.4: @F.%T.loc9_16.1 (%T) = splice_inst %.loc14_11.3 [template = %.loc14_11.4 (constants.%.b3e)] -// CHECK:STDOUT: %.loc14_11.5: = compound_member_access_action %.loc14_11.1, %n.ref [template] -// CHECK:STDOUT: %.loc14_11.6: type = type_of_inst %.loc14_11.5 [template] -// CHECK:STDOUT: %.loc14_11.7: @F.%.loc14_11.6 (@F.%.loc14_11.6) = splice_inst %.loc14_11.5 [template = %.loc14_11.7 (constants.%.1a3)] -// CHECK:STDOUT: %.loc14_17.3: = compound_member_access_action %.loc14_11.2, constants.%assoc0.368 [template] -// CHECK:STDOUT: %.loc14_17.4: type = type_of_inst %.loc14_17.3 [template] -// CHECK:STDOUT: %.loc14_17.5: @F.%.loc14_17.4 (@F.%.loc14_17.4) = splice_inst %.loc14_17.3 [template = %.loc14_17.5 (constants.%.d1c)] +// CHECK:STDOUT: %.loc10_11.3: = refine_type_action %x.ref, %T.loc9_16.1 [template] +// CHECK:STDOUT: %.loc10_11.4: @F.%T.loc9_16.1 (%T) = splice_inst %.loc10_11.3 [template = %.loc10_11.4 (constants.%.b3e)] +// CHECK:STDOUT: %.loc10_11.5: = compound_member_access_action %.loc10_11.1, %n.ref [template] +// CHECK:STDOUT: %.loc10_11.6: type = type_of_inst %.loc10_11.5 [template] +// CHECK:STDOUT: %.loc10_11.7: @F.%.loc10_11.6 (@F.%.loc10_11.6) = splice_inst %.loc10_11.5 [template = %.loc10_11.7 (constants.%.1a3)] +// CHECK:STDOUT: %.loc10_17.5: = compound_member_access_action %.loc10_11.2, constants.%assoc0.368 [template] +// CHECK:STDOUT: %.loc10_17.6: type = type_of_inst %.loc10_17.5 [template] +// CHECK:STDOUT: %.loc10_17.7: @F.%.loc10_17.6 (@F.%.loc10_17.6) = splice_inst %.loc10_17.5 [template = %.loc10_17.7 (constants.%.d1c)] +// CHECK:STDOUT: %.loc10_17.8: = call_action (%.loc10_17.1), true [template] +// CHECK:STDOUT: %.loc10_17.9: type = type_of_inst %.loc10_17.8 [template] +// CHECK:STDOUT: %.loc10_17.10: @F.%.loc10_17.9 (@F.%.loc10_17.9) = splice_inst %.loc10_17.8 [template = %.loc10_17.10 (constants.%.521)] +// CHECK:STDOUT: %.loc10_17.11: = convert_to_category_action %.loc10_17.3, element10 [template] +// CHECK:STDOUT: %.loc10_17.12: %i32 = splice_inst %.loc10_17.11 [template = %.loc10_17.12 (constants.%.eec)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%x.param: @F.%T.loc9_16.1 (%T)) -> out %return.param: %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @F.%T.loc9_16.1 (%T) = name_ref x, %x // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %n.ref: %C.elem = name_ref n, @C.%.loc5 [concrete = @C.%.loc5] -// CHECK:STDOUT: %.loc14_11.1: @F.%T.loc9_16.1 (%T) = splice_inst %.loc14_11.3 [template = %.loc14_11.4 (constants.%.b3e)] -// CHECK:STDOUT: %.loc14_11.2: @F.%.loc14_11.6 (@F.%.loc14_11.6) = splice_inst %.loc14_11.5 [template = %.loc14_11.7 (constants.%.1a3)] -// CHECK:STDOUT: %.loc14_17.1: @F.%.loc14_17.4 (@F.%.loc14_17.4) = splice_inst %.loc14_17.3 [template = %.loc14_17.5 (constants.%.d1c)] -// CHECK:STDOUT: %.loc14_17.2: %i32 = converted %.loc14_11.2, [concrete = ] -// CHECK:STDOUT: return +// CHECK:STDOUT: %.loc10_11.1: @F.%T.loc9_16.1 (%T) = splice_inst %.loc10_11.3 [template = %.loc10_11.4 (constants.%.b3e)] +// CHECK:STDOUT: %.loc10_11.2: @F.%.loc10_11.6 (@F.%.loc10_11.6) = splice_inst %.loc10_11.5 [template = %.loc10_11.7 (constants.%.1a3)] +// CHECK:STDOUT: %.loc10_17.1: @F.%.loc10_17.6 (@F.%.loc10_17.6) = splice_inst %.loc10_17.5 [template = %.loc10_17.7 (constants.%.d1c)] +// CHECK:STDOUT: %.loc10_17.2: @F.%.loc10_17.9 (@F.%.loc10_17.9) = splice_inst %.loc10_17.8 [template = %.loc10_17.10 (constants.%.521)] +// CHECK:STDOUT: %.loc10_17.3: %i32 = converted %.loc10_11.2, %.loc10_17.2 [template = %.loc10_17.10 (constants.%.521)] +// CHECK:STDOUT: %.loc10_17.4: %i32 = splice_inst %.loc10_17.11 [template = %.loc10_17.12 (constants.%.eec)] +// CHECK:STDOUT: return %.loc10_17.4 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -428,13 +433,18 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type.756 -// CHECK:STDOUT: %.loc14_11.3 => constants.%inst.as_compatible -// CHECK:STDOUT: %.loc14_11.4 => invalid -// CHECK:STDOUT: %.loc14_11.5 => constants.%inst.splice_block.08b -// CHECK:STDOUT: %.loc14_11.6 => constants.%i32 -// CHECK:STDOUT: %.loc14_11.7 => invalid -// CHECK:STDOUT: %.loc14_17.3 => constants.%inst.splice_block.edd -// CHECK:STDOUT: %.loc14_17.4 => -// CHECK:STDOUT: %.loc14_17.5 => +// CHECK:STDOUT: %.loc10_11.3 => constants.%inst.as_compatible +// CHECK:STDOUT: %.loc10_11.4 => invalid +// CHECK:STDOUT: %.loc10_11.5 => constants.%inst.splice_block.08b +// CHECK:STDOUT: %.loc10_11.6 => constants.%i32 +// CHECK:STDOUT: %.loc10_11.7 => invalid +// CHECK:STDOUT: %.loc10_17.5 => constants.%inst.splice_block.edd +// CHECK:STDOUT: %.loc10_17.6 => +// CHECK:STDOUT: %.loc10_17.7 => +// CHECK:STDOUT: %.loc10_17.8 => +// CHECK:STDOUT: %.loc10_17.9 => +// CHECK:STDOUT: %.loc10_17.10 => +// CHECK:STDOUT: %.loc10_17.11 => +// CHECK:STDOUT: %.loc10_17.12 => // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/template/unimplemented.carbon b/toolchain/check/testdata/generic/template/unimplemented.carbon index 26ede84f93c0..babbe8a2508f 100644 --- a/toolchain/check/testdata/generic/template/unimplemented.carbon +++ b/toolchain/check/testdata/generic/template/unimplemented.carbon @@ -18,12 +18,12 @@ library "[[@TEST_NAME]]"; // Check that we get a reasonable diagnostic for an unimplemented operation on a // template dependent expression. -fn F[template T: type](x: T) -> i32 { - // CHECK:STDERR: fail_todo_unimplemented_operator.carbon:[[@LINE+4]]:10: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: return x.n * 3; - // CHECK:STDERR: ^~~~~~~ +fn F[template T: type](x: T) { + // CHECK:STDERR: fail_todo_unimplemented_operator.carbon:[[@LINE+4]]:3: error: cannot dereference operand of non-pointer type `` [DerefOfNonPointer] + // CHECK:STDERR: *x.n; + // CHECK:STDERR: ^ // CHECK:STDERR: - return x.n * 3; + *x.n; } // --- fail_todo_unimplemented_value.carbon @@ -37,37 +37,14 @@ class C { // Check that we get a reasonable diagnostic for an unimplemented operation on a // template dependent value where the type is concrete but determined through // the template dependent value. -fn F(template c: C) -> i32 { - // CHECK:STDERR: fail_todo_unimplemented_value.carbon:[[@LINE+4]]:10: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: return c.n * 3; - // CHECK:STDERR: ^~~~~~~ +fn F(template c: C) { + // CHECK:STDERR: fail_todo_unimplemented_value.carbon:[[@LINE+4]]:3: error: cannot dereference operand of non-pointer type `` [DerefOfNonPointer] + // CHECK:STDERR: *c.n; + // CHECK:STDERR: ^ // CHECK:STDERR: - return c.n * 3; + *c.n; } -// --- fail_todo_unimplemented_convert.carbon - -library "[[@TEST_NAME]]"; - -fn F[template T: Core.Destroy](x: T) { - // TODO: These diagnostics aren't very good, and we should only produce one error here. - // CHECK:STDERR: fail_todo_unimplemented_convert.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: T = 0; - // CHECK:STDERR: ^~~~~~~~~~~~~~~ - // CHECK:STDERR: - var unused v: T = 0; - // CHECK:STDERR: fail_todo_unimplemented_convert.carbon:[[@LINE+8]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused w: i32 = x; - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_unimplemented_convert.carbon:[[@LINE-5]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: T = 0; - // CHECK:STDERR: ^~~~~~~~~~~~~~~ - // CHECK:STDERR: - var unused w: i32 = x; -} - - // CHECK:STDOUT: --- fail_todo_unimplemented_operator.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -76,40 +53,23 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template] // CHECK:STDOUT: %T: type = symbolic_binding T, 0, template [template] -// CHECK:STDOUT: %pattern_type.51d1c4.1: type = pattern_type %T [template] -// CHECK:STDOUT: %x.param_patt: %pattern_type.51d1c4.1 = value_param_pattern [template] -// CHECK:STDOUT: %x.patt: %pattern_type.51d1c4.1 = wrapper_binding_pattern x, %x.param_patt [template] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] -// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] -// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %.795: Core.Form = init_form %i32 [concrete] -// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete] -// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete] +// CHECK:STDOUT: %pattern_type.51d: type = pattern_type %T [template] +// CHECK:STDOUT: %x.param_patt: %pattern_type.51d = value_param_pattern [template] +// CHECK:STDOUT: %x.patt: %pattern_type.51d = wrapper_binding_pattern x, %x.param_patt [template] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T [template] -// CHECK:STDOUT: %.b3e: %T = splice_inst @F.%.loc11_11.3 [template] -// CHECK:STDOUT: %.432: @F.%.loc11_11.6 (@F.%.loc11_11.6) = splice_inst @F.%.loc11_11.5 [template] -// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete] -// CHECK:STDOUT: %MulWith.type.9f9: type = generic_interface_type @MulWith [concrete] -// CHECK:STDOUT: %MulWith.generic: %MulWith.type.9f9 = struct_value () [concrete] -// CHECK:STDOUT: %MulWith.assoc_type.4dd: type = assoc_entity_type @MulWith, @MulWith(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %assoc1.37c: %MulWith.assoc_type.4dd = assoc_entity element1, imports.%Core.import_ref.9555a9.1 [concrete] -// CHECK:STDOUT: %.b64: @F.%.loc11_14.3 (@F.%.loc11_14.3) = splice_inst @F.%.loc11_14.2 [template] +// CHECK:STDOUT: %.b3e: %T = splice_inst @F.%.loc11_5.4 [template] +// CHECK:STDOUT: %.432: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst @F.%.loc11_5.6 [template] +// CHECK:STDOUT: %require_complete.681: = require_complete_type @F.%.loc11_5.7 [template] +// CHECK:STDOUT: %.263: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst @F.%.loc11_5.9 [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .MulWith = %Core.MulWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] -// CHECK:STDOUT: %Core.MulWith: %MulWith.type.9f9 = import_ref Core//prelude/operators/arithmetic, MulWith, loaded [concrete = constants.%MulWith.generic] -// CHECK:STDOUT: %Core.import_ref.9555a9.1 = import_ref Core//prelude/operators/arithmetic, loc{{\d+_\d+}}, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -120,13 +80,9 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc6_16.1: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc6_16.2 (constants.%T.patt)] -// CHECK:STDOUT: %x.param_patt.loc6_25.1: @F.%pattern_type (%pattern_type.51d1c4.1) = value_param_pattern [template = %x.param_patt.loc6_25.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc6_25.1: @F.%pattern_type (%pattern_type.51d1c4.1) = wrapper_binding_pattern x, %x.param_patt.loc6_25.1 [template = %x.patt.loc6_25.2 (constants.%x.patt)] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32 [concrete = constants.%return.patt.e1b] +// CHECK:STDOUT: %x.param_patt.loc6_25.1: @F.%pattern_type (%pattern_type.51d) = value_param_pattern [template = %x.param_patt.loc6_25.2 (constants.%x.param_patt)] +// CHECK:STDOUT: %x.patt.loc6_25.1: @F.%pattern_type (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc6_25.1 [template = %x.patt.loc6_25.2 (constants.%x.patt)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc6_33: Core.Form = init_form %i32 [concrete = constants.%.795] // CHECK:STDOUT: %.loc6_18.1: type = splice_block %.loc6_18.2 [concrete = type] { // CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] // CHECK:STDOUT: %.loc6_18.2: type = type_literal type [concrete = type] @@ -135,44 +91,42 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %x.param: @F.%T.loc6_16.1 (%T) = value_param call_param0 // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc6_16.2 [template = %T.loc6_16.1 (constants.%T)] // CHECK:STDOUT: %x: @F.%T.loc6_16.1 (%T) = wrapper_binding x, %x.param -// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 -// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_16.2: type) { // CHECK:STDOUT: %T.patt.loc6_16.2: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc6_16.2 (constants.%T.patt)] // CHECK:STDOUT: %T.loc6_16.1: type = symbolic_binding T, 0, template [template = %T.loc6_16.1 (constants.%T)] -// CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc6_16.1 [template = %pattern_type (constants.%pattern_type.51d1c4.1)] -// CHECK:STDOUT: %x.param_patt.loc6_25.2: @F.%pattern_type (%pattern_type.51d1c4.1) = value_param_pattern [template = %x.param_patt.loc6_25.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc6_25.2: @F.%pattern_type (%pattern_type.51d1c4.1) = wrapper_binding_pattern x, %x.param_patt.loc6_25.2 [template = %x.patt.loc6_25.2 (constants.%x.patt)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc6_16.1 [template = %pattern_type (constants.%pattern_type.51d)] +// CHECK:STDOUT: %x.param_patt.loc6_25.2: @F.%pattern_type (%pattern_type.51d) = value_param_pattern [template = %x.param_patt.loc6_25.2 (constants.%x.param_patt)] +// CHECK:STDOUT: %x.patt.loc6_25.2: @F.%pattern_type (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc6_25.2 [template = %x.patt.loc6_25.2 (constants.%x.patt)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %T.loc6_16.1 [template = %require_complete (constants.%require_complete.944)] -// CHECK:STDOUT: %.loc11_11.3: = refine_type_action %x.ref, %T.loc6_16.1 [template] -// CHECK:STDOUT: %.loc11_11.4: @F.%T.loc6_16.1 (%T) = splice_inst %.loc11_11.3 [template = %.loc11_11.4 (constants.%.b3e)] -// CHECK:STDOUT: %.loc11_11.5: = access_member_action %.loc11_11.1, n [template] -// CHECK:STDOUT: %.loc11_11.6: type = type_of_inst %.loc11_11.5 [template] -// CHECK:STDOUT: %.loc11_11.7: @F.%.loc11_11.6 (@F.%.loc11_11.6) = splice_inst %.loc11_11.5 [template = %.loc11_11.7 (constants.%.432)] -// CHECK:STDOUT: %.loc11_14.2: = compound_member_access_action %.loc11_11.2, constants.%assoc1.37c [template] -// CHECK:STDOUT: %.loc11_14.3: type = type_of_inst %.loc11_14.2 [template] -// CHECK:STDOUT: %.loc11_14.4: @F.%.loc11_14.3 (@F.%.loc11_14.3) = splice_inst %.loc11_14.2 [template = %.loc11_14.4 (constants.%.b64)] +// CHECK:STDOUT: %require_complete.loc6: = require_complete_type %T.loc6_16.1 [template = %require_complete.loc6 (constants.%require_complete.944)] +// CHECK:STDOUT: %.loc11_5.4: = refine_type_action %x.ref, %T.loc6_16.1 [template] +// CHECK:STDOUT: %.loc11_5.5: @F.%T.loc6_16.1 (%T) = splice_inst %.loc11_5.4 [template = %.loc11_5.5 (constants.%.b3e)] +// CHECK:STDOUT: %.loc11_5.6: = access_member_action %.loc11_5.1, n [template] +// CHECK:STDOUT: %.loc11_5.7: type = type_of_inst %.loc11_5.6 [template] +// CHECK:STDOUT: %.loc11_5.8: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst %.loc11_5.6 [template = %.loc11_5.8 (constants.%.432)] +// CHECK:STDOUT: %require_complete.loc11: = require_complete_type %.loc11_5.7 [template = %require_complete.loc11 (constants.%require_complete.681)] +// CHECK:STDOUT: %.loc11_5.9: = convert_to_category_action %.loc11_5.2, element1 [template] +// CHECK:STDOUT: %.loc11_5.10: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst %.loc11_5.9 [template = %.loc11_5.10 (constants.%.263)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param: @F.%T.loc6_16.1 (%T)) -> out %return.param: %i32 { +// CHECK:STDOUT: fn(%x.param: @F.%T.loc6_16.1 (%T)) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @F.%T.loc6_16.1 (%T) = name_ref x, %x -// CHECK:STDOUT: %.loc11_11.1: @F.%T.loc6_16.1 (%T) = splice_inst %.loc11_11.3 [template = %.loc11_11.4 (constants.%.b3e)] -// CHECK:STDOUT: %.loc11_11.2: @F.%.loc11_11.6 (@F.%.loc11_11.6) = splice_inst %.loc11_11.5 [template = %.loc11_11.7 (constants.%.432)] -// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc11_14.1: @F.%.loc11_14.3 (@F.%.loc11_14.3) = splice_inst %.loc11_14.2 [template = %.loc11_14.4 (constants.%.b64)] -// CHECK:STDOUT: return +// CHECK:STDOUT: %.loc11_5.1: @F.%T.loc6_16.1 (%T) = splice_inst %.loc11_5.4 [template = %.loc11_5.5 (constants.%.b3e)] +// CHECK:STDOUT: %.loc11_5.2: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst %.loc11_5.6 [template = %.loc11_5.8 (constants.%.432)] +// CHECK:STDOUT: %.loc11_5.3: @F.%.loc11_5.7 (@F.%.loc11_5.7) = splice_inst %.loc11_5.9 [template = %.loc11_5.10 (constants.%.263)] +// CHECK:STDOUT: %.loc11_3: ref = deref %.loc11_5.3 [concrete = ] +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.patt.loc6_16.2 => constants.%T.patt // CHECK:STDOUT: %T.loc6_16.1 => constants.%T -// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d1c4.1 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d // CHECK:STDOUT: %x.param_patt.loc6_25.2 => constants.%x.param_patt // CHECK:STDOUT: %x.patt.loc6_25.2 => constants.%x.patt // CHECK:STDOUT: } @@ -185,7 +139,6 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.cdf: = complete_type_witness %struct_type.n [concrete] @@ -194,30 +147,20 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete] // CHECK:STDOUT: %c.patt: %pattern_type.98b = symbolic_binding_pattern c, 0, template [template] // CHECK:STDOUT: %c: %C = symbolic_binding c, 0, template [template] -// CHECK:STDOUT: %.795: Core.Form = init_form %i32 [concrete] -// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete] -// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %.26f: @F.%.loc16_11.3 (@F.%.loc16_11.3) = splice_inst @F.%.loc16_11.2 [template] -// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete] -// CHECK:STDOUT: %MulWith.type.9f9: type = generic_interface_type @MulWith [concrete] -// CHECK:STDOUT: %MulWith.generic: %MulWith.type.9f9 = struct_value () [concrete] -// CHECK:STDOUT: %MulWith.assoc_type.4dd: type = assoc_entity_type @MulWith, @MulWith(Core.IntLiteral) [concrete] -// CHECK:STDOUT: %assoc1.37c: %MulWith.assoc_type.4dd = assoc_entity element1, imports.%Core.import_ref.9555a9.1 [concrete] -// CHECK:STDOUT: %.a77: @F.%.loc16_14.3 (@F.%.loc16_14.3) = splice_inst @F.%.loc16_14.2 [template] +// CHECK:STDOUT: %.26f: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst @F.%.loc16_5.3 [template] +// CHECK:STDOUT: %require_complete.519: = require_complete_type @F.%.loc16_5.4 [template] +// CHECK:STDOUT: %.2d8: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst @F.%.loc16_5.6 [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .MulWith = %Core.MulWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] -// CHECK:STDOUT: %Core.MulWith: %MulWith.type.9f9 = import_ref Core//prelude/operators/arithmetic, MulWith, loaded [concrete = constants.%MulWith.generic] -// CHECK:STDOUT: %Core.import_ref.9555a9.1 = import_ref Core//prelude/operators/arithmetic, loc{{\d+_\d+}}, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -230,18 +173,12 @@ fn F[template T: Core.Destroy](x: T) { // 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: %c.patt.loc11_16.1: %pattern_type.98b = symbolic_binding_pattern c, 0, template [template = %c.patt.loc11_16.2 (constants.%c.patt)] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32 [concrete = constants.%return.patt.e1b] // CHECK:STDOUT: } { -// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc11_24: Core.Form = init_form %i32 [concrete = constants.%.795] -// CHECK:STDOUT: %.loc11_18: type = splice_block %C.ref [concrete = constants.%C] { +// CHECK:STDOUT: %.loc11: type = splice_block %C.ref [concrete = constants.%C] { // CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: } // CHECK:STDOUT: %c.loc11_16.2: %C = symbolic_binding c, 0, template [template = %c.loc11_16.1 (constants.%c)] -// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 -// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -260,20 +197,20 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %c.loc11_16.1: %C = symbolic_binding c, 0, template [template = %c.loc11_16.1 (constants.%c)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc16_11.2: = access_member_action %c.ref, n [template] -// CHECK:STDOUT: %.loc16_11.3: type = type_of_inst %.loc16_11.2 [template] -// CHECK:STDOUT: %.loc16_11.4: @F.%.loc16_11.3 (@F.%.loc16_11.3) = splice_inst %.loc16_11.2 [template = %.loc16_11.4 (constants.%.26f)] -// CHECK:STDOUT: %.loc16_14.2: = compound_member_access_action %.loc16_11.1, constants.%assoc1.37c [template] -// CHECK:STDOUT: %.loc16_14.3: type = type_of_inst %.loc16_14.2 [template] -// CHECK:STDOUT: %.loc16_14.4: @F.%.loc16_14.3 (@F.%.loc16_14.3) = splice_inst %.loc16_14.2 [template = %.loc16_14.4 (constants.%.a77)] +// CHECK:STDOUT: %.loc16_5.3: = access_member_action %c.ref, n [template] +// CHECK:STDOUT: %.loc16_5.4: type = type_of_inst %.loc16_5.3 [template] +// CHECK:STDOUT: %.loc16_5.5: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst %.loc16_5.3 [template = %.loc16_5.5 (constants.%.26f)] +// CHECK:STDOUT: %require_complete: = require_complete_type %.loc16_5.4 [template = %require_complete (constants.%require_complete.519)] +// CHECK:STDOUT: %.loc16_5.6: = convert_to_category_action %.loc16_5.1, element1 [template] +// CHECK:STDOUT: %.loc16_5.7: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst %.loc16_5.6 [template = %.loc16_5.7 (constants.%.2d8)] // CHECK:STDOUT: -// CHECK:STDOUT: fn() -> out %return.param: %i32 { +// CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %C = name_ref c, %c.loc11_16.2 [template = %c.loc11_16.1 (constants.%c)] -// CHECK:STDOUT: %.loc16_11.1: @F.%.loc16_11.3 (@F.%.loc16_11.3) = splice_inst %.loc16_11.2 [template = %.loc16_11.4 (constants.%.26f)] -// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc16_14.1: @F.%.loc16_14.3 (@F.%.loc16_14.3) = splice_inst %.loc16_14.2 [template = %.loc16_14.4 (constants.%.a77)] -// CHECK:STDOUT: return +// CHECK:STDOUT: %.loc16_5.1: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst %.loc16_5.3 [template = %.loc16_5.5 (constants.%.26f)] +// CHECK:STDOUT: %.loc16_5.2: @F.%.loc16_5.4 (@F.%.loc16_5.4) = splice_inst %.loc16_5.6 [template = %.loc16_5.7 (constants.%.2d8)] +// CHECK:STDOUT: %.loc16_3: ref = deref %.loc16_5.2 [concrete = ] +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -282,178 +219,3 @@ fn F[template T: Core.Destroy](x: T) { // CHECK:STDOUT: %c.loc11_16.1 => constants.%c // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_unimplemented_convert.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Self.0e7: %Destroy.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d3e: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Self.0e7) [symbolic] -// CHECK:STDOUT: %Destroy.WithSelf.Op.42b: %Destroy.WithSelf.Op.type.d3e = struct_value () [symbolic] -// CHECK:STDOUT: %pattern_type.429: type = pattern_type %Destroy.type [concrete] -// CHECK:STDOUT: %T.patt: %pattern_type.429 = symbolic_binding_pattern T, 0, template [template] -// CHECK:STDOUT: %T: %Destroy.type = symbolic_binding T, 0, template [template] -// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [template] -// CHECK:STDOUT: %pattern_type.f4e485.2: type = pattern_type %T.as_type [template] -// CHECK:STDOUT: %x.param_patt: %pattern_type.f4e485.2 = value_param_pattern [template] -// CHECK:STDOUT: %x.patt: %pattern_type.f4e485.2 = wrapper_binding_pattern x, %x.param_patt [template] -// 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: %require_complete.14c: = require_complete_type %T.as_type [template] -// CHECK:STDOUT: %v.patt: %pattern_type.f4e485.2 = ref_binding_pattern v [template] -// CHECK:STDOUT: %v.var_patt: %pattern_type.f4e485.2 = var_pattern %v.patt [template] -// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] -// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete] -// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.0ff = struct_value () [concrete] -// CHECK:STDOUT: %ImplicitAs.type.f42: type = facet_type <@ImplicitAs, @ImplicitAs(%T.as_type)> [template] -// CHECK:STDOUT: %.d48: @F.%.loc10_3.7 (@F.%.loc10_3.7) = splice_inst @F.%.loc10_3.6 [template] -// CHECK:STDOUT: %.e0a: @F.%.loc10_3.10 (@F.%.loc10_3.10) = splice_inst @F.%.loc10_3.9 [template] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] -// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] -// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] -// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %w.patt: %pattern_type.6b6 = ref_binding_pattern w [concrete] -// CHECK:STDOUT: %w.var_patt: %pattern_type.6b6 = var_pattern %w.patt [concrete] -// CHECK:STDOUT: %ImplicitAs.assoc_type.e23: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %assoc0.e1a: %ImplicitAs.assoc_type.e23 = assoc_entity element0, imports.%Core.import_ref.f9d913.1 [concrete] -// CHECK:STDOUT: %.75e: %T.as_type = splice_inst @F.%.loc19_3.4 [template] -// CHECK:STDOUT: %.2f2: @F.%.loc19_3.7 (@F.%.loc19_3.7) = splice_inst @F.%.loc19_3.6 [template] -// CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete] -// CHECK:STDOUT: %assoc0.ae8: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete] -// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc19_3.2 [concrete] -// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete] -// CHECK:STDOUT: %.407: %T.as_type = splice_inst @F.%.loc10_3.12 [template] -// CHECK:STDOUT: %.026: @F.%.loc10_3.15 (@F.%.loc10_3.15) = splice_inst @F.%.loc10_3.14 [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Destroy = %Core.Destroy -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: import Core//prelude -// CHECK:STDOUT: import Core//prelude/... -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] -// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.0ff = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.f9d913.1 = import_ref Core//prelude/operators/as, loc{{\d+_\d+}}, unloaded -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] -// CHECK:STDOUT: %Core.import_ref.918: @Destroy.WithSelf.%Destroy.WithSelf.Op.type (%Destroy.WithSelf.Op.type.d3e) = import_ref Core//prelude/destroy, loc{{\d+_\d+}}, loaded [symbolic = @Destroy.WithSelf.%Destroy.WithSelf.Op (constants.%Destroy.WithSelf.Op.42b)] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %T.patt.loc4_16.1: %pattern_type.429 = symbolic_binding_pattern T, 0, template [template = %T.patt.loc4_16.2 (constants.%T.patt)] -// CHECK:STDOUT: %x.param_patt.loc4_33.1: @F.%pattern_type (%pattern_type.f4e485.2) = value_param_pattern [template = %x.param_patt.loc4_33.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc4_33.1: @F.%pattern_type (%pattern_type.f4e485.2) = wrapper_binding_pattern x, %x.param_patt.loc4_33.1 [template = %x.patt.loc4_33.2 (constants.%x.patt)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc4_22: type = splice_block %Destroy.ref [concrete = constants.%Destroy.type] { -// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] -// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] -// CHECK:STDOUT: %Destroy.ref: type = name_ref Destroy, imports.%Core.Destroy [concrete = constants.%Destroy.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %T.loc4_16.2: %Destroy.type = symbolic_binding T, 0, template [template = %T.loc4_16.1 (constants.%T)] -// CHECK:STDOUT: %x.param: @F.%T.as_type.loc4_35.1 (%T.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc4_35.1: type = splice_block %.loc4_35.2 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] { -// CHECK:STDOUT: %T.ref.loc4: %Destroy.type = name_ref T, %T.loc4_16.2 [template = %T.loc4_16.1 (constants.%T)] -// CHECK:STDOUT: %T.as_type.loc4_35.2: type = facet_access_type %T.ref.loc4 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] -// CHECK:STDOUT: %.loc4_35.2: type = converted %T.ref.loc4, %T.as_type.loc4_35.2 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %x: @F.%T.as_type.loc4_35.1 (%T.as_type) = wrapper_binding x, %x.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F(%T.loc4_16.2: %Destroy.type) { -// CHECK:STDOUT: %T.patt.loc4_16.2: %pattern_type.429 = symbolic_binding_pattern T, 0, template [template = %T.patt.loc4_16.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.loc4_16.1: %Destroy.type = symbolic_binding T, 0, template [template = %T.loc4_16.1 (constants.%T)] -// CHECK:STDOUT: %T.as_type.loc4_35.1: type = facet_access_type %T.loc4_16.1 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] -// CHECK:STDOUT: %pattern_type: type = pattern_type %T.as_type.loc4_35.1 [template = %pattern_type (constants.%pattern_type.f4e485.2)] -// CHECK:STDOUT: %x.param_patt.loc4_33.2: @F.%pattern_type (%pattern_type.f4e485.2) = value_param_pattern [template = %x.param_patt.loc4_33.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc4_33.2: @F.%pattern_type (%pattern_type.f4e485.2) = wrapper_binding_pattern x, %x.param_patt.loc4_33.2 [template = %x.patt.loc4_33.2 (constants.%x.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type.loc4_35.1 [template = %require_complete (constants.%require_complete.14c)] -// CHECK:STDOUT: %v.patt.loc10_15.2: @F.%pattern_type (%pattern_type.f4e485.2) = ref_binding_pattern v [template = %v.patt.loc10_15.2 (constants.%v.patt)] -// CHECK:STDOUT: %v.var_patt.loc10_3.2: @F.%pattern_type (%pattern_type.f4e485.2) = var_pattern %v.patt.loc10_15.2 [template = %v.var_patt.loc10_3.2 (constants.%v.var_patt)] -// CHECK:STDOUT: %ImplicitAs.type.loc10_3.2: type = facet_type <@ImplicitAs, @ImplicitAs(%T.as_type.loc4_35.1)> [template = %ImplicitAs.type.loc10_3.2 (constants.%ImplicitAs.type.f42)] -// CHECK:STDOUT: %.loc10_3.6: = access_member_action %ImplicitAs.type.loc10_3.1, Convert [template] -// CHECK:STDOUT: %.loc10_3.7: type = type_of_inst %.loc10_3.6 [template] -// CHECK:STDOUT: %.loc10_3.8: @F.%.loc10_3.7 (@F.%.loc10_3.7) = splice_inst %.loc10_3.6 [template = %.loc10_3.8 (constants.%.d48)] -// CHECK:STDOUT: %.loc10_3.9: = compound_member_access_action %int_0, %.loc10_3.1 [template] -// CHECK:STDOUT: %.loc10_3.10: type = type_of_inst %.loc10_3.9 [template] -// CHECK:STDOUT: %.loc10_3.11: @F.%.loc10_3.10 (@F.%.loc10_3.10) = splice_inst %.loc10_3.9 [template = %.loc10_3.11 (constants.%.e0a)] -// CHECK:STDOUT: %.loc19_3.4: = refine_type_action %x.ref, %T.as_type.loc4_35.1 [template] -// CHECK:STDOUT: %.loc19_3.5: @F.%T.as_type.loc4_35.1 (%T.as_type) = splice_inst %.loc19_3.4 [template = %.loc19_3.5 (constants.%.75e)] -// CHECK:STDOUT: %.loc19_3.6: = compound_member_access_action %.loc19_3.1, constants.%assoc0.e1a [template] -// CHECK:STDOUT: %.loc19_3.7: type = type_of_inst %.loc19_3.6 [template] -// CHECK:STDOUT: %.loc19_3.8: @F.%.loc19_3.7 (@F.%.loc19_3.7) = splice_inst %.loc19_3.6 [template = %.loc19_3.8 (constants.%.2f2)] -// CHECK:STDOUT: %.loc10_3.12: = refine_type_action %v.var, %T.as_type.loc4_35.1 [template] -// CHECK:STDOUT: %.loc10_3.13: @F.%T.as_type.loc4_35.1 (%T.as_type) = splice_inst %.loc10_3.12 [template = %.loc10_3.13 (constants.%.407)] -// CHECK:STDOUT: %.loc10_3.14: = compound_member_access_action %.loc10_3.4, constants.%assoc0.ae8 [template] -// CHECK:STDOUT: %.loc10_3.15: type = type_of_inst %.loc10_3.14 [template] -// CHECK:STDOUT: %.loc10_3.16: @F.%.loc10_3.15 (@F.%.loc10_3.15) = splice_inst %.loc10_3.14 [template = %.loc10_3.16 (constants.%.026)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param: @F.%T.as_type.loc4_35.1 (%T.as_type)) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %v.var: ref @F.%T.as_type.loc4_35.1 (%T.as_type) = var_storage %v.var_patt.loc10_3.1 -// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] -// CHECK:STDOUT: %ImplicitAs.type.loc10_3.1: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%T.as_type)> [template = %ImplicitAs.type.loc10_3.2 (constants.%ImplicitAs.type.f42)] -// CHECK:STDOUT: %.loc10_3.1: @F.%.loc10_3.7 (@F.%.loc10_3.7) = splice_inst %.loc10_3.6 [template = %.loc10_3.8 (constants.%.d48)] -// CHECK:STDOUT: %.loc10_3.2: @F.%.loc10_3.10 (@F.%.loc10_3.10) = splice_inst %.loc10_3.9 [template = %.loc10_3.11 (constants.%.e0a)] -// CHECK:STDOUT: %.loc10_3.3: @F.%T.as_type.loc4_35.1 (%T.as_type) = converted %int_0, [concrete = ] -// CHECK:STDOUT: assign %v.var, -// CHECK:STDOUT: %.loc10_17.1: type = splice_block %.loc10_17.2 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] { -// CHECK:STDOUT: %T.ref.loc10: %Destroy.type = name_ref T, %T.loc4_16.2 [template = %T.loc4_16.1 (constants.%T)] -// CHECK:STDOUT: %T.as_type.loc10: type = facet_access_type %T.ref.loc10 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] -// CHECK:STDOUT: %.loc10_17.2: type = converted %T.ref.loc10, %T.as_type.loc10 [template = %T.as_type.loc4_35.1 (constants.%T.as_type)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %v: ref @F.%T.as_type.loc4_35.1 (%T.as_type) = wrapper_binding v, %v.var -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v.patt.loc10_15.1: @F.%pattern_type (%pattern_type.f4e485.2) = ref_binding_pattern v [template = %v.patt.loc10_15.2 (constants.%v.patt)] -// CHECK:STDOUT: %v.var_patt.loc10_3.1: @F.%pattern_type (%pattern_type.f4e485.2) = var_pattern %v.patt.loc10_15.1 [template = %v.var_patt.loc10_3.2 (constants.%v.var_patt)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %w.var: ref %i32 = var_storage %w.var_patt -// CHECK:STDOUT: %x.ref: @F.%T.as_type.loc4_35.1 (%T.as_type) = name_ref x, %x -// CHECK:STDOUT: %.loc19_3.1: @F.%T.as_type.loc4_35.1 (%T.as_type) = splice_inst %.loc19_3.4 [template = %.loc19_3.5 (constants.%.75e)] -// CHECK:STDOUT: %.loc19_3.2: @F.%.loc19_3.7 (@F.%.loc19_3.7) = splice_inst %.loc19_3.6 [template = %.loc19_3.8 (constants.%.2f2)] -// CHECK:STDOUT: %.loc19_3.3: %i32 = converted %x.ref, [concrete = ] -// CHECK:STDOUT: assign %w.var, -// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %w: ref %i32 = wrapper_binding w, %w.var -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %w.patt: %pattern_type.6b6 = ref_binding_pattern w [concrete = constants.%w.patt] -// CHECK:STDOUT: %w.var_patt: %pattern_type.6b6 = var_pattern %w.patt [concrete = constants.%w.var_patt] -// CHECK:STDOUT: } -// CHECK:STDOUT: %Destroy.Op.bound: = bound_method %w.var, constants.%Destroy.Op.1a2547.2 -// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%w.var) -// CHECK:STDOUT: %.loc10_3.4: @F.%T.as_type.loc4_35.1 (%T.as_type) = splice_inst %.loc10_3.12 [template = %.loc10_3.13 (constants.%.407)] -// CHECK:STDOUT: %.loc10_3.5: @F.%.loc10_3.15 (@F.%.loc10_3.15) = splice_inst %.loc10_3.14 [template = %.loc10_3.16 (constants.%.026)] -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc19_3.1(%self.param: ref %i32.builtin) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @Destroy.Op.loc19_3.2(%self.param: ref %i32) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%T) { -// CHECK:STDOUT: %T.patt.loc4_16.2 => constants.%T.patt -// CHECK:STDOUT: %T.loc4_16.1 => constants.%T -// CHECK:STDOUT: %T.as_type.loc4_35.1 => constants.%T.as_type -// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f4e485.2 -// CHECK:STDOUT: %x.param_patt.loc4_33.2 => constants.%x.param_patt -// CHECK:STDOUT: %x.patt.loc4_33.2 => constants.%x.patt -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/template_dependence.carbon b/toolchain/check/testdata/generic/template_dependence.carbon index fe51209c2d9f..1514dfc0b64a 100644 --- a/toolchain/check/testdata/generic/template_dependence.carbon +++ b/toolchain/check/testdata/generic/template_dependence.carbon @@ -16,11 +16,18 @@ library "[[@TEST_NAME]]"; //@dump-sem-ir-begin fn F[template T: type](x: T**) -> T* { - // CHECK:STDERR: fail_todo_type.carbon:[[@LINE+4]]:10: error: value of type `` is not callable [CallToNonCallable] + return *x; +} + +fn G(x: ()**) -> ()* { + // CHECK:STDERR: fail_todo_type.carbon:[[@LINE+7]]:10: error: unable to monomorphize specific `F(())` [ResolvingSpecificHere] + // CHECK:STDERR: return F(x); + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_todo_type.carbon:[[@LINE-7]]:10: note: value of type `` is not callable [CallToNonCallable] // CHECK:STDERR: return *x; // CHECK:STDERR: ^~ // CHECK:STDERR: - return *x; + return F(x); } //@dump-sem-ir-end @@ -41,106 +48,216 @@ fn F(template T: type, generic U: type) -> (T, U) { // CHECK:STDOUT: %type: type = facet_type [concrete] // CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] -// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template] -// CHECK:STDOUT: %T: type = symbolic_binding T, 0, template [template] -// CHECK:STDOUT: %ptr.e8f: type = ptr_type %T [template] -// CHECK:STDOUT: %ptr.125: type = ptr_type %ptr.e8f [template] +// CHECK:STDOUT: %T.patt.d47011.1: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template] +// CHECK:STDOUT: %T.67db0b.1: type = symbolic_binding T, 0, template [template] +// CHECK:STDOUT: %ptr.e8f8f9.1: type = ptr_type %T.67db0b.1 [template] +// CHECK:STDOUT: %ptr.125: type = ptr_type %ptr.e8f8f9.1 [template] // CHECK:STDOUT: %pattern_type.8bb: type = pattern_type %ptr.125 [template] -// CHECK:STDOUT: %x.param_patt: %pattern_type.8bb = value_param_pattern [template] -// CHECK:STDOUT: %x.patt: %pattern_type.8bb = wrapper_binding_pattern x, %x.param_patt [template] -// CHECK:STDOUT: %.cb6: Core.Form = init_form %ptr.e8f [template] -// CHECK:STDOUT: %pattern_type.4f4: type = pattern_type %ptr.e8f [template] -// CHECK:STDOUT: %return.param_patt.27f: %pattern_type.4f4 = out_param_pattern [template] -// CHECK:STDOUT: %return.patt.d67: %pattern_type.4f4 = return_slot_pattern %return.param_patt.27f, %ptr.e8f [template] +// CHECK:STDOUT: %x.param_patt.381: %pattern_type.8bb = value_param_pattern [template] +// CHECK:STDOUT: %x.patt.165: %pattern_type.8bb = wrapper_binding_pattern x, %x.param_patt.381 [template] +// CHECK:STDOUT: %.cb6cb9.1: Core.Form = init_form %ptr.e8f8f9.1 [template] +// CHECK:STDOUT: %pattern_type.4f4b84.1: type = pattern_type %ptr.e8f8f9.1 [template] +// CHECK:STDOUT: %return.param_patt.27f587.1: %pattern_type.4f4b84.1 = out_param_pattern [template] +// CHECK:STDOUT: %return.patt.d67: %pattern_type.4f4b84.1 = return_slot_pattern %return.param_patt.27f587.1, %ptr.e8f8f9.1 [template] // 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: %require_complete.fbe: = require_complete_type %ptr.125 [template] -// CHECK:STDOUT: %require_complete.ef1: = require_complete_type %ptr.e8f [template] +// CHECK:STDOUT: %require_complete.ef162c.1: = require_complete_type %ptr.e8f8f9.1 [template] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Self: %Copy.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Copy.WithSelf.Op.type.c85f21.1: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Self) [symbolic] +// CHECK:STDOUT: %Copy.WithSelf.Op.b85212.1: %Copy.WithSelf.Op.type.c85f21.1 = struct_value () [symbolic] // CHECK:STDOUT: %Copy.assoc_type: type = assoc_entity_type @Copy [concrete] -// CHECK:STDOUT: %assoc0: %Copy.assoc_type = assoc_entity element0, imports.%Core.import_ref.098 [concrete] -// CHECK:STDOUT: %.f57: %ptr.e8f = splice_inst @F.%.loc10_10.5 [template] -// CHECK:STDOUT: %.7cf: @F.%.loc10_10.8 (@F.%.loc10_10.8) = splice_inst @F.%.loc10_10.7 [template] +// CHECK:STDOUT: %assoc0: %Copy.assoc_type = assoc_entity element0, imports.%Core.import_ref.b5f [concrete] +// CHECK:STDOUT: %.f57: %ptr.e8f8f9.1 = splice_inst @F.%.loc6_10.6 [template] +// CHECK:STDOUT: %.5d1: @F.%.loc6_10.9 (@F.%.loc6_10.9) = splice_inst @F.%.loc6_10.8 [template] +// CHECK:STDOUT: %.c4d: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst @F.%.loc6_10.11 [template] +// CHECK:STDOUT: %.993: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst @F.%.loc6_12.2 [template] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %ptr.843: type = ptr_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %ptr.74f: type = ptr_type %ptr.843 [concrete] +// CHECK:STDOUT: %pattern_type.9ff: type = pattern_type %ptr.74f [concrete] +// CHECK:STDOUT: %x.param_patt.a10: %pattern_type.9ff = value_param_pattern [concrete] +// CHECK:STDOUT: %x.patt.d10: %pattern_type.9ff = wrapper_binding_pattern x, %x.param_patt.a10 [concrete] +// CHECK:STDOUT: %.4ba: Core.Form = init_form %ptr.843 [concrete] +// CHECK:STDOUT: %pattern_type.d64: type = pattern_type %ptr.843 [concrete] +// CHECK:STDOUT: %return.param_patt.e3f: %pattern_type.d64 = out_param_pattern [concrete] +// CHECK:STDOUT: %return.patt.d4e: %pattern_type.d64 = return_slot_pattern %return.param_patt.e3f, %ptr.843 [concrete] +// CHECK:STDOUT: %G.type: type = fn_type @G [concrete] +// CHECK:STDOUT: %G: %G.type = struct_value () [concrete] +// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%empty_tuple.type) [concrete] +// CHECK:STDOUT: %complete_type.2f1: = complete_type_witness %ptr.74f [concrete] +// CHECK:STDOUT: %complete_type.2ab: = complete_type_witness %ptr.843 [concrete] +// CHECK:STDOUT: %inst.as_compatible: = inst_value [concrete] { +// CHECK:STDOUT: %.34a: %ptr.843 = as_compatible @F.%.loc6_10.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.67db0b.2: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.ff5: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67db0b.2) [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.ce9: %ptr.as.Copy.impl.Op.type.ff5 = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.5e7: = impl_witness imports.%Copy.impl_witness_table.fb0, @ptr.as.Copy.impl(%empty_tuple.type) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.995: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%empty_tuple.type) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.ee1: %ptr.as.Copy.impl.Op.type.995 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.843, (%Copy.impl_witness.5e7) [concrete] +// CHECK:STDOUT: %Copy.WithSelf.Op.type.9ea: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete] +// CHECK:STDOUT: %.b77: type = fn_type_with_self_type %Copy.WithSelf.Op.type.9ea, %Copy.facet [concrete] +// CHECK:STDOUT: %inst.splice_block.64f: = inst_value [concrete] { +// CHECK:STDOUT: %.aaa: = splice_block %bound_method { +// CHECK:STDOUT: %impl.elem0.227: %.b77 = impl_witness_access %Copy.impl_witness.5e7, element0 [concrete = %ptr.as.Copy.impl.Op.ee1] +// CHECK:STDOUT: %bound_method: = bound_method %.34a, %impl.elem0.227 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %inst.splice_block.edd: = inst_value [concrete] { +// CHECK:STDOUT: %.432: = splice_block [concrete = ] {} +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core.import_ref.098 = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.b5f: @Copy.WithSelf.%Copy.WithSelf.Op.type (%Copy.WithSelf.Op.type.c85f21.1) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @Copy.WithSelf.%Copy.WithSelf.Op (constants.%Copy.WithSelf.Op.b85212.1)] +// CHECK:STDOUT: %Core.import_ref.e5f: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.ff5) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.ce9)] +// CHECK:STDOUT: %Copy.impl_witness_table.fb0 = impl_witness_table (%Core.import_ref.e5f), @ptr.as.Copy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %T.patt.loc5_16.1: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc5_16.2 (constants.%T.patt)] -// CHECK:STDOUT: %x.param_patt.loc5_25.1: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = value_param_pattern [template = %x.param_patt.loc5_25.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc5_25.1: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = wrapper_binding_pattern x, %x.param_patt.loc5_25.1 [template = %x.patt.loc5_25.2 (constants.%x.patt)] -// CHECK:STDOUT: %return.param_patt.loc5_36.1: @F.%pattern_type.loc5_36 (%pattern_type.4f4) = out_param_pattern [template = %return.param_patt.loc5_36.2 (constants.%return.param_patt.27f)] -// CHECK:STDOUT: %return.patt.loc5_32.1: @F.%pattern_type.loc5_36 (%pattern_type.4f4) = return_slot_pattern %return.param_patt.loc5_36.1, %ptr.loc5_36 [template = %return.patt.loc5_32.2 (constants.%return.patt.d67)] +// CHECK:STDOUT: %T.patt.loc5_16.1: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc5_16.2 (constants.%T.patt.d47011.1)] +// CHECK:STDOUT: %x.param_patt.loc5_25.1: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = value_param_pattern [template = %x.param_patt.loc5_25.2 (constants.%x.param_patt.381)] +// CHECK:STDOUT: %x.patt.loc5_25.1: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = wrapper_binding_pattern x, %x.param_patt.loc5_25.1 [template = %x.patt.loc5_25.2 (constants.%x.patt.165)] +// CHECK:STDOUT: %return.param_patt.loc5_36.1: @F.%pattern_type.loc5_36 (%pattern_type.4f4b84.1) = out_param_pattern [template = %return.param_patt.loc5_36.2 (constants.%return.param_patt.27f587.1)] +// CHECK:STDOUT: %return.patt.loc5_32.1: @F.%pattern_type.loc5_36 (%pattern_type.4f4b84.1) = return_slot_pattern %return.param_patt.loc5_36.1, %ptr.loc5_36 [template = %return.patt.loc5_32.2 (constants.%return.patt.d67)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %T.ref.loc5_35: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T)] -// CHECK:STDOUT: %ptr.loc5_36: type = ptr_type %T.ref.loc5_35 [template = %ptr.loc5_28.1 (constants.%ptr.e8f)] -// CHECK:STDOUT: %.loc5_36.2: Core.Form = init_form %ptr.loc5_36 [template = %.loc5_36.1 (constants.%.cb6)] +// CHECK:STDOUT: %T.ref.loc5_35: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T.67db0b.1)] +// CHECK:STDOUT: %ptr.loc5_36: type = ptr_type %T.ref.loc5_35 [template = %ptr.loc5_28.1 (constants.%ptr.e8f8f9.1)] +// CHECK:STDOUT: %.loc5_36.2: Core.Form = init_form %ptr.loc5_36 [template = %.loc5_36.1 (constants.%.cb6cb9.1)] // CHECK:STDOUT: %.loc5_18.1: type = splice_block %.loc5_18.2 [concrete = type] { // CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] // CHECK:STDOUT: %.loc5_18.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } -// CHECK:STDOUT: %T.loc5_16.2: type = symbolic_binding T, 0, template [template = %T.loc5_16.1 (constants.%T)] +// CHECK:STDOUT: %T.loc5_16.2: type = symbolic_binding T, 0, template [template = %T.loc5_16.1 (constants.%T.67db0b.1)] // CHECK:STDOUT: %x.param: @F.%ptr.loc5_29.1 (%ptr.125) = value_param call_param0 // CHECK:STDOUT: %.loc5_29: type = splice_block %ptr.loc5_29.2 [template = %ptr.loc5_29.1 (constants.%ptr.125)] { -// CHECK:STDOUT: %T.ref.loc5_27: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T)] -// CHECK:STDOUT: %ptr.loc5_28.2: type = ptr_type %T.ref.loc5_27 [template = %ptr.loc5_28.1 (constants.%ptr.e8f)] +// CHECK:STDOUT: %T.ref.loc5_27: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T.67db0b.1)] +// CHECK:STDOUT: %ptr.loc5_28.2: type = ptr_type %T.ref.loc5_27 [template = %ptr.loc5_28.1 (constants.%ptr.e8f8f9.1)] // CHECK:STDOUT: %ptr.loc5_29.2: type = ptr_type %ptr.loc5_28.2 [template = %ptr.loc5_29.1 (constants.%ptr.125)] // CHECK:STDOUT: } // CHECK:STDOUT: %x: @F.%ptr.loc5_29.1 (%ptr.125) = wrapper_binding x, %x.param -// CHECK:STDOUT: %return.param: ref @F.%ptr.loc5_28.1 (%ptr.e8f) = out_param call_param1 -// CHECK:STDOUT: %return: ref @F.%ptr.loc5_28.1 (%ptr.e8f) = return_slot %return.param +// CHECK:STDOUT: %return.param: ref @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = out_param call_param1 +// CHECK:STDOUT: %return: ref @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { +// CHECK:STDOUT: %x.param_patt: %pattern_type.9ff = value_param_pattern [concrete = constants.%x.param_patt.a10] +// CHECK:STDOUT: %x.patt: %pattern_type.9ff = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt.d10] +// CHECK:STDOUT: %return.param_patt: %pattern_type.d64 = out_param_pattern [concrete = constants.%return.param_patt.e3f] +// CHECK:STDOUT: %return.patt: %pattern_type.d64 = return_slot_pattern %return.param_patt, %ptr.loc9_20 [concrete = constants.%return.patt.d4e] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc9_19: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc9_20.1: type = converted %.loc9_19, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %ptr.loc9_20: type = ptr_type %.loc9_20.1 [concrete = constants.%ptr.843] +// CHECK:STDOUT: %.loc9_20.2: Core.Form = init_form %ptr.loc9_20 [concrete = constants.%.4ba] +// CHECK:STDOUT: %x.param: %ptr.74f = value_param call_param0 +// CHECK:STDOUT: %.loc9_12: type = splice_block %ptr.loc9_12 [concrete = constants.%ptr.74f] { +// CHECK:STDOUT: %.loc9_10: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc9_11: type = converted %.loc9_10, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %ptr.loc9_11: type = ptr_type %.loc9_11 [concrete = constants.%ptr.843] +// CHECK:STDOUT: %ptr.loc9_12: type = ptr_type %ptr.loc9_11 [concrete = constants.%ptr.74f] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: %ptr.74f = wrapper_binding x, %x.param +// CHECK:STDOUT: %return.param: ref %ptr.843 = out_param call_param1 +// CHECK:STDOUT: %return: ref %ptr.843 = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc5_16.2: type) { -// CHECK:STDOUT: %T.patt.loc5_16.2: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc5_16.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.loc5_16.1: type = symbolic_binding T, 0, template [template = %T.loc5_16.1 (constants.%T)] -// CHECK:STDOUT: %ptr.loc5_28.1: type = ptr_type %T.loc5_16.1 [template = %ptr.loc5_28.1 (constants.%ptr.e8f)] +// CHECK:STDOUT: %T.patt.loc5_16.2: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc5_16.2 (constants.%T.patt.d47011.1)] +// CHECK:STDOUT: %T.loc5_16.1: type = symbolic_binding T, 0, template [template = %T.loc5_16.1 (constants.%T.67db0b.1)] +// CHECK:STDOUT: %ptr.loc5_28.1: type = ptr_type %T.loc5_16.1 [template = %ptr.loc5_28.1 (constants.%ptr.e8f8f9.1)] // CHECK:STDOUT: %ptr.loc5_29.1: type = ptr_type %ptr.loc5_28.1 [template = %ptr.loc5_29.1 (constants.%ptr.125)] // CHECK:STDOUT: %pattern_type.loc5_25: type = pattern_type %ptr.loc5_29.1 [template = %pattern_type.loc5_25 (constants.%pattern_type.8bb)] -// CHECK:STDOUT: %x.param_patt.loc5_25.2: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = value_param_pattern [template = %x.param_patt.loc5_25.2 (constants.%x.param_patt)] -// CHECK:STDOUT: %x.patt.loc5_25.2: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = wrapper_binding_pattern x, %x.param_patt.loc5_25.2 [template = %x.patt.loc5_25.2 (constants.%x.patt)] -// CHECK:STDOUT: %.loc5_36.1: Core.Form = init_form %ptr.loc5_28.1 [template = %.loc5_36.1 (constants.%.cb6)] -// CHECK:STDOUT: %pattern_type.loc5_36: type = pattern_type %ptr.loc5_28.1 [template = %pattern_type.loc5_36 (constants.%pattern_type.4f4)] -// CHECK:STDOUT: %return.param_patt.loc5_36.2: @F.%pattern_type.loc5_36 (%pattern_type.4f4) = out_param_pattern [template = %return.param_patt.loc5_36.2 (constants.%return.param_patt.27f)] -// CHECK:STDOUT: %return.patt.loc5_32.2: @F.%pattern_type.loc5_36 (%pattern_type.4f4) = return_slot_pattern %return.param_patt.loc5_36.2, %ptr.loc5_28.1 [template = %return.patt.loc5_32.2 (constants.%return.patt.d67)] +// CHECK:STDOUT: %x.param_patt.loc5_25.2: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = value_param_pattern [template = %x.param_patt.loc5_25.2 (constants.%x.param_patt.381)] +// CHECK:STDOUT: %x.patt.loc5_25.2: @F.%pattern_type.loc5_25 (%pattern_type.8bb) = wrapper_binding_pattern x, %x.param_patt.loc5_25.2 [template = %x.patt.loc5_25.2 (constants.%x.patt.165)] +// CHECK:STDOUT: %.loc5_36.1: Core.Form = init_form %ptr.loc5_28.1 [template = %.loc5_36.1 (constants.%.cb6cb9.1)] +// CHECK:STDOUT: %pattern_type.loc5_36: type = pattern_type %ptr.loc5_28.1 [template = %pattern_type.loc5_36 (constants.%pattern_type.4f4b84.1)] +// CHECK:STDOUT: %return.param_patt.loc5_36.2: @F.%pattern_type.loc5_36 (%pattern_type.4f4b84.1) = out_param_pattern [template = %return.param_patt.loc5_36.2 (constants.%return.param_patt.27f587.1)] +// CHECK:STDOUT: %return.patt.loc5_32.2: @F.%pattern_type.loc5_36 (%pattern_type.4f4b84.1) = return_slot_pattern %return.param_patt.loc5_36.2, %ptr.loc5_28.1 [template = %return.patt.loc5_32.2 (constants.%return.patt.d67)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc5_25: = require_complete_type %ptr.loc5_29.1 [template = %require_complete.loc5_25 (constants.%require_complete.fbe)] -// CHECK:STDOUT: %require_complete.loc5_32: = require_complete_type %ptr.loc5_28.1 [template = %require_complete.loc5_32 (constants.%require_complete.ef1)] -// CHECK:STDOUT: %.loc10_10.5: = refine_type_action %.loc10_10.2, %ptr.loc5_28.1 [template] -// CHECK:STDOUT: %.loc10_10.6: @F.%ptr.loc5_28.1 (%ptr.e8f) = splice_inst %.loc10_10.5 [template = %.loc10_10.6 (constants.%.f57)] -// CHECK:STDOUT: %.loc10_10.7: = compound_member_access_action %.loc10_10.3, constants.%assoc0 [template] -// CHECK:STDOUT: %.loc10_10.8: type = type_of_inst %.loc10_10.7 [template] -// CHECK:STDOUT: %.loc10_10.9: @F.%.loc10_10.8 (@F.%.loc10_10.8) = splice_inst %.loc10_10.7 [template = %.loc10_10.9 (constants.%.7cf)] +// CHECK:STDOUT: %require_complete.loc5_32: = require_complete_type %ptr.loc5_28.1 [template = %require_complete.loc5_32 (constants.%require_complete.ef162c.1)] +// CHECK:STDOUT: %.loc6_10.6: = refine_type_action %.loc6_10.2, %ptr.loc5_28.1 [template] +// CHECK:STDOUT: %.loc6_10.7: @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = splice_inst %.loc6_10.6 [template = %.loc6_10.7 (constants.%.f57)] +// CHECK:STDOUT: %.loc6_10.8: = compound_member_access_action %.loc6_10.3, constants.%assoc0 [template] +// CHECK:STDOUT: %.loc6_10.9: type = type_of_inst %.loc6_10.8 [template] +// CHECK:STDOUT: %.loc6_10.10: @F.%.loc6_10.9 (@F.%.loc6_10.9) = splice_inst %.loc6_10.8 [template = %.loc6_10.10 (constants.%.5d1)] +// CHECK:STDOUT: %.loc6_10.11: = call_action (%.loc6_10.4), true [template] +// CHECK:STDOUT: %.loc6_10.12: type = type_of_inst %.loc6_10.11 [template] +// CHECK:STDOUT: %.loc6_10.13: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst %.loc6_10.11 [template = %.loc6_10.13 (constants.%.c4d)] +// CHECK:STDOUT: %.loc6_12.2: = convert_to_category_action %.loc6_10.5, element10 [template] +// CHECK:STDOUT: %.loc6_12.3: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst %.loc6_12.2 [template = %.loc6_12.3 (constants.%.993)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param: @F.%ptr.loc5_29.1 (%ptr.125)) -> out %return.param: @F.%ptr.loc5_28.1 (%ptr.e8f) { +// CHECK:STDOUT: fn(%x.param: @F.%ptr.loc5_29.1 (%ptr.125)) -> out %return.param: @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @F.%ptr.loc5_29.1 (%ptr.125) = name_ref x, %x -// CHECK:STDOUT: %.loc10_10.1: ref @F.%ptr.loc5_28.1 (%ptr.e8f) = deref %x.ref -// CHECK:STDOUT: %.loc10_10.2: @F.%ptr.loc5_28.1 (%ptr.e8f) = acquire_value %.loc10_10.1 -// CHECK:STDOUT: %.loc10_10.3: @F.%ptr.loc5_28.1 (%ptr.e8f) = splice_inst %.loc10_10.5 [template = %.loc10_10.6 (constants.%.f57)] -// CHECK:STDOUT: %.loc10_10.4: @F.%.loc10_10.8 (@F.%.loc10_10.8) = splice_inst %.loc10_10.7 [template = %.loc10_10.9 (constants.%.7cf)] -// CHECK:STDOUT: return +// CHECK:STDOUT: %.loc6_10.1: ref @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = deref %x.ref +// CHECK:STDOUT: %.loc6_10.2: @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = acquire_value %.loc6_10.1 +// CHECK:STDOUT: %.loc6_10.3: @F.%ptr.loc5_28.1 (%ptr.e8f8f9.1) = splice_inst %.loc6_10.6 [template = %.loc6_10.7 (constants.%.f57)] +// CHECK:STDOUT: %.loc6_10.4: @F.%.loc6_10.9 (@F.%.loc6_10.9) = splice_inst %.loc6_10.8 [template = %.loc6_10.10 (constants.%.5d1)] +// CHECK:STDOUT: %.loc6_10.5: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst %.loc6_10.11 [template = %.loc6_10.13 (constants.%.c4d)] +// CHECK:STDOUT: %.loc6_12.1: @F.%.loc6_10.12 (@F.%.loc6_10.12) = splice_inst %.loc6_12.2 [template = %.loc6_12.3 (constants.%.993)] +// CHECK:STDOUT: return %.loc6_12.1 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @F(constants.%T) { -// CHECK:STDOUT: %T.patt.loc5_16.2 => constants.%T.patt -// CHECK:STDOUT: %T.loc5_16.1 => constants.%T -// CHECK:STDOUT: %ptr.loc5_28.1 => constants.%ptr.e8f +// CHECK:STDOUT: fn @G(%x.param: %ptr.74f) -> out %return.param: %ptr.843 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: %ptr.74f = name_ref x, %x +// CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%empty_tuple.type) [concrete = constants.%F.specific_fn] +// CHECK:STDOUT: %F.call: init %ptr.843 = call %F.specific_fn(%x.ref) +// CHECK:STDOUT: return %F.call +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%T.67db0b.1) { +// CHECK:STDOUT: %T.patt.loc5_16.2 => constants.%T.patt.d47011.1 +// CHECK:STDOUT: %T.loc5_16.1 => constants.%T.67db0b.1 +// CHECK:STDOUT: %ptr.loc5_28.1 => constants.%ptr.e8f8f9.1 // CHECK:STDOUT: %ptr.loc5_29.1 => constants.%ptr.125 // CHECK:STDOUT: %pattern_type.loc5_25 => constants.%pattern_type.8bb -// CHECK:STDOUT: %x.param_patt.loc5_25.2 => constants.%x.param_patt -// CHECK:STDOUT: %x.patt.loc5_25.2 => constants.%x.patt -// CHECK:STDOUT: %.loc5_36.1 => constants.%.cb6 -// CHECK:STDOUT: %pattern_type.loc5_36 => constants.%pattern_type.4f4 -// CHECK:STDOUT: %return.param_patt.loc5_36.2 => constants.%return.param_patt.27f +// CHECK:STDOUT: %x.param_patt.loc5_25.2 => constants.%x.param_patt.381 +// CHECK:STDOUT: %x.patt.loc5_25.2 => constants.%x.patt.165 +// CHECK:STDOUT: %.loc5_36.1 => constants.%.cb6cb9.1 +// CHECK:STDOUT: %pattern_type.loc5_36 => constants.%pattern_type.4f4b84.1 +// CHECK:STDOUT: %return.param_patt.loc5_36.2 => constants.%return.param_patt.27f587.1 // CHECK:STDOUT: %return.patt.loc5_32.2 => constants.%return.patt.d67 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @F(constants.%empty_tuple.type) { +// CHECK:STDOUT: %T.patt.loc5_16.2 => constants.%T.patt.d47011.1 +// CHECK:STDOUT: %T.loc5_16.1 => constants.%empty_tuple.type +// CHECK:STDOUT: %ptr.loc5_28.1 => constants.%ptr.843 +// CHECK:STDOUT: %ptr.loc5_29.1 => constants.%ptr.74f +// CHECK:STDOUT: %pattern_type.loc5_25 => constants.%pattern_type.9ff +// CHECK:STDOUT: %x.param_patt.loc5_25.2 => constants.%x.param_patt.a10 +// CHECK:STDOUT: %x.patt.loc5_25.2 => constants.%x.patt.d10 +// CHECK:STDOUT: %.loc5_36.1 => constants.%.4ba +// CHECK:STDOUT: %pattern_type.loc5_36 => constants.%pattern_type.d64 +// CHECK:STDOUT: %return.param_patt.loc5_36.2 => constants.%return.param_patt.e3f +// CHECK:STDOUT: %return.patt.loc5_32.2 => constants.%return.patt.d4e +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc5_25 => constants.%complete_type.2f1 +// CHECK:STDOUT: %require_complete.loc5_32 => constants.%complete_type.2ab +// CHECK:STDOUT: %.loc6_10.6 => constants.%inst.as_compatible +// CHECK:STDOUT: %.loc6_10.7 => invalid +// CHECK:STDOUT: %.loc6_10.8 => constants.%inst.splice_block.64f +// CHECK:STDOUT: %.loc6_10.9 => +// CHECK:STDOUT: %.loc6_10.10 => invalid +// CHECK:STDOUT: %.loc6_10.11 => constants.%inst.splice_block.edd +// CHECK:STDOUT: %.loc6_10.12 => +// CHECK:STDOUT: %.loc6_10.13 => +// CHECK:STDOUT: %.loc6_12.2 => +// CHECK:STDOUT: %.loc6_12.3 => +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- mixed.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -156,26 +273,34 @@ fn F(template T: type, generic U: type) -> (T, U) { // CHECK:STDOUT: %tuple.type.a5e: type = tuple_type (%T, %U) [template] // CHECK:STDOUT: %.f18: Core.Form = init_form %tuple.type.a5e [template] // CHECK:STDOUT: %pattern_type.eee: type = pattern_type %tuple.type.a5e [template] -// CHECK:STDOUT: %return.param_patt: %pattern_type.eee = out_param_pattern [template] -// CHECK:STDOUT: %return.patt: %pattern_type.eee = return_slot_pattern %return.param_patt, %tuple.type.a5e [template] +// CHECK:STDOUT: %return.param_patt.a41: %pattern_type.eee = out_param_pattern [template] +// CHECK:STDOUT: %return.patt.453: %pattern_type.eee = return_slot_pattern %return.param_patt.a41, %tuple.type.a5e [template] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete: = require_complete_type %tuple.type.a5e [template] -// CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%T, %U) [template] +// CHECK:STDOUT: %.dca: @F.%.loc6_16.3 (@F.%.loc6_16.3) = splice_inst @F.%.loc6_16.2 [template] +// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.0ff = struct_value () [concrete] +// CHECK:STDOUT: %.6c2: @F.%.loc6_17.9 (@F.%.loc6_17.9) = splice_inst @F.%.loc6_17.8 [template] +// CHECK:STDOUT: %.201: @F.%.loc6_17.12 (@F.%.loc6_17.12) = splice_inst @F.%.loc6_17.11 [template] +// CHECK:STDOUT: %.7f3: @F.%.loc6_17.15 (@F.%.loc6_17.15) = splice_inst @F.%.loc6_17.14 [template] +// CHECK:STDOUT: %.e78: @F.%.loc6_17.18 (@F.%.loc6_17.18) = splice_inst @F.%.loc6_17.17 [template] +// CHECK:STDOUT: %.a48: %tuple.type.a5e = splice_inst @F.%.loc6_17.20 [template] +// CHECK:STDOUT: %.c7e: %tuple.type.a5e = splice_inst @F.%.loc6_17.22 [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %T.patt.loc5_16.1: %pattern_type.98f = symbolic_binding_pattern T, 0, template [template = %T.patt.loc5_16.2 (constants.%T.patt)] // CHECK:STDOUT: %U.patt.loc5_33.1: %pattern_type.98f = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc5_33.2 (constants.%U.patt)] -// CHECK:STDOUT: %return.param_patt.loc5_49.1: @F.%pattern_type (%pattern_type.eee) = out_param_pattern [template = %return.param_patt.loc5_49.2 (constants.%return.param_patt)] -// CHECK:STDOUT: %return.patt.loc5_41.1: @F.%pattern_type (%pattern_type.eee) = return_slot_pattern %return.param_patt.loc5_49.1, %.loc5_49.4 [template = %return.patt.loc5_41.2 (constants.%return.patt)] +// CHECK:STDOUT: %return.param_patt.loc5_49.1: @F.%pattern_type (%pattern_type.eee) = out_param_pattern [template = %return.param_patt.loc5_49.2 (constants.%return.param_patt.a41)] +// CHECK:STDOUT: %return.patt.loc5_41.1: @F.%pattern_type (%pattern_type.eee) = return_slot_pattern %return.param_patt.loc5_49.1, %.loc5_49.3 [template = %return.patt.loc5_41.2 (constants.%return.patt.453)] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.ref.loc5: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T)] // CHECK:STDOUT: %U.ref.loc5: type = name_ref U, %U.loc5_33.2 [symbolic = %U.loc5_33.1 (constants.%U)] -// CHECK:STDOUT: %.loc5_49.3: %tuple.type.24b = tuple_literal (%T.ref.loc5, %U.ref.loc5) [template = %tuple (constants.%tuple)] -// CHECK:STDOUT: %.loc5_49.4: type = converted %.loc5_49.3, constants.%tuple.type.a5e [template = %tuple.type (constants.%tuple.type.a5e)] -// CHECK:STDOUT: %.loc5_49.5: Core.Form = init_form %.loc5_49.4 [template = %.loc5_49.2 (constants.%.f18)] +// CHECK:STDOUT: %.loc5_49.2: %tuple.type.24b = tuple_literal (%T.ref.loc5, %U.ref.loc5) [template = %tuple (constants.%tuple)] +// CHECK:STDOUT: %.loc5_49.3: type = converted %.loc5_49.2, constants.%tuple.type.a5e [template = %tuple.type (constants.%tuple.type.a5e)] +// CHECK:STDOUT: %.loc5_49.4: Core.Form = init_form %.loc5_49.3 [template = %.loc5_49.1 (constants.%.f18)] // CHECK:STDOUT: %.loc5_18.1: type = splice_block %.loc5_18.2 [concrete = type] { // CHECK:STDOUT: %.Self.frozen.loc5_16: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] // CHECK:STDOUT: %.loc5_18.2: type = type_literal type [concrete = type] @@ -198,24 +323,47 @@ fn F(template T: type, generic U: type) -> (T, U) { // CHECK:STDOUT: %U.loc5_33.1: type = symbolic_binding U, 1 [symbolic = %U.loc5_33.1 (constants.%U)] // CHECK:STDOUT: %tuple: %tuple.type.24b = tuple_value (%T.loc5_16.1, %U.loc5_33.1) [template = %tuple (constants.%tuple)] // CHECK:STDOUT: %tuple.type: type = tuple_type (%T.loc5_16.1, %U.loc5_33.1) [template = %tuple.type (constants.%tuple.type.a5e)] -// CHECK:STDOUT: %.loc5_49.2: Core.Form = init_form %tuple.type [template = %.loc5_49.2 (constants.%.f18)] +// CHECK:STDOUT: %.loc5_49.1: Core.Form = init_form %tuple.type [template = %.loc5_49.1 (constants.%.f18)] // CHECK:STDOUT: %pattern_type: type = pattern_type %tuple.type [template = %pattern_type (constants.%pattern_type.eee)] -// CHECK:STDOUT: %return.param_patt.loc5_49.2: @F.%pattern_type (%pattern_type.eee) = out_param_pattern [template = %return.param_patt.loc5_49.2 (constants.%return.param_patt)] -// CHECK:STDOUT: %return.patt.loc5_41.2: @F.%pattern_type (%pattern_type.eee) = return_slot_pattern %return.param_patt.loc5_49.2, %tuple.type [template = %return.patt.loc5_41.2 (constants.%return.patt)] +// CHECK:STDOUT: %return.param_patt.loc5_49.2: @F.%pattern_type (%pattern_type.eee) = out_param_pattern [template = %return.param_patt.loc5_49.2 (constants.%return.param_patt.a41)] +// CHECK:STDOUT: %return.patt.loc5_41.2: @F.%pattern_type (%pattern_type.eee) = return_slot_pattern %return.param_patt.loc5_49.2, %tuple.type [template = %return.patt.loc5_41.2 (constants.%return.patt.453)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %tuple.type [template = %require_complete (constants.%require_complete)] -// CHECK:STDOUT: %F.specific_fn.loc6_10.2: = specific_function constants.%F, @F(%T.loc5_16.1, %U.loc5_33.1) [template = %F.specific_fn.loc6_10.2 (constants.%F.specific_fn)] +// CHECK:STDOUT: %.loc6_16.2: = call_action (%F.ref, %T.ref.loc6, %U.ref.loc6), false [template] +// CHECK:STDOUT: %.loc6_16.3: type = type_of_inst %.loc6_16.2 [template] +// CHECK:STDOUT: %.loc6_16.4: @F.%.loc6_16.3 (@F.%.loc6_16.3) = splice_inst %.loc6_16.2 [template = %.loc6_16.4 (constants.%.dca)] +// CHECK:STDOUT: %.loc6_17.8: = call_action (constants.%ImplicitAs.generic, constants.%tuple.type.a5e), false [template] +// CHECK:STDOUT: %.loc6_17.9: type = type_of_inst %.loc6_17.8 [template] +// CHECK:STDOUT: %.loc6_17.10: @F.%.loc6_17.9 (@F.%.loc6_17.9) = splice_inst %.loc6_17.8 [template = %.loc6_17.10 (constants.%.6c2)] +// CHECK:STDOUT: %.loc6_17.11: = access_member_action %.loc6_17.1, Convert [template] +// CHECK:STDOUT: %.loc6_17.12: type = type_of_inst %.loc6_17.11 [template] +// CHECK:STDOUT: %.loc6_17.13: @F.%.loc6_17.12 (@F.%.loc6_17.12) = splice_inst %.loc6_17.11 [template = %.loc6_17.13 (constants.%.201)] +// CHECK:STDOUT: %.loc6_17.14: = compound_member_access_action %.loc6_16.1, %.loc6_17.2 [template] +// CHECK:STDOUT: %.loc6_17.15: type = type_of_inst %.loc6_17.14 [template] +// CHECK:STDOUT: %.loc6_17.16: @F.%.loc6_17.15 (@F.%.loc6_17.15) = splice_inst %.loc6_17.14 [template = %.loc6_17.16 (constants.%.7f3)] +// CHECK:STDOUT: %.loc6_17.17: = call_action (%.loc6_17.3), true [template] +// CHECK:STDOUT: %.loc6_17.18: type = type_of_inst %.loc6_17.17 [template] +// CHECK:STDOUT: %.loc6_17.19: @F.%.loc6_17.18 (@F.%.loc6_17.18) = splice_inst %.loc6_17.17 [template = %.loc6_17.19 (constants.%.e78)] +// CHECK:STDOUT: %.loc6_17.20: = refine_type_action %.loc6_17.5, %tuple.type [template] +// CHECK:STDOUT: %.loc6_17.21: @F.%tuple.type (%tuple.type.a5e) = splice_inst %.loc6_17.20 [template = %.loc6_17.21 (constants.%.a48)] +// CHECK:STDOUT: %.loc6_17.22: = convert_to_category_action %.loc6_17.6, element10 [template] +// CHECK:STDOUT: %.loc6_17.23: @F.%tuple.type (%tuple.type.a5e) = splice_inst %.loc6_17.22 [template = %.loc6_17.23 (constants.%.c7e)] // CHECK:STDOUT: // CHECK:STDOUT: fn() -> out %return.param: @F.%tuple.type (%tuple.type.a5e) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] // CHECK:STDOUT: %T.ref.loc6: type = name_ref T, %T.loc5_16.2 [template = %T.loc5_16.1 (constants.%T)] // CHECK:STDOUT: %U.ref.loc6: type = name_ref U, %U.loc5_33.2 [symbolic = %U.loc5_33.1 (constants.%U)] -// CHECK:STDOUT: %F.specific_fn.loc6_10.1: = specific_function %F.ref, @F(constants.%T, constants.%U) [template = %F.specific_fn.loc6_10.2 (constants.%F.specific_fn)] -// CHECK:STDOUT: %.loc5_49.1: ref @F.%tuple.type (%tuple.type.a5e) = splice_block %return.param {} -// CHECK:STDOUT: %F.call: init @F.%tuple.type (%tuple.type.a5e) to %.loc5_49.1 = call %F.specific_fn.loc6_10.1() -// CHECK:STDOUT: return %F.call to %return.param +// CHECK:STDOUT: %.loc6_16.1: @F.%.loc6_16.3 (@F.%.loc6_16.3) = splice_inst %.loc6_16.2 [template = %.loc6_16.4 (constants.%.dca)] +// CHECK:STDOUT: %.loc6_17.1: @F.%.loc6_17.9 (@F.%.loc6_17.9) = splice_inst %.loc6_17.8 [template = %.loc6_17.10 (constants.%.6c2)] +// CHECK:STDOUT: %.loc6_17.2: @F.%.loc6_17.12 (@F.%.loc6_17.12) = splice_inst %.loc6_17.11 [template = %.loc6_17.13 (constants.%.201)] +// CHECK:STDOUT: %.loc6_17.3: @F.%.loc6_17.15 (@F.%.loc6_17.15) = splice_inst %.loc6_17.14 [template = %.loc6_17.16 (constants.%.7f3)] +// CHECK:STDOUT: %.loc6_17.4: @F.%.loc6_17.18 (@F.%.loc6_17.18) = splice_inst %.loc6_17.17 [template = %.loc6_17.19 (constants.%.e78)] +// CHECK:STDOUT: %.loc6_17.5: @F.%tuple.type (%tuple.type.a5e) = converted %.loc6_16.1, %.loc6_17.4 [template = %.loc6_17.19 (constants.%.e78)] +// CHECK:STDOUT: %.loc6_17.6: @F.%tuple.type (%tuple.type.a5e) = splice_inst %.loc6_17.20 [template = %.loc6_17.21 (constants.%.a48)] +// CHECK:STDOUT: %.loc6_17.7: @F.%tuple.type (%tuple.type.a5e) = splice_inst %.loc6_17.22 [template = %.loc6_17.23 (constants.%.c7e)] +// CHECK:STDOUT: return %.loc6_17.7 to %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -226,13 +374,9 @@ fn F(template T: type, generic U: type) -> (T, U) { // CHECK:STDOUT: %U.loc5_33.1 => constants.%U // CHECK:STDOUT: %tuple => constants.%tuple // CHECK:STDOUT: %tuple.type => constants.%tuple.type.a5e -// CHECK:STDOUT: %.loc5_49.2 => constants.%.f18 +// CHECK:STDOUT: %.loc5_49.1 => constants.%.f18 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.eee -// CHECK:STDOUT: %return.param_patt.loc5_49.2 => constants.%return.param_patt -// CHECK:STDOUT: %return.patt.loc5_41.2 => constants.%return.patt -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%require_complete -// CHECK:STDOUT: %F.specific_fn.loc6_10.2 => constants.%F.specific_fn +// CHECK:STDOUT: %return.param_patt.loc5_49.2 => constants.%return.param_patt.a41 +// CHECK:STDOUT: %return.patt.loc5_41.2 => constants.%return.patt.453 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/class/import/template.carbon b/toolchain/check/testdata/interop/cpp/class/import/template.carbon index 86c5f60c711b..fb7636078211 100644 --- a/toolchain/check/testdata/interop/cpp/class/import/template.carbon +++ b/toolchain/check/testdata/interop/cpp/class/import/template.carbon @@ -118,6 +118,47 @@ fn F(ref b: B(i32)) { } //@dump-sem-ir-end +// --- let_cpp_template_constructor.carbon + +library "[[@TEST_NAME]]"; +import Cpp inline ''' +template +struct A {}; +'''; + +// @dump-sem-ir-begin +fn F(generic T: type) { + let unused a: Cpp.A(T) = Cpp.A(T).A(); +} + +fn G() { + F(i32); +} +// @dump-sem-ir-end + +// --- fail_todo_var_cpp_template_constructor.carbon + +library "[[@TEST_NAME]]"; +import Cpp inline ''' +template +struct A {}; +'''; + +fn F(generic T: type) { + var unused a: Cpp.A(T) = Cpp.A(T).A(); +} + +fn G() { + // CHECK:STDERR: fail_todo_var_cpp_template_constructor.carbon:[[@LINE+7]]:3: error: unable to monomorphize specific `F(i32)` [ResolvingSpecificHere] + // CHECK:STDERR: F(i32); + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_todo_var_cpp_template_constructor.carbon:[[@LINE-7]]:3: note: value of type `` is not callable [CallToNonCallable] + // CHECK:STDERR: var unused a: Cpp.A(T) = Cpp.A(T).A(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + F(i32); +} + // CHECK:STDOUT: --- use_class_template.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interop/cpp/template/generic_call.carbon b/toolchain/check/testdata/interop/cpp/template/generic_call.carbon index e7ad2dd09625..9b441edea09d 100644 --- a/toolchain/check/testdata/interop/cpp/template/generic_call.carbon +++ b/toolchain/check/testdata/interop/cpp/template/generic_call.carbon @@ -24,19 +24,16 @@ library "[[@TEST_NAME]]"; import Cpp library "header.h"; fn F[T: type](unused x: T) { - // TODO: This should be treated as being template-dependent on T, - // and we should perform the call during monomorphization. - // CHECK:STDERR: fail_todo_generic_call.carbon:[[@LINE+8]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: Cpp.S(T); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_generic_call.carbon:[[@LINE+4]]:3: error: value of type `` is not callable [CallToNonCallable] - // CHECK:STDERR: var unused v: Cpp.S(T); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: var unused v: Cpp.S(T); } fn G() { + // CHECK:STDERR: fail_todo_generic_call.carbon:[[@LINE+7]]:3: error: unable to monomorphize specific `F(Cpp.X)` [ResolvingSpecificHere] + // CHECK:STDERR: F({} as Cpp.X); + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_todo_generic_call.carbon:[[@LINE-7]]:3: note: value of type `` is not callable [CallToNonCallable] + // CHECK:STDERR: var unused v: Cpp.S(T); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: F({} as Cpp.X); } diff --git a/toolchain/sem_ir/id_kind.h b/toolchain/sem_ir/id_kind.h index 37008d5a5bd0..e742db71b512 100644 --- a/toolchain/sem_ir/id_kind.h +++ b/toolchain/sem_ir/id_kind.h @@ -64,6 +64,7 @@ using IdKind = TypeEnum< LibraryNameId, LocId, MetaInstId, + MetaInstBlockId, NameId, NameScopeId, NamedConstraintId, diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 0bcad22ca2f3..1a8972c70535 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -844,6 +844,21 @@ class DeclInstBlockId : public InstBlockId { using InstBlockId::InstBlockId; }; +// An ID of an instruction block that is referenced as a meta-operand of an +// action. This is analogous to a `MetaInstId`, but for an instructions block +// instead of an instruction. +class MetaInstBlockId : public InstBlockId { + public: + static constexpr llvm::StringLiteral Label = "meta_inst_block"; + + // Support implicit conversion from InstBlockId so that InstBlockId and + // MetaInstBlockId have the same interface. + explicit(false) constexpr MetaInstBlockId(InstBlockId inst_block_id) + : InstBlockId(inst_block_id) {} + + using InstBlockId::InstBlockId; +}; + // An ID of an instruction block that is used as a label in a branch instruction // or similar. This is a block that is not nested within the instruction, but // instead exists elsewhere in the enclosing executable region. This should diff --git a/toolchain/sem_ir/inst_kind.def b/toolchain/sem_ir/inst_kind.def index 040d54370a32..2bf171ad7f5e 100644 --- a/toolchain/sem_ir/inst_kind.def +++ b/toolchain/sem_ir/inst_kind.def @@ -43,6 +43,7 @@ CARBON_SEM_IR_INST_KIND(Branch) CARBON_SEM_IR_INST_KIND(BranchIf) CARBON_SEM_IR_INST_KIND(BranchWithArg) CARBON_SEM_IR_INST_KIND(Call) +CARBON_SEM_IR_INST_KIND(CallAction) CARBON_SEM_IR_INST_KIND(CallCppTemplateAction) CARBON_SEM_IR_INST_KIND(CalleePatternMatchAction) CARBON_SEM_IR_INST_KIND(CallerPatternMatchAction) diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 3f43ddf19e09..171cdd5a68d5 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -390,6 +390,21 @@ struct Call { InstBlockId args_id; }; +// An action that performs a call. +struct CallAction { + static constexpr auto Kind = InstKind::CallAction.Define( + {.ir_name = "call_action", + .expr_category = ActionExprCategory(ExprCategory::Dependent), + .constant_kind = InstConstantKind::InstAction, + .is_lowered = false}); + + TypeId type_id; + // The first element in this block is the callee. The rest are the call + // arguments. + MetaInstBlockId inst_block_id; + BoolValue is_desugared; +}; + // An action that performs a C++ template call. struct CallCppTemplateAction { static constexpr auto Kind =