Add tests for generic functions with ref, val, and var auto returns. (#7997)

Assisted-by: Claude via Antigravity
This commit is contained in:
Richard Smith authored and GitHub committed 2026-10-16 22:42:21 +00:00
1 parent b766aa4d16
commit e8ffeef7b5
2 files changed
+693

No files matched your search

@@ -0,0 +1,607 @@
// 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/primitives.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/deduced_return/generic_form.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/deduced_return/generic_form.carbon
// --- ref_auto.carbon
library "[[@TEST_NAME]]";
//@dump-sem-ir-begin
fn F[T: type](ref x: T) -> ref auto { return x; }
fn G(ref n: i32) -> ref i32 { return F(ref n); }
//@dump-sem-ir-end
// --- ref_auto_call_from_generic.carbon
library "[[@TEST_NAME]]";
fn F[T: type](ref x: T) -> ref auto { return x; }
//@dump-sem-ir-begin
fn G[U: type](ref u: U) -> ref U { return F(ref u); }
//@dump-sem-ir-end
fn H(ref n: i32) -> ref i32 { return G(ref n); }
// --- ref_auto_address_of_result.carbon
library "[[@TEST_NAME]]";
fn F[T: type](ref x: T) -> ref auto { return x; }
// The call is a durable reference expression, so its address can be taken.
fn G(ref n: i32) -> i32* { return &F(ref n); }
fn H[U: type](ref u: U) -> U* { return &F(ref u); }
// --- ref_auto_deduced_from_call.carbon
library "[[@TEST_NAME]]";
fn F[T: type](ref x: T) -> ref auto { return x; }
fn G[U: type](ref u: U) -> ref auto { return F(ref u); }
fn H(ref n: i32) -> i32* { return &G(ref n); }
fn I[V: type](ref v: V) -> V* { return &G(ref v); }
// --- ref_auto_return_type_from_definition.carbon
library "[[@TEST_NAME]]";
class C(T: type) {
var x: T;
}
// The return type doesn't appear in the declaration, so is only computed by the
// definition's eval block.
fn F[T: type](ref c: C(T)) -> ref auto { return c.x; }
fn G(ref c: C(i32)) -> i32* { return &F(ref c); }
fn H[U: type](ref c: C(U)) -> U* { return &F(ref c); }
// --- ref_auto_member_of_generic_class.carbon
library "[[@TEST_NAME]]";
class C(T: type) {
fn Get(ref self) -> ref auto { return self.x; }
var x: T;
}
fn G(ref c: C(i32)) -> i32* { return &c.Get(); }
fn H[U: type](ref c: C(U)) -> U* { return &c.Get(); }
// --- val_auto.carbon
library "[[@TEST_NAME]]";
//@dump-sem-ir-begin
fn F[T: type](x: T) -> val auto { return x; }
fn G() {
let unused n: i32 = F(1 as i32);
}
//@dump-sem-ir-end
fn H[U: type](u: U) {
let unused v: U = F(u);
}
// --- var_auto.carbon
library "[[@TEST_NAME]]";
fn F[T: Core.Copy](x: T) -> var auto { return x; }
fn G() {
var unused n: i32 = F(1 as i32);
}
fn H[U: Core.Copy & Core.Destroy](u: U) {
var unused v: U = F(u);
}
// --- var_auto_returned_var.carbon
library "[[@TEST_NAME]]";
fn F[T: Core.Copy](x: T) -> var auto {
returned var v: T = x;
return var;
}
fn G() -> i32 { return F(1 as i32); }
fn H[U: Core.Copy](u: U) -> U { return F(u); }
// --- template_ref_auto.carbon
library "[[@TEST_NAME]]";
fn F[template T: type](ref x: T) -> ref auto { return x.n; }
class C {
var n: i32;
}
fn G(ref c: C) -> i32* { return &F(ref c); }
fn H(ref s: {.n: bool}) -> bool* { return &F(ref s); }
// --- template_val_auto.carbon
library "[[@TEST_NAME]]";
fn F[template T: type](x: T) -> val auto { return x.n; }
class C {
var n: i32;
}
fn G(c: C) -> i32 { return F(c); }
// --- template_ref_auto_call_from_checked_generic.carbon
library "[[@TEST_NAME]]";
fn F[template T: type](ref x: T) -> ref auto { return x; }
fn G[U: type](ref u: U) -> U* { return &F(ref u); }
fn H(ref n: i32) -> i32* { return G(ref n); }
// --- fail_ref_auto_non_ref.carbon
library "[[@TEST_NAME]]";
fn F[T: type](x: T) -> ref auto {
// CHECK:STDERR: fail_ref_auto_non_ref.carbon:[[@LINE+3]]:3-11: error: cannot bind durable reference to non-reference value of type `T` [ConversionFailureNonRefToRef]
// CHECK:STDERR: fail_ref_auto_non_ref.carbon:[[@LINE+2]]:10: note: return type deduced as `T` [ReturnTypeDeducedAs]
// CHECK:STDERR:
return x;
}
// --- fail_template_ref_auto_non_ref.carbon
library "[[@TEST_NAME]]";
fn F[template T: type](x: T) -> ref auto { return x.n; }
class C {
var n: i32;
}
fn G(c: C) {
// CHECK:STDERR: fail_template_ref_auto_non_ref.carbon:[[@LINE+3]]:3-6: error: unable to monomorphize specific `F(C)` [ResolvingSpecificHere]
// CHECK:STDERR: fail_template_ref_auto_non_ref.carbon:[[@LINE-8]]:44-54: note: cannot bind durable reference to non-reference value of type `i32` [ConversionFailureNonRefToRef]
// CHECK:STDERR:
F(c);
}
// --- fail_template_ref_auto_recursion_before_deduced.carbon
library "[[@TEST_NAME]]";
fn F[template T: type](ref x: T) -> ref auto {
return F(ref x);
}
fn G(ref n: i32) {
// CHECK:STDERR: fail_template_ref_auto_recursion_before_deduced.carbon:[[@LINE+4]]:3-10: error: unable to monomorphize specific `F(i32)` [ResolvingSpecificHere]
// CHECK:STDERR: fail_template_ref_auto_recursion_before_deduced.carbon:[[@LINE-5]]:10-17: note: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
// CHECK:STDERR: fail_template_ref_auto_recursion_before_deduced.carbon:[[@LINE-7]]:1-46: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
// CHECK:STDERR:
F(ref n);
}
// --- lib.carbon
library "[[@TEST_NAME]]";
fn RefId[T: type](ref x: T) -> ref auto { return x; }
fn ValId[T: type](x: T) -> val auto { return x; }
// --- use_lib.carbon
library "[[@TEST_NAME]]";
import library "lib";
fn G(ref n: i32) -> i32* { return &RefId(ref n); }
fn H() {
let unused v: i32 = ValId(1 as i32);
}
fn I[U: type](ref u: U) -> U* { return &RefId(ref u); }
// CHECK:STDOUT: --- ref_auto.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.9a5: type = pattern_type type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.51d: type = pattern_type %T [symbolic]
// CHECK:STDOUT: %x.param_patt.2ca: %pattern_type.51d = ref_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.c65: %pattern_type.51d = wrapper_binding_pattern x, %x.param_patt.2ca [symbolic]
// CHECK:STDOUT: %.010: Core.Form = ref_form auto [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %require_complete.944: <witness> = require_complete_type %T [symbolic]
// CHECK:STDOUT: %.b33: Core.Form = ref_form %T [symbolic]
// CHECK:STDOUT: %.066: %pattern_type.51d = ref_return_pattern [symbolic]
// CHECK:STDOUT: %return.patt.1cc: %pattern_type.51d = return_slot_pattern %.066, %T [symbolic]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %n.param_patt: %pattern_type.d94 = ref_param_pattern [concrete]
// CHECK:STDOUT: %n.patt: %pattern_type.d94 = wrapper_binding_pattern n, %n.param_patt [concrete]
// CHECK:STDOUT: %.30e: Core.Form = ref_form %i32 [concrete]
// CHECK:STDOUT: %.b71: %pattern_type.d94 = ref_return_pattern [concrete]
// CHECK:STDOUT: %return.patt.2c5: %pattern_type.d94 = return_slot_pattern %.b71, %i32 [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
// CHECK:STDOUT: %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
// CHECK:STDOUT: %x.param_patt.85b: %pattern_type.d94 = ref_param_pattern [concrete]
// CHECK:STDOUT: %x.patt.fe0: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt.85b [concrete]
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F, @F(%i32) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
// CHECK:STDOUT: %T.patt.loc4_7.1: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %x.param_patt.loc4_20.1: @F.%pattern_type (%pattern_type.51d) = ref_param_pattern [symbolic = %x.param_patt.loc4_20.2 (constants.%x.param_patt.2ca)]
// CHECK:STDOUT: %x.patt.loc4_20.1: @F.%pattern_type (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc4_20.1 [symbolic = %x.patt.loc4_20.2 (constants.%x.patt.c65)]
// CHECK:STDOUT: %.loc4_46.1: @F.%pattern_type (%pattern_type.51d) = ref_return_pattern [symbolic = %.loc4_46.3 (constants.%.066)]
// CHECK:STDOUT: %return.patt.loc4_46.1: @F.%pattern_type (%pattern_type.51d) = return_slot_pattern %.loc4_46.1, %.loc4_46.4 [symbolic = %return.patt.loc4_46.2 (constants.%return.patt.1cc)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc4_28: Core.Form = ref_form auto [concrete = constants.%.010]
// CHECK:STDOUT: %.loc4_9.1: type = splice_block %.loc4_9.2 [concrete = type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.loc4_9.2: type = type_literal type [concrete = type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc4_7.2: type = symbolic_binding T, 0 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %x.param: ref @F.%T.loc4_7.1 (%T) = ref_param call_param0
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_7.2 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %x: ref @F.%T.loc4_7.1 (%T) = wrapper_binding x, %x.param
// CHECK:STDOUT: %.loc4_46.4: type = type_literal constants.%T [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %.loc4_46.5: Core.Form = ref_form %.loc4_46.4 [symbolic = %.loc4_46.2 (constants.%.b33)]
// CHECK:STDOUT: %.loc4_46.6: ref @F.%T.loc4_7.1 (%T) = ref_return
// CHECK:STDOUT: %return: ref @F.%T.loc4_7.1 (%T) = return_slot %.loc4_46.6
// CHECK:STDOUT: }
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
// CHECK:STDOUT: %n.param_patt: %pattern_type.d94 = ref_param_pattern [concrete = constants.%n.param_patt]
// CHECK:STDOUT: %n.patt: %pattern_type.d94 = wrapper_binding_pattern n, %n.param_patt [concrete = constants.%n.patt]
// CHECK:STDOUT: %.loc6_21.1: %pattern_type.d94 = ref_return_pattern [concrete = constants.%.b71]
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %.loc6_21.1, %.loc6_21.3 [concrete = constants.%return.patt.2c5]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %i32.loc6_25: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %.loc6_21.2: Core.Form = ref_form %i32.loc6_25 [concrete = constants.%.30e]
// CHECK:STDOUT: %.loc6_21.3: type = type_component_of %.loc6_21.2 [concrete = constants.%i32]
// CHECK:STDOUT: %n.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %i32.loc6_13: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %n: ref %i32 = wrapper_binding n, %n.param
// CHECK:STDOUT: %.loc6_21.4: ref %i32 = ref_return
// CHECK:STDOUT: %return: ref %i32 = return_slot %.loc6_21.4
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @F(%T.loc4_7.2: type) {
// CHECK:STDOUT: %T.patt.loc4_7.2: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.loc4_7.1: type = symbolic_binding T, 0 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc4_7.1 [symbolic = %pattern_type (constants.%pattern_type.51d)]
// CHECK:STDOUT: %x.param_patt.loc4_20.2: @F.%pattern_type (%pattern_type.51d) = ref_param_pattern [symbolic = %x.param_patt.loc4_20.2 (constants.%x.param_patt.2ca)]
// CHECK:STDOUT: %x.patt.loc4_20.2: @F.%pattern_type (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc4_20.2 [symbolic = %x.patt.loc4_20.2 (constants.%x.patt.c65)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.loc4_7.1 [symbolic = %require_complete (constants.%require_complete.944)]
// CHECK:STDOUT: %.loc4_46.2: Core.Form = ref_form %T.loc4_7.1 [symbolic = %.loc4_46.2 (constants.%.b33)]
// CHECK:STDOUT: %.loc4_46.3: @F.%pattern_type (%pattern_type.51d) = ref_return_pattern [symbolic = %.loc4_46.3 (constants.%.066)]
// CHECK:STDOUT: %return.patt.loc4_46.2: @F.%pattern_type (%pattern_type.51d) = return_slot_pattern %.loc4_46.3, %T.loc4_7.1 [symbolic = %return.patt.loc4_46.2 (constants.%return.patt.1cc)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: ref @F.%T.loc4_7.1 (%T)) -> ref %T [deduced] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: ref @F.%T.loc4_7.1 (%T) = name_ref x, %x
// CHECK:STDOUT: %.loc4_47: ref @F.%T.loc4_7.1 (%T) = splice_block %x.ref {}
// CHECK:STDOUT: return %.loc4_47
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G(%n.param: ref %i32) -> ref %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %n.ref: ref %i32 = name_ref n, %n
// CHECK:STDOUT: %.loc6_40: %i32 = ref_tag %n.ref
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%i32) [concrete = constants.%F.specific_fn]
// CHECK:STDOUT: %F.call: ref %i32 = call %F.specific_fn(%n.ref)
// CHECK:STDOUT: return %F.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%T) {
// CHECK:STDOUT: %T.patt.loc4_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_7.1 => constants.%T
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d
// CHECK:STDOUT: %x.param_patt.loc4_20.2 => constants.%x.param_patt.2ca
// CHECK:STDOUT: %x.patt.loc4_20.2 => constants.%x.patt.c65
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%i32) {
// CHECK:STDOUT: %T.patt.loc4_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_7.1 => constants.%i32
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d94
// CHECK:STDOUT: %x.param_patt.loc4_20.2 => constants.%x.param_patt.85b
// CHECK:STDOUT: %x.patt.loc4_20.2 => constants.%x.patt.fe0
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
// CHECK:STDOUT: %.loc4_46.2 => constants.%.30e
// CHECK:STDOUT: %.loc4_46.3 => constants.%.b71
// CHECK:STDOUT: %return.patt.loc4_46.2 => constants.%return.patt.2c5
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- ref_auto_call_from_generic.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.9a5: type = pattern_type type [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %U.patt: %pattern_type.9a5 = symbolic_binding_pattern U, 0 [symbolic]
// CHECK:STDOUT: %U: type = symbolic_binding U, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.51d1c4.2: type = pattern_type %U [symbolic]
// CHECK:STDOUT: %u.param_patt.5e6: %pattern_type.51d1c4.2 = ref_param_pattern [symbolic]
// CHECK:STDOUT: %u.patt.c4b: %pattern_type.51d1c4.2 = wrapper_binding_pattern u, %u.param_patt.5e6 [symbolic]
// CHECK:STDOUT: %.b33a4e.2: Core.Form = ref_form %U [symbolic]
// CHECK:STDOUT: %.06682e.2: %pattern_type.51d1c4.2 = ref_return_pattern [symbolic]
// CHECK:STDOUT: %return.patt.1cce12.2: %pattern_type.51d1c4.2 = return_slot_pattern %.06682e.2, %U [symbolic]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %require_complete.9443dd.2: <witness> = require_complete_type %U [symbolic]
// CHECK:STDOUT: %F.specific_fn.c05: <specific function> = specific_function %F, @F(%U) [symbolic]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %.30e: Core.Form = ref_form %i32 [concrete]
// CHECK:STDOUT: %.b71: %pattern_type.d94 = ref_return_pattern [concrete]
// CHECK:STDOUT: %return.patt.2c5: %pattern_type.d94 = return_slot_pattern %.b71, %i32 [concrete]
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
// CHECK:STDOUT: %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
// CHECK:STDOUT: %u.param_patt.508: %pattern_type.d94 = ref_param_pattern [concrete]
// CHECK:STDOUT: %u.patt.4fa: %pattern_type.d94 = wrapper_binding_pattern u, %u.param_patt.508 [concrete]
// CHECK:STDOUT: %F.specific_fn.9db: <specific function> = specific_function %F, @F(%i32) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
// CHECK:STDOUT: %U.patt.loc6_7.1: %pattern_type.9a5 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc6_7.2 (constants.%U.patt)]
// CHECK:STDOUT: %u.param_patt.loc6_20.1: @G.%pattern_type (%pattern_type.51d1c4.2) = ref_param_pattern [symbolic = %u.param_patt.loc6_20.2 (constants.%u.param_patt.5e6)]
// CHECK:STDOUT: %u.patt.loc6_20.1: @G.%pattern_type (%pattern_type.51d1c4.2) = wrapper_binding_pattern u, %u.param_patt.loc6_20.1 [symbolic = %u.patt.loc6_20.2 (constants.%u.patt.c4b)]
// CHECK:STDOUT: %.loc6_28.1: @G.%pattern_type (%pattern_type.51d1c4.2) = ref_return_pattern [symbolic = %.loc6_28.3 (constants.%.06682e.2)]
// CHECK:STDOUT: %return.patt.loc6_25.1: @G.%pattern_type (%pattern_type.51d1c4.2) = return_slot_pattern %.loc6_28.1, %.loc6_28.5 [symbolic = %return.patt.loc6_25.2 (constants.%return.patt.1cce12.2)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %U.ref.loc6_32: type = name_ref U, %U.loc6_7.2 [symbolic = %U.loc6_7.1 (constants.%U)]
// CHECK:STDOUT: %.loc6_28.4: Core.Form = ref_form %U.ref.loc6_32 [symbolic = %.loc6_28.2 (constants.%.b33a4e.2)]
// CHECK:STDOUT: %.loc6_28.5: type = type_component_of %.loc6_28.4 [symbolic = %U.loc6_7.1 (constants.%U)]
// CHECK:STDOUT: %.loc6_9.1: type = splice_block %.loc6_9.2 [concrete = type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.loc6_9.2: type = type_literal type [concrete = type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %U.loc6_7.2: type = symbolic_binding U, 0 [symbolic = %U.loc6_7.1 (constants.%U)]
// CHECK:STDOUT: %u.param: ref @G.%U.loc6_7.1 (%U) = ref_param call_param0
// CHECK:STDOUT: %U.ref.loc6_22: type = name_ref U, %U.loc6_7.2 [symbolic = %U.loc6_7.1 (constants.%U)]
// CHECK:STDOUT: %u: ref @G.%U.loc6_7.1 (%U) = wrapper_binding u, %u.param
// CHECK:STDOUT: %.loc6_28.6: ref @G.%U.loc6_7.1 (%U) = ref_return
// CHECK:STDOUT: %return: ref @G.%U.loc6_7.1 (%U) = return_slot %.loc6_28.6
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @G(%U.loc6_7.2: type) {
// CHECK:STDOUT: %U.patt.loc6_7.2: %pattern_type.9a5 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc6_7.2 (constants.%U.patt)]
// CHECK:STDOUT: %U.loc6_7.1: type = symbolic_binding U, 0 [symbolic = %U.loc6_7.1 (constants.%U)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %U.loc6_7.1 [symbolic = %pattern_type (constants.%pattern_type.51d1c4.2)]
// CHECK:STDOUT: %u.param_patt.loc6_20.2: @G.%pattern_type (%pattern_type.51d1c4.2) = ref_param_pattern [symbolic = %u.param_patt.loc6_20.2 (constants.%u.param_patt.5e6)]
// CHECK:STDOUT: %u.patt.loc6_20.2: @G.%pattern_type (%pattern_type.51d1c4.2) = wrapper_binding_pattern u, %u.param_patt.loc6_20.2 [symbolic = %u.patt.loc6_20.2 (constants.%u.patt.c4b)]
// CHECK:STDOUT: %.loc6_28.2: Core.Form = ref_form %U.loc6_7.1 [symbolic = %.loc6_28.2 (constants.%.b33a4e.2)]
// CHECK:STDOUT: %.loc6_28.3: @G.%pattern_type (%pattern_type.51d1c4.2) = ref_return_pattern [symbolic = %.loc6_28.3 (constants.%.06682e.2)]
// CHECK:STDOUT: %return.patt.loc6_25.2: @G.%pattern_type (%pattern_type.51d1c4.2) = return_slot_pattern %.loc6_28.3, %U.loc6_7.1 [symbolic = %return.patt.loc6_25.2 (constants.%return.patt.1cce12.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %U.loc6_7.1 [symbolic = %require_complete (constants.%require_complete.9443dd.2)]
// CHECK:STDOUT: %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%U.loc6_7.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.c05)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%u.param: ref @G.%U.loc6_7.1 (%U)) -> ref %U {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %u.ref: ref @G.%U.loc6_7.1 (%U) = name_ref u, %u
// CHECK:STDOUT: %.loc6_45: @G.%U.loc6_7.1 (%U) = ref_tag %u.ref
// CHECK:STDOUT: %F.specific_fn.loc6_43.1: <specific function> = specific_function %F.ref, @F(constants.%U) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.c05)]
// CHECK:STDOUT: %F.call: ref @G.%U.loc6_7.1 (%U) = call %F.specific_fn.loc6_43.1(%u.ref)
// CHECK:STDOUT: return %F.call
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @G(constants.%U) {
// CHECK:STDOUT: %U.patt.loc6_7.2 => constants.%U.patt
// CHECK:STDOUT: %U.loc6_7.1 => constants.%U
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d1c4.2
// CHECK:STDOUT: %u.param_patt.loc6_20.2 => constants.%u.param_patt.5e6
// CHECK:STDOUT: %u.patt.loc6_20.2 => constants.%u.patt.c4b
// CHECK:STDOUT: %.loc6_28.2 => constants.%.b33a4e.2
// CHECK:STDOUT: %.loc6_28.3 => constants.%.06682e.2
// CHECK:STDOUT: %return.patt.loc6_25.2 => constants.%return.patt.1cce12.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @G(constants.%i32) {
// CHECK:STDOUT: %U.patt.loc6_7.2 => constants.%U.patt
// CHECK:STDOUT: %U.loc6_7.1 => constants.%i32
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d94
// CHECK:STDOUT: %u.param_patt.loc6_20.2 => constants.%u.param_patt.508
// CHECK:STDOUT: %u.patt.loc6_20.2 => constants.%u.patt.4fa
// CHECK:STDOUT: %.loc6_28.2 => constants.%.30e
// CHECK:STDOUT: %.loc6_28.3 => constants.%.b71
// CHECK:STDOUT: %return.patt.loc6_25.2 => constants.%return.patt.2c5
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
// CHECK:STDOUT: %F.specific_fn.loc6_43.2 => constants.%F.specific_fn.9db
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- val_auto.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.9a5: type = pattern_type type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.51d1c4.1: type = pattern_type %T [symbolic]
// CHECK:STDOUT: %x.param_patt.91de5a.1: %pattern_type.51d1c4.1 = value_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.26065e.1: %pattern_type.51d1c4.1 = wrapper_binding_pattern x, %x.param_patt.91de5a.1 [symbolic]
// CHECK:STDOUT: %.0c3: Core.Form = value_form auto [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %require_complete.9443dd.1: <witness> = require_complete_type %T [symbolic]
// CHECK:STDOUT: %.a89f79.1: Core.Form = value_form %T [symbolic]
// CHECK:STDOUT: %.c5a291.1: %pattern_type.51d1c4.1 = value_return_pattern [symbolic]
// CHECK:STDOUT: %return.patt.5d1d5c.1: %pattern_type.51d1c4.1 = return_slot_pattern %.c5a291.1, %T [symbolic]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
// CHECK:STDOUT: %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %n.patt: %pattern_type.d94 = value_binding_pattern n [concrete]
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %As.type.b93: type = facet_type <@As, @As(%i32)> [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.type.396: type = fn_type @Core.IntLiteral.as.As.impl.Convert, @Core.IntLiteral.as.As.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.84a: %Core.IntLiteral.as.As.impl.Convert.type.396 = struct_value () [symbolic]
// CHECK:STDOUT: %As.impl_witness.e09: <witness> = impl_witness imports.%As.impl_witness_table.1c2, @Core.IntLiteral.as.As.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.type.2b0: type = fn_type @Core.IntLiteral.as.As.impl.Convert, @Core.IntLiteral.as.As.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.94f: %Core.IntLiteral.as.As.impl.Convert.type.2b0 = struct_value () [concrete]
// CHECK:STDOUT: %As.facet: %As.type.b93 = facet_value Core.IntLiteral, (%As.impl_witness.e09) [concrete]
// CHECK:STDOUT: %As.WithSelf.Convert.type.2be: type = fn_type @As.WithSelf.Convert, @As.WithSelf(%i32, %As.facet) [concrete]
// CHECK:STDOUT: %.979: type = fn_type_with_self_type %As.WithSelf.Convert.type.2be, %As.facet [concrete]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.bound: <bound method> = bound_method %int_1.5b8, %Core.IntLiteral.as.As.impl.Convert.94f [concrete]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.As.impl.Convert.94f, @Core.IntLiteral.as.As.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Core.IntLiteral.as.As.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.68a: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %x.param_patt.051: %pattern_type.d94 = value_param_pattern [concrete]
// CHECK:STDOUT: %x.patt.0f7: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt.051 [concrete]
// CHECK:STDOUT: %F.specific_fn.9db: <specific function> = specific_function %F, @F(%i32) [concrete]
// CHECK:STDOUT: %.acd: Core.Form = value_form %i32 [concrete]
// CHECK:STDOUT: %.45b: %pattern_type.d94 = value_return_pattern [concrete]
// CHECK:STDOUT: %return.patt.f8b: %pattern_type.d94 = return_slot_pattern %.45b, %i32 [concrete]
// CHECK:STDOUT: %U: type = symbolic_binding U, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.51d1c4.3: type = pattern_type %U [symbolic]
// CHECK:STDOUT: %require_complete.9443dd.2: <witness> = require_complete_type %U [symbolic]
// CHECK:STDOUT: %x.param_patt.91de5a.2: %pattern_type.51d1c4.3 = value_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.26065e.2: %pattern_type.51d1c4.3 = wrapper_binding_pattern x, %x.param_patt.91de5a.2 [symbolic]
// CHECK:STDOUT: %.a89f79.2: Core.Form = value_form %U [symbolic]
// CHECK:STDOUT: %.c5a291.2: %pattern_type.51d1c4.3 = value_return_pattern [symbolic]
// CHECK:STDOUT: %return.patt.5d1d5c.2: %pattern_type.51d1c4.3 = return_slot_pattern %.c5a291.2, %U [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.9e0: @Core.IntLiteral.as.As.impl.%Core.IntLiteral.as.As.impl.Convert.type (%Core.IntLiteral.as.As.impl.Convert.type.396) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.As.impl.%Core.IntLiteral.as.As.impl.Convert (constants.%Core.IntLiteral.as.As.impl.Convert.84a)]
// CHECK:STDOUT: %As.impl_witness_table.1c2 = impl_witness_table (%Core.import_ref.9e0), @Core.IntLiteral.as.As.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.loc4_7.1: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %x.param_patt.loc4_16.1: @F.%pattern_type (%pattern_type.51d1c4.1) = value_param_pattern [symbolic = %x.param_patt.loc4_16.2 (constants.%x.param_patt.91de5a.1)]
// CHECK:STDOUT: %x.patt.loc4_16.1: @F.%pattern_type (%pattern_type.51d1c4.1) = wrapper_binding_pattern x, %x.param_patt.loc4_16.1 [symbolic = %x.patt.loc4_16.2 (constants.%x.patt.26065e.1)]
// CHECK:STDOUT: %.loc4_42.1: @F.%pattern_type (%pattern_type.51d1c4.1) = value_return_pattern [symbolic = %.loc4_42.3 (constants.%.c5a291.1)]
// CHECK:STDOUT: %return.patt.loc4_42.1: @F.%pattern_type (%pattern_type.51d1c4.1) = return_slot_pattern %.loc4_42.1, %.loc4_42.4 [symbolic = %return.patt.loc4_42.2 (constants.%return.patt.5d1d5c.1)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc4_24: Core.Form = value_form auto [concrete = constants.%.0c3]
// CHECK:STDOUT: %.loc4_9.1: type = splice_block %.loc4_9.2 [concrete = type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.loc4_9.2: type = type_literal type [concrete = type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc4_7.2: type = symbolic_binding T, 0 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %x.param: @F.%T.loc4_7.1 (%T) = value_param call_param0
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_7.2 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %x: @F.%T.loc4_7.1 (%T) = wrapper_binding x, %x.param
// CHECK:STDOUT: %.loc4_42.4: type = type_literal constants.%T [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %.loc4_42.5: Core.Form = value_form %.loc4_42.4 [symbolic = %.loc4_42.2 (constants.%.a89f79.1)]
// CHECK:STDOUT: %.loc4_42.6: @F.%T.loc4_7.1 (%T) = value_return
// CHECK:STDOUT: %return: @F.%T.loc4_7.1 (%T) = return_slot %.loc4_42.6
// CHECK:STDOUT: }
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @F(%T.loc4_7.2: type) {
// CHECK:STDOUT: %T.patt.loc4_7.2: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.loc4_7.1: type = symbolic_binding T, 0 [symbolic = %T.loc4_7.1 (constants.%T)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc4_7.1 [symbolic = %pattern_type (constants.%pattern_type.51d1c4.1)]
// CHECK:STDOUT: %x.param_patt.loc4_16.2: @F.%pattern_type (%pattern_type.51d1c4.1) = value_param_pattern [symbolic = %x.param_patt.loc4_16.2 (constants.%x.param_patt.91de5a.1)]
// CHECK:STDOUT: %x.patt.loc4_16.2: @F.%pattern_type (%pattern_type.51d1c4.1) = wrapper_binding_pattern x, %x.param_patt.loc4_16.2 [symbolic = %x.patt.loc4_16.2 (constants.%x.patt.26065e.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.loc4_7.1 [symbolic = %require_complete (constants.%require_complete.9443dd.1)]
// CHECK:STDOUT: %.loc4_42.2: Core.Form = value_form %T.loc4_7.1 [symbolic = %.loc4_42.2 (constants.%.a89f79.1)]
// CHECK:STDOUT: %.loc4_42.3: @F.%pattern_type (%pattern_type.51d1c4.1) = value_return_pattern [symbolic = %.loc4_42.3 (constants.%.c5a291.1)]
// CHECK:STDOUT: %return.patt.loc4_42.2: @F.%pattern_type (%pattern_type.51d1c4.1) = return_slot_pattern %.loc4_42.3, %T.loc4_7.1 [symbolic = %return.patt.loc4_42.2 (constants.%return.patt.5d1d5c.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @F.%T.loc4_7.1 (%T)) -> val %T [deduced] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: @F.%T.loc4_7.1 (%T) = name_ref x, %x
// CHECK:STDOUT: %.loc4_43: @F.%T.loc4_7.1 (%T) = splice_block %x.ref {}
// CHECK:STDOUT: return %.loc4_43
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %i32.loc7_30: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %impl.elem0: %.979 = impl_witness_access constants.%As.impl_witness.e09, element0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.94f]
// CHECK:STDOUT: %bound_method.loc7_27.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.As.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_27.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i32 = call %bound_method.loc7_27.2(%int_1) [concrete = constants.%int_1.68a]
// CHECK:STDOUT: %.loc7_27.1: %i32 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_1.68a]
// CHECK:STDOUT: %.loc7_27.2: %i32 = converted %int_1, %.loc7_27.1 [concrete = constants.%int_1.68a]
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%i32) [concrete = constants.%F.specific_fn.9db]
// CHECK:STDOUT: %F.call: %i32 = call %F.specific_fn(%.loc7_27.2)
// CHECK:STDOUT: %i32.loc7_17: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %n: %i32 = wrapper_binding n, %F.call
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %n.patt: %pattern_type.d94 = value_binding_pattern n [concrete = constants.%n.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%T) {
// CHECK:STDOUT: %T.patt.loc4_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_7.1 => constants.%T
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d1c4.1
// CHECK:STDOUT: %x.param_patt.loc4_16.2 => constants.%x.param_patt.91de5a.1
// CHECK:STDOUT: %x.patt.loc4_16.2 => constants.%x.patt.26065e.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%i32) {
// CHECK:STDOUT: %T.patt.loc4_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_7.1 => constants.%i32
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d94
// CHECK:STDOUT: %x.param_patt.loc4_16.2 => constants.%x.param_patt.051
// CHECK:STDOUT: %x.patt.loc4_16.2 => constants.%x.patt.0f7
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
// CHECK:STDOUT: %.loc4_42.2 => constants.%.acd
// CHECK:STDOUT: %.loc4_42.3 => constants.%.45b
// CHECK:STDOUT: %return.patt.loc4_42.2 => constants.%return.patt.f8b
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%U) {
// CHECK:STDOUT: %T.patt.loc4_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_7.1 => constants.%U
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.51d1c4.3
// CHECK:STDOUT: %x.param_patt.loc4_16.2 => constants.%x.param_patt.91de5a.2
// CHECK:STDOUT: %x.patt.loc4_16.2 => constants.%x.patt.26065e.2
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%require_complete.9443dd.2
// CHECK:STDOUT: %.loc4_42.2 => constants.%.a89f79.2
// CHECK:STDOUT: %.loc4_42.3 => constants.%.c5a291.2
// CHECK:STDOUT: %return.patt.loc4_42.2 => constants.%return.patt.5d1d5c.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -42,6 +42,19 @@ import library "lib";
fn Use(n: i32) -> (i32, i32) { return Pair(n); }
// --- form.carbon
library "[[@TEST_NAME]]";
fn RefId[T: type](ref x: T) -> ref auto { return x; }
fn ValId[T: type](x: T) -> val auto { return x; }
fn RefIdFromGeneric[T: type](ref x: T) -> ref T { return RefId(ref x); }
fn Use(ref n: i32) -> i32 {
let unused p: i32* = &RefIdFromGeneric(ref n);
let unused q: i32* = &RefId(ref n);
return ValId(n);
}
// CHECK:STDOUT: ; ---
// CHECK:STDOUT: ; ModuleID = 'generic.carbon'
// CHECK:STDOUT: source_filename = "generic.carbon"
@@ -284,3 +297,76 @@ fn Use(n: i32) -> (i32, i32) { return Pair(n); }
// CHECK:STDOUT: !112 = !DILocation(line: 3, column: 39, scope: !106)
// CHECK:STDOUT: !113 = !{!107}
// CHECK:STDOUT:
// CHECK:STDOUT: ; ---
// CHECK:STDOUT: ; ModuleID = 'form.carbon'
// CHECK:STDOUT: source_filename = "form.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CUse.Main(ptr %n) #0 !dbg !116 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %RefIdFromGeneric.call = call ptr @_CRefIdFromGeneric.Main.55456748a8a2eb70(ptr %n), !dbg !123
// CHECK:STDOUT: %RefId.call = call ptr @_CRefId.Main.55456748a8a2eb70(ptr %n), !dbg !129
// CHECK:STDOUT: %.loc10 = load i32, ptr %n, align 4, !dbg !133
// CHECK:STDOUT: %ValId.call = call i32 @_CValId.Main.55456748a8a2eb70(i32 %.loc10), !dbg !134
// CHECK:STDOUT: ret i32 %ValId.call, !dbg !135
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr ptr @_CRefIdFromGeneric.Main.55456748a8a2eb70(ptr %x) #0 !dbg !137 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %RefId.call = call ptr @_CRefId.Main.55456748a8a2eb70(ptr %x), !dbg !144
// CHECK:STDOUT: ret ptr %RefId.call, !dbg !145
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr ptr @_CRefId.Main.55456748a8a2eb70(ptr %x) #0 !dbg !147 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret ptr %x, !dbg !151
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @_CValId.Main.55456748a8a2eb70(i32 %x) #0 !dbg !153 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !157
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @_CRefId.Main.55456748a8a2eb70, { 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.dbg.cu = !{!115}
// CHECK:STDOUT: !llvm.module.flags = !{!2, !3}
// CHECK:STDOUT:
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK:STDOUT: !7 = !{!6, !6}
// CHECK:STDOUT: !8 = !DISubroutineType(types: !7)
// CHECK:STDOUT: !11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
// CHECK:STDOUT: !21 = !{!11, !6}
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
// CHECK:STDOUT: !114 = !DIFile(filename: "form.carbon", directory: "")
// CHECK:STDOUT: !115 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !114, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !116 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Main", scope: null, file: !114, line: 7, type: !8, spFlags: DISPFlagDefinition, unit: !115, retainedNodes: !136)
// CHECK:STDOUT: !117 = !DILocalVariable(arg: 1, scope: !116, type: !6)
// CHECK:STDOUT: !123 = !DILocation(line: 8, column: 25, scope: !116)
// CHECK:STDOUT: !129 = !DILocation(line: 9, column: 25, scope: !116)
// CHECK:STDOUT: !133 = !DILocation(line: 10, column: 16, scope: !116)
// CHECK:STDOUT: !134 = !DILocation(line: 10, column: 10, scope: !116)
// CHECK:STDOUT: !135 = !DILocation(line: 10, column: 3, scope: !116)
// CHECK:STDOUT: !136 = !{!117}
// CHECK:STDOUT: !137 = distinct !DISubprogram(name: "RefIdFromGeneric", linkageName: "_CRefIdFromGeneric.Main.55456748a8a2eb70", scope: null, file: !114, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !115, retainedNodes: !146)
// CHECK:STDOUT: !138 = !DILocalVariable(arg: 1, scope: !137, type: !6)
// CHECK:STDOUT: !144 = !DILocation(line: 5, column: 58, scope: !137)
// CHECK:STDOUT: !145 = !DILocation(line: 5, column: 51, scope: !137)
// CHECK:STDOUT: !146 = !{!138}
// CHECK:STDOUT: !147 = distinct !DISubprogram(name: "RefId", linkageName: "_CRefId.Main.55456748a8a2eb70", scope: null, file: !114, line: 3, type: !22, spFlags: DISPFlagDefinition, unit: !115, retainedNodes: !152)
// CHECK:STDOUT: !148 = !DILocalVariable(arg: 1, scope: !147, type: !6)
// CHECK:STDOUT: !151 = !DILocation(line: 3, column: 43, scope: !147)
// CHECK:STDOUT: !152 = !{!148}
// CHECK:STDOUT: !153 = distinct !DISubprogram(name: "ValId", linkageName: "_CValId.Main.55456748a8a2eb70", scope: null, file: !114, line: 4, type: !8, spFlags: DISPFlagDefinition, unit: !115, retainedNodes: !158)
// CHECK:STDOUT: !154 = !DILocalVariable(arg: 1, scope: !153, type: !6)
// CHECK:STDOUT: !157 = !DILocation(line: 4, column: 39, scope: !153)
// CHECK:STDOUT: !158 = !{!154}
// CHECK:STDOUT: