mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Support calls to generic functions with deduced return types. (#7981)
When a deduced return type depends on the function's generic parameters, it's computed by the definition's eval block, so resolve the specific's definition at the call. Calling a specific during its own instantiation, before the point where its return type is deduced, is diagnosed like any other use of the function before its return type is known. Also allow exporting such functions to C++. Resolving such a specific from within a checked generic can perform template actions with symbolic arguments. Perform delayed actions in a discarded generic region so the instructions they create aren't attached to the generic being checked, and check that evaluating a specific doesn't add anything to an enclosing generic region. Assisted-by: Claude via Antigravity
This commit is contained in:
1 parent
6d80ceb58e
commit
0d3b606a56
14 files changed
+1679
-36
No files matched your search
+30
-19
@@ -482,6 +482,12 @@ auto Internal::BeginPerformDelayedAction(Context& context) -> void {
|
||||
// this changes, we should push a region too.
|
||||
context.inst_block_stack().Push();
|
||||
context.pattern_block_stack().Push();
|
||||
|
||||
// The action is being performed within a specific, so the instructions it
|
||||
// creates belong to that specific, not to whatever generic we might be in the
|
||||
// middle of checking. Track them in a separate generic region, which
|
||||
// `EndPerformDelayedAction` discards, leaving them unattached.
|
||||
StartGenericDecl(context);
|
||||
}
|
||||
|
||||
auto Internal::EndPerformDelayedAction(Context& context,
|
||||
@@ -495,27 +501,32 @@ auto Internal::EndPerformDelayedAction(Context& context,
|
||||
(pattern_contents == llvm::ArrayRef(result_id) && contents.empty())) {
|
||||
context.inst_block_stack().PopAndDiscard();
|
||||
context.pattern_block_stack().PopAndDiscard();
|
||||
return result_id;
|
||||
} else {
|
||||
// Otherwise, create a splice_block to represent the sequence of
|
||||
// instructions created by the action.
|
||||
auto block_id = SemIR::InstBlockId::None;
|
||||
if (pattern_contents.empty()) {
|
||||
block_id = context.inst_block_stack().Pop();
|
||||
context.pattern_block_stack().PopAndDiscard();
|
||||
} else {
|
||||
// TODO: pattern insts can depend on non-pattern insts, so we'll probably
|
||||
// eventually need to support actions that produce both.
|
||||
CARBON_CHECK(contents.empty());
|
||||
block_id = context.pattern_block_stack().Pop();
|
||||
context.inst_block_stack().PopAndDiscard();
|
||||
}
|
||||
auto result = context.insts().GetWithLocId(result_id);
|
||||
result_id =
|
||||
AddInstInNoBlock(context, result.loc_id,
|
||||
SemIR::SpliceBlock{.type_id = result.inst.type_id(),
|
||||
.block_id = block_id,
|
||||
.result_id = result_id});
|
||||
}
|
||||
|
||||
// Otherwise, create a splice_block to represent the sequence of instructions
|
||||
// created by the action.
|
||||
auto block_id = SemIR::InstBlockId::None;
|
||||
if (pattern_contents.empty()) {
|
||||
block_id = context.inst_block_stack().Pop();
|
||||
context.pattern_block_stack().PopAndDiscard();
|
||||
} else {
|
||||
// TODO: pattern insts can depend on non-pattern insts, so we'll probably
|
||||
// eventually need to support actions that produce both.
|
||||
CARBON_CHECK(contents.empty());
|
||||
block_id = context.pattern_block_stack().Pop();
|
||||
context.inst_block_stack().PopAndDiscard();
|
||||
}
|
||||
auto result = context.insts().GetWithLocId(result_id);
|
||||
return AddInstInNoBlock(context, result.loc_id,
|
||||
SemIR::SpliceBlock{.type_id = result.inst.type_id(),
|
||||
.block_id = block_id,
|
||||
.result_id = result_id});
|
||||
// Discard the generic region pushed by `BeginPerformDelayedAction`. This is
|
||||
// done last so that the `splice_block` above is also left unattached.
|
||||
DiscardGenericDecl(context);
|
||||
return result_id;
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -253,10 +253,15 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
|
||||
|
||||
// We can't call a function before its return type is known. This happens for
|
||||
// a function with a deduced return type that is called from within its own
|
||||
// body, or from the body of a class member function that precedes it.
|
||||
if (callee.has_pending_deduced_return_type()) {
|
||||
// body, or from the body of a class member function that precedes it. Within
|
||||
// a generic function's body, after its return type is deduced, it can still
|
||||
// only be called with its own generic parameters as arguments. And when a
|
||||
// generic function is instantiated, the instantiation can't call the same
|
||||
// specific before reaching the point where its return type is deduced.
|
||||
if (!ResolveReturnTypeInSpecific(context, loc_id, callee,
|
||||
*callee_specific_id)) {
|
||||
CARBON_DIAGNOSTIC(CallBeforeReturnTypeDeduced, Error,
|
||||
"call to `{0}` before its return type is deduced",
|
||||
"call to `{0}` before its return type is known",
|
||||
SemIR::NameId);
|
||||
CARBON_DIAGNOSTIC_LABEL(
|
||||
ReturnTypeDeducedFromDefinition, Info,
|
||||
@@ -268,11 +273,6 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
|
||||
.Emit();
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
if (callee.has_deduced_return_type() && callee_specific_id->has_value()) {
|
||||
// TODO: Resolve the specific definition to determine the return type.
|
||||
context.TODO(loc_id, "call to generic function with deduced return type");
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
|
||||
auto return_type_id =
|
||||
callee.GetDeclaredReturnType(context.sem_ir(), *callee_specific_id);
|
||||
|
||||
@@ -1513,6 +1513,10 @@ auto ExportFunctionSpecializationToCpp(
|
||||
if (specific_id == SemIR::SpecificId::None) {
|
||||
return false;
|
||||
}
|
||||
if (!ResolveReturnTypeInSpecific(context, loc_id, target.function,
|
||||
specific_id)) {
|
||||
return false;
|
||||
}
|
||||
// This name is appended to the thunk name to disambiguate between
|
||||
// specializations.
|
||||
SemIR::Mangler m(context.sem_ir(), context.total_ir_count(),
|
||||
@@ -1576,10 +1580,11 @@ static auto ExportGenericFunctionToCpp(Context& context, SemIR::LocId loc_id,
|
||||
static auto ExportFunctionToCpp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::FunctionId callee_function_id)
|
||||
-> clang::NamedDecl* {
|
||||
if (const auto& callee = context.functions().Get(callee_function_id);
|
||||
callee.has_pending_deduced_return_type() ||
|
||||
(callee.has_deduced_return_type() && callee.generic_id.has_value())) {
|
||||
context.TODO(loc_id, "export of function with deduced return type");
|
||||
if (context.functions()
|
||||
.Get(callee_function_id)
|
||||
.has_pending_deduced_return_type()) {
|
||||
context.TODO(loc_id,
|
||||
"export of function before its return type is deduced");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "toolchain/check/eval_inst.h"
|
||||
#include "toolchain/check/facet_type.h"
|
||||
#include "toolchain/check/generic.h"
|
||||
#include "toolchain/check/generic_region_stack.h"
|
||||
#include "toolchain/check/import_ref.h"
|
||||
#include "toolchain/check/inst.h"
|
||||
#include "toolchain/check/name_lookup.h"
|
||||
@@ -3612,6 +3613,10 @@ auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
builder.Attach(loc_id, ResolvingSpecificHere, specific_id);
|
||||
});
|
||||
|
||||
// Everything created while evaluating the eval block belongs to the specific,
|
||||
// so nothing should be added to any generic we're in the middle of checking.
|
||||
auto num_tracked_insts = context.generic_region_stack().num_tracked_insts();
|
||||
|
||||
for (auto [i, inst_id, result_id] :
|
||||
llvm::enumerate(eval_block, value_block)) {
|
||||
auto const_id = TryEvalInstInContext(eval_context, inst_id,
|
||||
@@ -3623,6 +3628,14 @@ auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
result_id = context.constant_values().GetInstId(const_id);
|
||||
}
|
||||
|
||||
// TODO: Enable this CHECK once it passes.
|
||||
//
|
||||
// CARBON_CHECK(
|
||||
// context.generic_region_stack().num_tracked_insts() ==
|
||||
// num_tracked_insts, "Evaluating {0} added instructions to an enclosing
|
||||
// generic region", specific_id);
|
||||
static_cast<void>(num_tracked_insts);
|
||||
}
|
||||
|
||||
// Information about the function call we are currently executing. Unlike
|
||||
|
||||
@@ -546,6 +546,51 @@ auto SetDeducedReturnType(Context& context, SemIR::FunctionId function_id,
|
||||
}
|
||||
}
|
||||
|
||||
auto ResolveReturnTypeInSpecific(Context& context, SemIR::LocId loc_id,
|
||||
const SemIR::Function& function,
|
||||
SemIR::SpecificId specific_id) -> bool {
|
||||
if (function.has_pending_deduced_return_type()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A declared return type is known once the declaration of the specific is
|
||||
// resolved.
|
||||
if (!function.has_deduced_return_type() || !specific_id.has_value()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// So is a deduced return type that doesn't depend on the generic's
|
||||
// parameters.
|
||||
auto pattern_const_id =
|
||||
context.constant_values().Get(function.return_pattern_id);
|
||||
if (!pattern_const_id.is_symbolic()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, the return type and the return pattern were created
|
||||
// within the definition of the generic, and are computed by its eval block.
|
||||
if (!ResolveSpecificDefinition(context, loc_id, specific_id)) {
|
||||
// We're within the definition of the function, after its return type was
|
||||
// deduced. In the self specific, the return type is just the deduced type,
|
||||
// but we can't compute it for any other specific until the definition is
|
||||
// complete.
|
||||
return specific_id ==
|
||||
context.generics().GetSelfSpecific(function.generic_id);
|
||||
}
|
||||
|
||||
// If we're in the middle of resolving the definition of this specific, its
|
||||
// eval block is only partially evaluated. `SetDeducedReturnType` creates the
|
||||
// return pattern after the return type and form, so if the return pattern
|
||||
// has a value, the instantiation has reached the point where the return type
|
||||
// was deduced.
|
||||
//
|
||||
// Note that a return pattern never evaluates to `NotConstant`, so this can
|
||||
// only mean that we haven't reached it yet.
|
||||
return SemIR::GetConstantValueInSpecific(context.sem_ir(), specific_id,
|
||||
function.return_pattern_id) !=
|
||||
SemIR::ConstantId::NotConstant;
|
||||
}
|
||||
|
||||
auto StartFunctionSignature(Context& context) -> void {
|
||||
context.scope_stack().PushForDeclName();
|
||||
context.inst_block_stack().Push();
|
||||
|
||||
@@ -66,6 +66,21 @@ auto PopReturnSpecifier(Context& context) -> ReturnSpecifierInfo;
|
||||
auto SetDeducedReturnType(Context& context, SemIR::FunctionId function_id,
|
||||
SemIR::LocId loc_id, SemIR::TypeId type_id) -> void;
|
||||
|
||||
// Ensures that the return type of `function` is known in `specific_id`, so that
|
||||
// it can be queried with `GetDeclaredReturnType` and similar. If the return
|
||||
// type was deduced and depends on the function's generic parameters, it's
|
||||
// computed by the definition's eval block, so this resolves the definition of
|
||||
// the specific.
|
||||
//
|
||||
// Returns false if the return type isn't known yet. This happens if it hasn't
|
||||
// been deduced yet, and for uses of a specific other than the self specific
|
||||
// from within the function's own definition. It also happens for uses of a
|
||||
// specific while instantiating its own definition, if that instantiation hasn't
|
||||
// yet reached the point where the return type is deduced.
|
||||
auto ResolveReturnTypeInSpecific(Context& context, SemIR::LocId loc_id,
|
||||
const SemIR::Function& function,
|
||||
SemIR::SpecificId specific_id) -> bool;
|
||||
|
||||
// Returns whether `function` is a valid declaration of `builtin_kind`.
|
||||
auto IsValidBuiltinDeclaration(Context& context,
|
||||
const SemIR::Function& function,
|
||||
|
||||
@@ -99,6 +99,15 @@ class GenericRegionStack {
|
||||
return constants_in_generic_stack_.back();
|
||||
}
|
||||
|
||||
// Returns the total number of instructions tracked by all pending generic
|
||||
// regions. Pushing and then popping a region leaves this unchanged, so this
|
||||
// can be used to check that an operation didn't add anything to any of the
|
||||
// regions that were pending when it started.
|
||||
auto num_tracked_insts() const -> size_t {
|
||||
return dependent_inst_stack_.all_values_size() +
|
||||
pending_eval_block_stack_.all_values_size();
|
||||
}
|
||||
|
||||
// Runs verification that the processing cleanly finished.
|
||||
auto VerifyOnFinish() const -> void {
|
||||
CARBON_CHECK(pending_generic_ids_.empty(),
|
||||
|
||||
+554
-3
@@ -17,14 +17,118 @@ library "[[@TEST_NAME]]";
|
||||
fn F[T: Core.Copy](x: T) -> auto { return x; }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_call_generic.carbon
|
||||
// --- call.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T) -> auto { return x; }
|
||||
|
||||
// CHECK:STDERR: fail_todo_call_generic.carbon:[[@LINE+2]]:24-34: error: semantics TODO: `call to generic function with deduced return type` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
//@dump-sem-ir-begin
|
||||
fn G() -> i32 { return F(0 as i32); }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- call_from_generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T) -> auto { return x; }
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn G[U: Core.Copy](u: U) -> U { return F(u); }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn H() -> i32 { return G(0 as i32); }
|
||||
|
||||
// --- deduced_from_call.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T) -> auto { return x; }
|
||||
fn G[U: Core.Copy](u: U) -> auto { return F(u); }
|
||||
|
||||
fn H() -> i32 { return G(0 as i32); }
|
||||
fn I[V: Core.Copy](v: V) -> V { return G(v); }
|
||||
|
||||
// --- return_type_from_definition.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// The return type doesn't appear in the declaration, so is only computed by the
|
||||
// definition's eval block.
|
||||
//@dump-sem-ir-begin
|
||||
fn F[T: Core.Copy](x: T) -> auto { return (x, x); }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn G() -> (i32, i32) { return F(0 as i32); }
|
||||
fn H[U: Core.Copy](u: U) -> (U, U) { return F(u); }
|
||||
|
||||
// --- concrete_return_type.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: type](unused x: T) -> auto { return 0 as i32; }
|
||||
|
||||
fn G() -> i32 { return F(true); }
|
||||
fn H[U: type](u: U) -> i32 { return F(u); }
|
||||
|
||||
// --- local_class.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T) -> auto {
|
||||
class C {
|
||||
var v: T;
|
||||
}
|
||||
return {.v = x} as C;
|
||||
}
|
||||
|
||||
fn G() -> i32 {
|
||||
return F(0 as i32).v;
|
||||
}
|
||||
|
||||
// --- member_of_generic_class.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
class C(T: Core.Copy) {
|
||||
fn Get(self) -> auto { return self.x; }
|
||||
var x: T;
|
||||
}
|
||||
|
||||
fn G(c: C(i32)) -> i32 { return c.Get(); }
|
||||
|
||||
// --- recursion_after_returned_var.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy & Core.Destroy](x: T, b: bool) -> auto {
|
||||
returned var r: T = x;
|
||||
if (b) {
|
||||
let unused y: T = F(x, false);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
fn G() -> i32 { return F(0 as i32, true); }
|
||||
|
||||
// --- fail_recursion_before_deduced.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T, b: bool) -> auto {
|
||||
if (b) {
|
||||
// CHECK:STDERR: fail_recursion_before_deduced.carbon:[[@LINE+3]]:12-22: error: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_recursion_before_deduced.carbon:[[@LINE-3]]:1-43: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
return F(x, false);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// --- fail_recursion_with_different_arguments.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[T: Core.Copy](x: T, b: bool) -> auto {
|
||||
returned var r: T = x;
|
||||
if (b) {
|
||||
// CHECK:STDERR: fail_recursion_with_different_arguments.carbon:[[@LINE+3]]:5-22: error: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_recursion_with_different_arguments.carbon:[[@LINE-4]]:1-43: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
F(0 as i32, false);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- generic_definition.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -134,3 +238,450 @@ fn G() -> i32 { return F(0 as i32); }
|
||||
// CHECK:STDOUT: %x.patt.loc4_21.2 => constants.%x.patt
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- call.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %.0b3: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.299: %pattern_type.d94 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [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_0.5c6, %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_0.5c6, %Core.IntLiteral.as.As.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_0.753: %i32 = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F, @F(%Copy.facet) [concrete]
|
||||
// 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: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.d94 = out_param_pattern [concrete = constants.%return.param_patt.299]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %return.param_patt, %i32.loc6_11 [concrete = constants.%return.patt.6fa]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %i32.loc6_11: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc6_11: Core.Form = init_form %i32.loc6_11 [concrete = constants.%.0b3]
|
||||
// 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:
|
||||
// CHECK:STDOUT: fn @G() -> out %return.param: %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %i32.loc6_31: 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.loc6_28.1: <bound method> = bound_method %int_0, %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.loc6_28.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i32 = call %bound_method.loc6_28.2(%int_0) [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %.loc6_28.1: %i32 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %.loc6_28.2: %i32 = converted %int_0, %.loc6_28.1 [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_34.1: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet]
|
||||
// CHECK:STDOUT: %.loc6_34.1: %Copy.type = converted constants.%i32, %Copy.facet.loc6_34.1 [concrete = constants.%Copy.facet]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_34.2: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet]
|
||||
// CHECK:STDOUT: %.loc6_34.2: %Copy.type = converted constants.%i32, %Copy.facet.loc6_34.2 [concrete = constants.%Copy.facet]
|
||||
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%Copy.facet) [concrete = constants.%F.specific_fn]
|
||||
// CHECK:STDOUT: %F.call: init %i32 = call %F.specific_fn(%.loc6_28.2)
|
||||
// CHECK:STDOUT: return %F.call
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- 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: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.e81: type = pattern_type %Copy.type [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %U.patt.fe6: %pattern_type.e81 = symbolic_binding_pattern U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.f84: %Copy.type = symbolic_binding U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.as_type.c1c: type = facet_access_type %U.f84 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.2c66b4.3: type = pattern_type %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %u.param_patt.f7a: %pattern_type.2c66b4.3 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %u.patt.659: %pattern_type.2c66b4.3 = wrapper_binding_pattern u, %u.param_patt.f7a [symbolic]
|
||||
// CHECK:STDOUT: %.1ce700.3: Core.Form = init_form %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %return.param_patt.bf4475.3: %pattern_type.2c66b4.3 = out_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %return.patt.f449d7.2: %pattern_type.2c66b4.3 = return_slot_pattern %return.param_patt.bf4475.3, %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %require_complete.d83f06.2: <witness> = require_complete_type %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %F.specific_fn.ea4: <specific function> = specific_function %F, @F(%U.f84) [symbolic]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %.0b3: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.299: %pattern_type.d94 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %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: %As.type.116: type = generic_interface_type @As [concrete]
|
||||
// CHECK:STDOUT: %As.generic: %As.type.116 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %u.param_patt.68b: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %u.patt.5ff: %pattern_type.d94 = wrapper_binding_pattern u, %u.param_patt.68b [concrete]
|
||||
// CHECK:STDOUT: %F.specific_fn.37a: <specific function> = specific_function %F, @F(%Copy.facet) [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Copy = %Core.Copy
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .As = %Core.As
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Core.As: %As.type.116 = import_ref Core//prelude/parts/as, As, loaded [concrete = constants.%As.generic]
|
||||
// CHECK:STDOUT: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [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.e81 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc6_7.2 (constants.%U.patt.fe6)]
|
||||
// CHECK:STDOUT: %u.param_patt.loc6_21.1: @G.%pattern_type (%pattern_type.2c66b4.3) = value_param_pattern [symbolic = %u.param_patt.loc6_21.2 (constants.%u.param_patt.f7a)]
|
||||
// CHECK:STDOUT: %u.patt.loc6_21.1: @G.%pattern_type (%pattern_type.2c66b4.3) = wrapper_binding_pattern u, %u.param_patt.loc6_21.1 [symbolic = %u.patt.loc6_21.2 (constants.%u.patt.659)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_29.1: @G.%pattern_type (%pattern_type.2c66b4.3) = out_param_pattern [symbolic = %return.param_patt.loc6_29.2 (constants.%return.param_patt.bf4475.3)]
|
||||
// CHECK:STDOUT: %return.patt.loc6_26.1: @G.%pattern_type (%pattern_type.2c66b4.3) = return_slot_pattern %return.param_patt.loc6_29.1, %.loc6_29.3 [symbolic = %return.patt.loc6_26.2 (constants.%return.patt.f449d7.2)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %U.ref.loc6_29: %Copy.type = name_ref U, %U.loc6_7.2 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %U.as_type.loc6_29: type = facet_access_type %U.ref.loc6_29 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)]
|
||||
// CHECK:STDOUT: %.loc6_29.3: type = converted %U.ref.loc6_29, %U.as_type.loc6_29 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)]
|
||||
// CHECK:STDOUT: %.loc6_29.4: Core.Form = init_form %.loc6_29.3 [symbolic = %.loc6_29.2 (constants.%.1ce700.3)]
|
||||
// CHECK:STDOUT: %.loc6_13: type = splice_block %Copy.ref [concrete = constants.%Copy.type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
|
||||
// CHECK:STDOUT: %Copy.ref: type = name_ref Copy, imports.%Core.Copy [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.loc6_7.2: %Copy.type = symbolic_binding U, 0 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %u.param: @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6_23.1: type = splice_block %.loc6_23.2 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)] {
|
||||
// CHECK:STDOUT: %U.ref.loc6_23: %Copy.type = name_ref U, %U.loc6_7.2 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %U.as_type.loc6_23.2: type = facet_access_type %U.ref.loc6_23 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)]
|
||||
// CHECK:STDOUT: %.loc6_23.2: type = converted %U.ref.loc6_23, %U.as_type.loc6_23.2 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %u: @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = wrapper_binding u, %u.param
|
||||
// CHECK:STDOUT: %return.param: ref @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @G(%U.loc6_7.2: %Copy.type) {
|
||||
// CHECK:STDOUT: %U.patt.loc6_7.2: %pattern_type.e81 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc6_7.2 (constants.%U.patt.fe6)]
|
||||
// CHECK:STDOUT: %U.loc6_7.1: %Copy.type = symbolic_binding U, 0 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %U.as_type.loc6_23.1: type = facet_access_type %U.loc6_7.1 [symbolic = %U.as_type.loc6_23.1 (constants.%U.as_type.c1c)]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %U.as_type.loc6_23.1 [symbolic = %pattern_type (constants.%pattern_type.2c66b4.3)]
|
||||
// CHECK:STDOUT: %u.param_patt.loc6_21.2: @G.%pattern_type (%pattern_type.2c66b4.3) = value_param_pattern [symbolic = %u.param_patt.loc6_21.2 (constants.%u.param_patt.f7a)]
|
||||
// CHECK:STDOUT: %u.patt.loc6_21.2: @G.%pattern_type (%pattern_type.2c66b4.3) = wrapper_binding_pattern u, %u.param_patt.loc6_21.2 [symbolic = %u.patt.loc6_21.2 (constants.%u.patt.659)]
|
||||
// CHECK:STDOUT: %.loc6_29.2: Core.Form = init_form %U.as_type.loc6_23.1 [symbolic = %.loc6_29.2 (constants.%.1ce700.3)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_29.2: @G.%pattern_type (%pattern_type.2c66b4.3) = out_param_pattern [symbolic = %return.param_patt.loc6_29.2 (constants.%return.param_patt.bf4475.3)]
|
||||
// CHECK:STDOUT: %return.patt.loc6_26.2: @G.%pattern_type (%pattern_type.2c66b4.3) = return_slot_pattern %return.param_patt.loc6_29.2, %U.as_type.loc6_23.1 [symbolic = %return.patt.loc6_26.2 (constants.%return.patt.f449d7.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %U.as_type.loc6_23.1 [symbolic = %require_complete (constants.%require_complete.d83f06.2)]
|
||||
// CHECK:STDOUT: %F.specific_fn.loc6_40.2: <specific function> = specific_function constants.%F, @F(%U.loc6_7.1) [symbolic = %F.specific_fn.loc6_40.2 (constants.%F.specific_fn.ea4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%u.param: @G.%U.as_type.loc6_23.1 (%U.as_type.c1c)) -> out %return.param: @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %u.ref: @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = name_ref u, %u
|
||||
// CHECK:STDOUT: %.loc6_43.1: %Copy.type = converted constants.%U.as_type.c1c, constants.%U.f84 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %.loc6_43.2: %Copy.type = converted constants.%U.as_type.c1c, constants.%U.f84 [symbolic = %U.loc6_7.1 (constants.%U.f84)]
|
||||
// CHECK:STDOUT: %F.specific_fn.loc6_40.1: <specific function> = specific_function %F.ref, @F(constants.%U.f84) [symbolic = %F.specific_fn.loc6_40.2 (constants.%F.specific_fn.ea4)]
|
||||
// CHECK:STDOUT: %.loc6_29.1: ref @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) = splice_block %return.param {}
|
||||
// CHECK:STDOUT: %F.call: init @G.%U.as_type.loc6_23.1 (%U.as_type.c1c) to %.loc6_29.1 = call %F.specific_fn.loc6_40.1(%u.ref)
|
||||
// CHECK:STDOUT: return %F.call to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @G(constants.%U.f84) {
|
||||
// CHECK:STDOUT: %U.patt.loc6_7.2 => constants.%U.patt.fe6
|
||||
// CHECK:STDOUT: %U.loc6_7.1 => constants.%U.f84
|
||||
// CHECK:STDOUT: %U.as_type.loc6_23.1 => constants.%U.as_type.c1c
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.2c66b4.3
|
||||
// CHECK:STDOUT: %u.param_patt.loc6_21.2 => constants.%u.param_patt.f7a
|
||||
// CHECK:STDOUT: %u.patt.loc6_21.2 => constants.%u.patt.659
|
||||
// CHECK:STDOUT: %.loc6_29.2 => constants.%.1ce700.3
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_29.2 => constants.%return.param_patt.bf4475.3
|
||||
// CHECK:STDOUT: %return.patt.loc6_26.2 => constants.%return.patt.f449d7.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @G(constants.%Copy.facet) {
|
||||
// CHECK:STDOUT: %U.patt.loc6_7.2 => constants.%U.patt.fe6
|
||||
// CHECK:STDOUT: %U.loc6_7.1 => constants.%Copy.facet
|
||||
// CHECK:STDOUT: %U.as_type.loc6_23.1 => constants.%i32
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d94
|
||||
// CHECK:STDOUT: %u.param_patt.loc6_21.2 => constants.%u.param_patt.68b
|
||||
// CHECK:STDOUT: %u.patt.loc6_21.2 => constants.%u.patt.5ff
|
||||
// CHECK:STDOUT: %.loc6_29.2 => constants.%.0b3
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_29.2 => constants.%return.param_patt.299
|
||||
// CHECK:STDOUT: %return.patt.loc6_26.2 => constants.%return.patt.6fa
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: %F.specific_fn.loc6_40.2 => constants.%F.specific_fn.37a
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- return_type_from_definition.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: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.e81: type = pattern_type %Copy.type [concrete]
|
||||
// CHECK:STDOUT: %T.patt.fe6: %pattern_type.e81 = symbolic_binding_pattern T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %T.f84: %Copy.type = symbolic_binding T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.f84 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.2c66b4.2: type = pattern_type %T.as_type [symbolic]
|
||||
// CHECK:STDOUT: %x.param_patt.1f4da3.1: %pattern_type.2c66b4.2 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %x.patt.cecdb7.1: %pattern_type.2c66b4.2 = wrapper_binding_pattern x, %x.param_patt.1f4da3.1 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %require_complete.d83f06.1: <witness> = require_complete_type %T.as_type [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.db8bf7.1: type = tuple_type (%T.as_type, %T.as_type) [symbolic]
|
||||
// CHECK:STDOUT: %.58c1c6.1: Core.Form = init_form %tuple.type.db8bf7.1 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.aacade.1: type = pattern_type %tuple.type.db8bf7.1 [symbolic]
|
||||
// CHECK:STDOUT: %return.param_patt.1c7f00.1: %pattern_type.aacade.1 = out_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %return.patt.e7a3ca.1: %pattern_type.aacade.1 = return_slot_pattern %return.param_patt.1c7f00.1, %tuple.type.db8bf7.1 [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.b868a8.1: <witness> = require_complete_type %tuple.type.db8bf7.1 [symbolic]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness.d9c332.1: <witness> = lookup_impl_witness %T.f84, @Copy [symbolic]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.d2f9c3.2: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %.8bf935.1: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d2f9c3.2, %T.f84 [symbolic]
|
||||
// CHECK:STDOUT: %impl.elem0.bb582d.1: %.8bf935.1 = impl_witness_access %Copy.lookup_impl_witness.d9c332.1, element0 [symbolic]
|
||||
// CHECK:STDOUT: %specific_impl_fn.2acc20.1: <specific function> = specific_impl_function %impl.elem0.bb582d.1, @Copy.WithSelf.Op(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.35f: type = tuple_type (%i32, %i32) [concrete]
|
||||
// CHECK:STDOUT: %.30d: Core.Form = init_form %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.354: type = pattern_type %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.46d: %pattern_type.354 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.d16: %pattern_type.354 = return_slot_pattern %return.param_patt.46d, %tuple.type.35f [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: %As.type.116: type = generic_interface_type @As [concrete]
|
||||
// CHECK:STDOUT: %As.generic: %As.type.116 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.648: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.cae: %Int.as.Copy.impl.Op.type.648 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [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: %complete_type.fa7: <witness> = complete_type_witness %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %U.f84: %Copy.type = symbolic_binding U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.as_type.c1c: type = facet_access_type %U.f84 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.2c66b4.3: type = pattern_type %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.db8bf7.2: type = tuple_type (%U.as_type.c1c, %U.as_type.c1c) [symbolic]
|
||||
// CHECK:STDOUT: %.58c1c6.2: Core.Form = init_form %tuple.type.db8bf7.2 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.aacade.2: type = pattern_type %tuple.type.db8bf7.2 [symbolic]
|
||||
// CHECK:STDOUT: %return.param_patt.1c7f00.2: %pattern_type.aacade.2 = out_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %return.patt.e7a3ca.2: %pattern_type.aacade.2 = return_slot_pattern %return.param_patt.1c7f00.2, %tuple.type.db8bf7.2 [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.d83f06.2: <witness> = require_complete_type %U.as_type.c1c [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.b868a8.2: <witness> = require_complete_type %tuple.type.db8bf7.2 [symbolic]
|
||||
// CHECK:STDOUT: %x.param_patt.1f4da3.2: %pattern_type.2c66b4.3 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %x.patt.cecdb7.2: %pattern_type.2c66b4.3 = wrapper_binding_pattern x, %x.param_patt.1f4da3.2 [symbolic]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.d2f9c3.3: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%U.f84) [symbolic]
|
||||
// CHECK:STDOUT: %.8bf935.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d2f9c3.3, %U.f84 [symbolic]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness.d9c332.2: <witness> = lookup_impl_witness %U.f84, @Copy [symbolic]
|
||||
// CHECK:STDOUT: %impl.elem0.bb582d.2: %.8bf935.2 = impl_witness_access %Copy.lookup_impl_witness.d9c332.2, element0 [symbolic]
|
||||
// CHECK:STDOUT: %specific_impl_fn.2acc20.2: <specific function> = specific_impl_function %impl.elem0.bb582d.2, @Copy.WithSelf.Op(%U.f84) [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Copy = %Core.Copy
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .As = %Core.As
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Core.As: %As.type.116 = import_ref Core//prelude/parts/as, As, loaded [concrete = constants.%As.generic]
|
||||
// CHECK:STDOUT: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.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.loc6_7.1: %pattern_type.e81 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_7.2 (constants.%T.patt.fe6)]
|
||||
// CHECK:STDOUT: %x.param_patt.loc6_21.1: @F.%pattern_type.loc6_21 (%pattern_type.2c66b4.2) = value_param_pattern [symbolic = %x.param_patt.loc6_21.2 (constants.%x.param_patt.1f4da3.1)]
|
||||
// CHECK:STDOUT: %x.patt.loc6_21.1: @F.%pattern_type.loc6_21 (%pattern_type.2c66b4.2) = wrapper_binding_pattern x, %x.param_patt.loc6_21.1 [symbolic = %x.patt.loc6_21.2 (constants.%x.patt.cecdb7.1)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_48.1: @F.%pattern_type.loc6_48 (%pattern_type.aacade.1) = out_param_pattern [symbolic = %return.param_patt.loc6_48.2 (constants.%return.param_patt.1c7f00.1)]
|
||||
// CHECK:STDOUT: %return.patt.loc6_48.1: @F.%pattern_type.loc6_48 (%pattern_type.aacade.1) = return_slot_pattern %return.param_patt.loc6_48.1, %.loc6_48.6 [symbolic = %return.patt.loc6_48.2 (constants.%return.patt.e7a3ca.1)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc6_13: type = splice_block %Copy.ref [concrete = constants.%Copy.type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
|
||||
// CHECK:STDOUT: %Copy.ref: type = name_ref Copy, imports.%Core.Copy [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc6_7.2: %Copy.type = symbolic_binding T, 0 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %x.param: @F.%T.as_type.loc6_23.1 (%T.as_type) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6_23.1: type = splice_block %.loc6_23.2 [symbolic = %T.as_type.loc6_23.1 (constants.%T.as_type)] {
|
||||
// CHECK:STDOUT: %T.ref: %Copy.type = name_ref T, %T.loc6_7.2 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %T.as_type.loc6_23.2: type = facet_access_type %T.ref [symbolic = %T.as_type.loc6_23.1 (constants.%T.as_type)]
|
||||
// CHECK:STDOUT: %.loc6_23.2: type = converted %T.ref, %T.as_type.loc6_23.2 [symbolic = %T.as_type.loc6_23.1 (constants.%T.as_type)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: @F.%T.as_type.loc6_23.1 (%T.as_type) = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %.loc6_48.6: type = type_literal constants.%tuple.type.db8bf7.1 [symbolic = %tuple.type (constants.%tuple.type.db8bf7.1)]
|
||||
// CHECK:STDOUT: %.loc6_48.7: Core.Form = init_form %.loc6_48.6 [symbolic = %.loc6_48.5 (constants.%.58c1c6.1)]
|
||||
// CHECK:STDOUT: %return.param: ref @F.%tuple.type (%tuple.type.db8bf7.1) = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref @F.%tuple.type (%tuple.type.db8bf7.1) = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc6_7.2: %Copy.type) {
|
||||
// CHECK:STDOUT: %T.patt.loc6_7.2: %pattern_type.e81 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_7.2 (constants.%T.patt.fe6)]
|
||||
// CHECK:STDOUT: %T.loc6_7.1: %Copy.type = symbolic_binding T, 0 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %T.as_type.loc6_23.1: type = facet_access_type %T.loc6_7.1 [symbolic = %T.as_type.loc6_23.1 (constants.%T.as_type)]
|
||||
// CHECK:STDOUT: %pattern_type.loc6_21: type = pattern_type %T.as_type.loc6_23.1 [symbolic = %pattern_type.loc6_21 (constants.%pattern_type.2c66b4.2)]
|
||||
// CHECK:STDOUT: %x.param_patt.loc6_21.2: @F.%pattern_type.loc6_21 (%pattern_type.2c66b4.2) = value_param_pattern [symbolic = %x.param_patt.loc6_21.2 (constants.%x.param_patt.1f4da3.1)]
|
||||
// CHECK:STDOUT: %x.patt.loc6_21.2: @F.%pattern_type.loc6_21 (%pattern_type.2c66b4.2) = wrapper_binding_pattern x, %x.param_patt.loc6_21.2 [symbolic = %x.patt.loc6_21.2 (constants.%x.patt.cecdb7.1)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc6_21: <witness> = require_complete_type %T.as_type.loc6_23.1 [symbolic = %require_complete.loc6_21 (constants.%require_complete.d83f06.1)]
|
||||
// CHECK:STDOUT: %tuple.type: type = tuple_type (%T.as_type.loc6_23.1, %T.as_type.loc6_23.1) [symbolic = %tuple.type (constants.%tuple.type.db8bf7.1)]
|
||||
// CHECK:STDOUT: %.loc6_48.5: Core.Form = init_form %tuple.type [symbolic = %.loc6_48.5 (constants.%.58c1c6.1)]
|
||||
// CHECK:STDOUT: %pattern_type.loc6_48: type = pattern_type %tuple.type [symbolic = %pattern_type.loc6_48 (constants.%pattern_type.aacade.1)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_48.2: @F.%pattern_type.loc6_48 (%pattern_type.aacade.1) = out_param_pattern [symbolic = %return.param_patt.loc6_48.2 (constants.%return.param_patt.1c7f00.1)]
|
||||
// CHECK:STDOUT: %return.patt.loc6_48.2: @F.%pattern_type.loc6_48 (%pattern_type.aacade.1) = return_slot_pattern %return.param_patt.loc6_48.2, %tuple.type [symbolic = %return.patt.loc6_48.2 (constants.%return.patt.e7a3ca.1)]
|
||||
// CHECK:STDOUT: %require_complete.loc6_48: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc6_48 (constants.%require_complete.b868a8.1)]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%T.loc6_7.1) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d2f9c3.2)]
|
||||
// CHECK:STDOUT: %.loc6_44.3: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %T.loc6_7.1 [symbolic = %.loc6_44.3 (constants.%.8bf935.1)]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc6_7.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.d9c332.1)]
|
||||
// CHECK:STDOUT: %impl.elem0.loc6_44.2: @F.%.loc6_44.3 (%.8bf935.1) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_44.2 (constants.%impl.elem0.bb582d.1)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc6_44.2: <specific function> = specific_impl_function %impl.elem0.loc6_44.2, @Copy.WithSelf.Op(%T.loc6_7.1) [symbolic = %specific_impl_fn.loc6_44.2 (constants.%specific_impl_fn.2acc20.1)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%x.param: @F.%T.as_type.loc6_23.1 (%T.as_type)) -> out %return.param: @F.%tuple.type (%tuple.type.db8bf7.1) [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref.loc6_44: @F.%T.as_type.loc6_23.1 (%T.as_type) = name_ref x, %x
|
||||
// CHECK:STDOUT: %x.ref.loc6_47: @F.%T.as_type.loc6_23.1 (%T.as_type) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc6_48.1: @F.%tuple.type (%tuple.type.db8bf7.1) = tuple_literal (%x.ref.loc6_44, %x.ref.loc6_47)
|
||||
// CHECK:STDOUT: %.loc6_49.1: init @F.%tuple.type (%tuple.type.db8bf7.1) = splice_block %.loc6_49.2 {
|
||||
// CHECK:STDOUT: %impl.elem0.loc6_44.1: @F.%.loc6_44.3 (%.8bf935.1) = impl_witness_access constants.%Copy.lookup_impl_witness.d9c332.1, element0 [symbolic = %impl.elem0.loc6_44.2 (constants.%impl.elem0.bb582d.1)]
|
||||
// CHECK:STDOUT: %bound_method.loc6_44.1: <bound method> = bound_method %x.ref.loc6_44, %impl.elem0.loc6_44.1
|
||||
// CHECK:STDOUT: %.loc6_44.1: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %.loc6_44.2: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc6_44.1: <specific function> = specific_impl_function %impl.elem0.loc6_44.1, @Copy.WithSelf.Op(constants.%T.f84) [symbolic = %specific_impl_fn.loc6_44.2 (constants.%specific_impl_fn.2acc20.1)]
|
||||
// CHECK:STDOUT: %bound_method.loc6_44.2: <bound method> = bound_method %x.ref.loc6_44, %specific_impl_fn.loc6_44.1
|
||||
// CHECK:STDOUT: %tuple.elem0: ref @F.%T.as_type.loc6_23.1 (%T.as_type) = tuple_access %return.param, element0
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.call.loc6_44: init @F.%T.as_type.loc6_23.1 (%T.as_type) to %tuple.elem0 = call %bound_method.loc6_44.2(%x.ref.loc6_44)
|
||||
// CHECK:STDOUT: %.loc6_48.2: init @F.%T.as_type.loc6_23.1 (%T.as_type) to %tuple.elem0 = in_place_init %Copy.WithSelf.Op.call.loc6_44
|
||||
// CHECK:STDOUT: %impl.elem0.loc6_47: @F.%.loc6_44.3 (%.8bf935.1) = impl_witness_access constants.%Copy.lookup_impl_witness.d9c332.1, element0 [symbolic = %impl.elem0.loc6_44.2 (constants.%impl.elem0.bb582d.1)]
|
||||
// CHECK:STDOUT: %bound_method.loc6_47.1: <bound method> = bound_method %x.ref.loc6_47, %impl.elem0.loc6_47
|
||||
// CHECK:STDOUT: %.loc6_47.1: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %.loc6_47.2: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc6_7.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc6_47: <specific function> = specific_impl_function %impl.elem0.loc6_47, @Copy.WithSelf.Op(constants.%T.f84) [symbolic = %specific_impl_fn.loc6_44.2 (constants.%specific_impl_fn.2acc20.1)]
|
||||
// CHECK:STDOUT: %bound_method.loc6_47.2: <bound method> = bound_method %x.ref.loc6_47, %specific_impl_fn.loc6_47
|
||||
// CHECK:STDOUT: %tuple.elem1: ref @F.%T.as_type.loc6_23.1 (%T.as_type) = tuple_access %return.param, element1
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.call.loc6_47: init @F.%T.as_type.loc6_23.1 (%T.as_type) to %tuple.elem1 = call %bound_method.loc6_47.2(%x.ref.loc6_47)
|
||||
// CHECK:STDOUT: %.loc6_48.3: init @F.%T.as_type.loc6_23.1 (%T.as_type) to %tuple.elem1 = in_place_init %Copy.WithSelf.Op.call.loc6_47
|
||||
// CHECK:STDOUT: %.loc6_48.4: init @F.%tuple.type (%tuple.type.db8bf7.1) to %return.param = tuple_init (%.loc6_48.2, %.loc6_48.3)
|
||||
// CHECK:STDOUT: %.loc6_49.2: init @F.%tuple.type (%tuple.type.db8bf7.1) = converted %.loc6_48.1, %.loc6_48.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc6_49.1 to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T.f84) {
|
||||
// CHECK:STDOUT: %T.patt.loc6_7.2 => constants.%T.patt.fe6
|
||||
// CHECK:STDOUT: %T.loc6_7.1 => constants.%T.f84
|
||||
// CHECK:STDOUT: %T.as_type.loc6_23.1 => constants.%T.as_type
|
||||
// CHECK:STDOUT: %pattern_type.loc6_21 => constants.%pattern_type.2c66b4.2
|
||||
// CHECK:STDOUT: %x.param_patt.loc6_21.2 => constants.%x.param_patt.1f4da3.1
|
||||
// CHECK:STDOUT: %x.patt.loc6_21.2 => constants.%x.patt.cecdb7.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%Copy.facet) {
|
||||
// CHECK:STDOUT: %T.patt.loc6_7.2 => constants.%T.patt.fe6
|
||||
// CHECK:STDOUT: %T.loc6_7.1 => constants.%Copy.facet
|
||||
// CHECK:STDOUT: %T.as_type.loc6_23.1 => constants.%i32
|
||||
// CHECK:STDOUT: %pattern_type.loc6_21 => constants.%pattern_type.d94
|
||||
// CHECK:STDOUT: %x.param_patt.loc6_21.2 => constants.%x.param_patt.051
|
||||
// CHECK:STDOUT: %x.patt.loc6_21.2 => constants.%x.patt.0f7
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc6_21 => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: %tuple.type => constants.%tuple.type.35f
|
||||
// CHECK:STDOUT: %.loc6_48.5 => constants.%.30d
|
||||
// CHECK:STDOUT: %pattern_type.loc6_48 => constants.%pattern_type.354
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_48.2 => constants.%return.param_patt.46d
|
||||
// CHECK:STDOUT: %return.patt.loc6_48.2 => constants.%return.patt.d16
|
||||
// CHECK:STDOUT: %require_complete.loc6_48 => constants.%complete_type.fa7
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.f76
|
||||
// CHECK:STDOUT: %.loc6_44.3 => constants.%.2b9
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.8af
|
||||
// CHECK:STDOUT: %impl.elem0.loc6_44.2 => constants.%Int.as.Copy.impl.Op.cae
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc6_44.2 => constants.%Int.as.Copy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%U.f84) {
|
||||
// CHECK:STDOUT: %T.patt.loc6_7.2 => constants.%T.patt.fe6
|
||||
// CHECK:STDOUT: %T.loc6_7.1 => constants.%U.f84
|
||||
// CHECK:STDOUT: %T.as_type.loc6_23.1 => constants.%U.as_type.c1c
|
||||
// CHECK:STDOUT: %pattern_type.loc6_21 => constants.%pattern_type.2c66b4.3
|
||||
// CHECK:STDOUT: %x.param_patt.loc6_21.2 => constants.%x.param_patt.1f4da3.2
|
||||
// CHECK:STDOUT: %x.patt.loc6_21.2 => constants.%x.patt.cecdb7.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc6_21 => constants.%require_complete.d83f06.2
|
||||
// CHECK:STDOUT: %tuple.type => constants.%tuple.type.db8bf7.2
|
||||
// CHECK:STDOUT: %.loc6_48.5 => constants.%.58c1c6.2
|
||||
// CHECK:STDOUT: %pattern_type.loc6_48 => constants.%pattern_type.aacade.2
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_48.2 => constants.%return.param_patt.1c7f00.2
|
||||
// CHECK:STDOUT: %return.patt.loc6_48.2 => constants.%return.patt.e7a3ca.2
|
||||
// CHECK:STDOUT: %require_complete.loc6_48 => constants.%require_complete.b868a8.2
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.d2f9c3.3
|
||||
// CHECK:STDOUT: %.loc6_44.3 => constants.%.8bf935.2
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.d9c332.2
|
||||
// CHECK:STDOUT: %impl.elem0.loc6_44.2 => constants.%impl.elem0.bb582d.2
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc6_44.2 => constants.%specific_impl_fn.2acc20.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -19,10 +19,15 @@ class C {
|
||||
fn G() -> auto { return 1 as i32; }
|
||||
}
|
||||
|
||||
fn Id[T: Core.Copy](x: T) -> auto { return x; }
|
||||
fn Pair[T: Core.Copy](x: T) -> auto { return (x, x); }
|
||||
|
||||
// --- lib.impl.carbon
|
||||
impl library "[[@TEST_NAME]]";
|
||||
|
||||
fn H() -> i32 { return F(); }
|
||||
fn J() -> (i32, i32) { return Pair(Id(0 as i32)); }
|
||||
fn K[U: Core.Copy & Core.Destroy](u: U) -> (U, U) { return Pair(Id(u)); }
|
||||
|
||||
// --- use.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
@@ -34,6 +39,18 @@ fn I() -> i32 { return F(); }
|
||||
fn J() -> i32 { return C.G(); }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- use_generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import library "lib";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn J() -> (i32, i32) { return Pair(Id(0 as i32)); }
|
||||
fn K[U: Core.Copy & Core.Destroy](u: U) -> (U, U) { return Pair(Id(u)); }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn L() -> (bool, bool) { return K(true); }
|
||||
|
||||
// CHECK:STDOUT: --- use.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -97,3 +114,341 @@ fn J() -> i32 { return C.G(); }
|
||||
// CHECK:STDOUT: return %C.G.call
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_generic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.693: type = tuple_type (type, type) [concrete]
|
||||
// CHECK:STDOUT: %tuple.be9: %tuple.type.693 = tuple_value (%i32, %i32) [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.35f: type = tuple_type (%i32, %i32) [concrete]
|
||||
// CHECK:STDOUT: %.30d: Core.Form = init_form %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.354: type = pattern_type %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.46d: %pattern_type.354 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.d16: %pattern_type.354 = return_slot_pattern %return.param_patt.46d, %tuple.type.35f [concrete]
|
||||
// CHECK:STDOUT: %J.type: type = fn_type @J [concrete]
|
||||
// CHECK:STDOUT: %J: %J.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Pair.type: type = fn_type @Pair [concrete]
|
||||
// CHECK:STDOUT: %Pair: %Pair.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Id.type: type = fn_type @Id [concrete]
|
||||
// CHECK:STDOUT: %Id: %Id.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %As.type.116: type = generic_interface_type @As [concrete]
|
||||
// CHECK:STDOUT: %As.generic: %As.type.116 = struct_value () [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_0.5c6, %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_0.5c6, %Core.IntLiteral.as.As.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_0.753: %i32 = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet.95d: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %Id.specific_fn.04c: <specific function> = specific_function %Id, @Id(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %Pair.specific_fn.24c: <specific function> = specific_function %Pair, @Pair(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.type.a06: type = generic_interface_type @BitAndWith [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.generic: %BitAndWith.type.a06 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.type.7f7: type = facet_type <@BitAndWith, @BitAndWith(type)> [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.impl_witness: <witness> = impl_witness imports.%BitAndWith.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.facet: %BitAndWith.type.7f7 = facet_value type, (%BitAndWith.impl_witness) [concrete]
|
||||
// CHECK:STDOUT: %BitAndWith.WithSelf.Op.type.1a6: type = fn_type @BitAndWith.WithSelf.Op, @BitAndWith.WithSelf(type, %BitAndWith.facet) [concrete]
|
||||
// CHECK:STDOUT: %.b4e: type = fn_type_with_self_type %BitAndWith.WithSelf.Op.type.1a6, %BitAndWith.facet [concrete]
|
||||
// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.type: type = fn_type @type.as.BitAndWith.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %type.as.BitAndWith.impl.Op: %type.as.BitAndWith.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.bound: <bound method> = bound_method %Copy.type, %type.as.BitAndWith.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %facet_type: type = facet_type <@Copy & @Destroy> [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.143: type = pattern_type %facet_type [concrete]
|
||||
// CHECK:STDOUT: %U.patt.256: %pattern_type.143 = symbolic_binding_pattern U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.dc4: %facet_type = symbolic_binding U, 0 [symbolic]
|
||||
// CHECK:STDOUT: %U.as_type.5d6: type = facet_access_type %U.dc4 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.0e9: type = pattern_type %U.as_type.5d6 [symbolic]
|
||||
// CHECK:STDOUT: %u.param_patt.f9a: %pattern_type.0e9 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %u.patt.d30: %pattern_type.0e9 = wrapper_binding_pattern u, %u.param_patt.f9a [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.56f: type = tuple_type (%facet_type, %facet_type) [concrete]
|
||||
// CHECK:STDOUT: %tuple.f81: %tuple.type.56f = tuple_value (%U.dc4, %U.dc4) [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.7d0: type = tuple_type (%U.as_type.5d6, %U.as_type.5d6) [symbolic]
|
||||
// CHECK:STDOUT: %.7db: Core.Form = init_form %tuple.type.7d0 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.c29: type = pattern_type %tuple.type.7d0 [symbolic]
|
||||
// CHECK:STDOUT: %return.param_patt.df9: %pattern_type.c29 = out_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %return.patt.b82: %pattern_type.c29 = return_slot_pattern %return.param_patt.df9, %tuple.type.7d0 [symbolic]
|
||||
// CHECK:STDOUT: %K.type: type = fn_type @K [concrete]
|
||||
// CHECK:STDOUT: %K: %K.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %require_complete.091: <witness> = require_complete_type %U.as_type.5d6 [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.8f6: <witness> = require_complete_type %tuple.type.7d0 [symbolic]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness.fd8: <witness> = lookup_impl_witness %U.dc4, @Copy [symbolic]
|
||||
// CHECK:STDOUT: %Copy.facet.40c: %Copy.type = facet_value %U.as_type.5d6, (%Copy.lookup_impl_witness.fd8) [symbolic]
|
||||
// CHECK:STDOUT: %Id.specific_fn.e53: <specific function> = specific_function %Id, @Id(%Copy.facet.40c) [symbolic]
|
||||
// CHECK:STDOUT: %Pair.specific_fn.540: <specific function> = specific_function %Pair, @Pair(%Copy.facet.40c) [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.lookup_impl_witness.491: <witness> = lookup_impl_witness %U.dc4, @Destroy [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.facet.589: %Destroy.type = facet_value %U.as_type.5d6, (%Destroy.lookup_impl_witness.491) [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.613: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.589) [symbolic]
|
||||
// CHECK:STDOUT: %.a48: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type.613, %Destroy.facet.589 [symbolic]
|
||||
// CHECK:STDOUT: %impl.elem2: %.a48 = impl_witness_access %Destroy.lookup_impl_witness.491, element2 [symbolic]
|
||||
// CHECK:STDOUT: %specific_impl_fn.eba: <specific function> = specific_impl_function %impl.elem2, @Destroy.WithSelf.SelfDestruct.1(%Destroy.facet.589) [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.784: type = tuple_type (bool, bool) [concrete]
|
||||
// CHECK:STDOUT: %.7b8: Core.Form = init_form %tuple.type.784 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.860: type = pattern_type %tuple.type.784 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.3b7: %pattern_type.860 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.fc1: %pattern_type.860 = return_slot_pattern %return.param_patt.3b7, %tuple.type.784 [concrete]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.5e1: <witness> = impl_witness imports.%Copy.impl_witness_table.bda [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc10 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc10 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %custom_witness.f8f: <witness> = custom_witness (%Destroy.WithSelf.Op.403, %Destroy.WithSelf.SubobjectDestroy.d01, %Destroy.WithSelf.SelfDestruct.db3), @Destroy [concrete]
|
||||
// CHECK:STDOUT: %facet_value: %facet_type = facet_value bool, (%Copy.impl_witness.5e1, %custom_witness.f8f) [concrete]
|
||||
// CHECK:STDOUT: %u.param_patt.56f: %pattern_type.831 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %u.patt.0d7: %pattern_type.831 = wrapper_binding_pattern u, %u.param_patt.56f [concrete]
|
||||
// CHECK:STDOUT: %tuple.6be: %tuple.type.56f = tuple_value (%facet_value, %facet_value) [concrete]
|
||||
// CHECK:STDOUT: %complete_type.127: <witness> = complete_type_witness bool [concrete]
|
||||
// CHECK:STDOUT: %complete_type.e0b: <witness> = complete_type_witness %tuple.type.784 [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet.7af: %Copy.type = facet_value bool, (%Copy.impl_witness.5e1) [concrete]
|
||||
// CHECK:STDOUT: %Id.specific_fn.06a: <specific function> = specific_function %Id, @Id(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %Pair.specific_fn.62b: <specific function> = specific_function %Pair, @Pair(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.75f: %Destroy.type = facet_value bool, (%custom_witness.f8f) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.2a2: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.75f) [concrete]
|
||||
// CHECK:STDOUT: %.fb9: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type.2a2, %Destroy.facet.75f [concrete]
|
||||
// CHECK:STDOUT: %bool.as.Copy.impl.Op.type: type = fn_type @bool.as.Copy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %bool.as.Copy.impl.Op: %bool.as.Copy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Main.Id: %Id.type = import_ref Main//lib, Id, loaded [concrete = constants.%Id]
|
||||
// CHECK:STDOUT: %Main.Pair: %Pair.type = import_ref Main//lib, Pair, loaded [concrete = constants.%Pair]
|
||||
// CHECK:STDOUT: %Core.048aa3.1: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .As = %Core.As
|
||||
// CHECK:STDOUT: .Copy = %Core.Copy
|
||||
// CHECK:STDOUT: .Destroy = %Core.Destroy
|
||||
// CHECK:STDOUT: .BitAndWith = %Core.BitAndWith
|
||||
// CHECK:STDOUT: .Bool = %Core.Bool
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Core.As: %As.type.116 = import_ref Core//prelude/parts/as, As, loaded [concrete = constants.%As.generic]
|
||||
// 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: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.a06 = import_ref Core//prelude/parts/as, BitAndWith, loaded [concrete = constants.%BitAndWith.generic]
|
||||
// CHECK:STDOUT: %Core.import_ref.9c3475.1: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude/parts/as, loc{{\d+_\d+}}, loaded [concrete = constants.%type.as.BitAndWith.impl.Op]
|
||||
// CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.9c3475.1), @type.as.BitAndWith.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.Bool: type = import_ref Core//prelude/parts/bool, Bool, loaded [concrete = bool]
|
||||
// CHECK:STDOUT: %Core.import_ref.9c3475.2: %bool.as.Copy.impl.Op.type = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [concrete = constants.%bool.as.Copy.impl.Op]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.bda = impl_witness_table (%Core.import_ref.9c3475.2), @bool.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %J.decl: %J.type = fn_decl @J [concrete = constants.%J] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.354 = out_param_pattern [concrete = constants.%return.param_patt.46d]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.354 = return_slot_pattern %return.param_patt, %.loc6_20.3 [concrete = constants.%return.patt.d16]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %i32.loc6_12: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.loc6_17: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc6_20.2: %tuple.type.693 = tuple_literal (%i32.loc6_12, %i32.loc6_17) [concrete = constants.%tuple.be9]
|
||||
// CHECK:STDOUT: %.loc6_20.3: type = converted %.loc6_20.2, constants.%tuple.type.35f [concrete = constants.%tuple.type.35f]
|
||||
// CHECK:STDOUT: %.loc6_20.4: Core.Form = init_form %.loc6_20.3 [concrete = constants.%.30d]
|
||||
// CHECK:STDOUT: %return.param: ref %tuple.type.35f = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %tuple.type.35f = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %K.decl: %K.type = fn_decl @K [concrete = constants.%K] {
|
||||
// CHECK:STDOUT: %U.patt.loc7_7.1: %pattern_type.143 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc7_7.2 (constants.%U.patt.256)]
|
||||
// CHECK:STDOUT: %u.param_patt.loc7_36.1: @K.%pattern_type.loc7_36 (%pattern_type.0e9) = value_param_pattern [symbolic = %u.param_patt.loc7_36.2 (constants.%u.param_patt.f9a)]
|
||||
// CHECK:STDOUT: %u.patt.loc7_36.1: @K.%pattern_type.loc7_36 (%pattern_type.0e9) = wrapper_binding_pattern u, %u.param_patt.loc7_36.1 [symbolic = %u.patt.loc7_36.2 (constants.%u.patt.d30)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc7_49.1: @K.%pattern_type.loc7_49 (%pattern_type.c29) = out_param_pattern [symbolic = %return.param_patt.loc7_49.2 (constants.%return.param_patt.df9)]
|
||||
// CHECK:STDOUT: %return.patt.loc7_41.1: @K.%pattern_type.loc7_49 (%pattern_type.c29) = return_slot_pattern %return.param_patt.loc7_49.1, %.loc7_49.6 [symbolic = %return.patt.loc7_41.2 (constants.%return.patt.b82)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %U.ref.loc7_45: %facet_type = name_ref U, %U.loc7_7.2 [symbolic = %U.loc7_7.1 (constants.%U.dc4)]
|
||||
// CHECK:STDOUT: %U.ref.loc7_48: %facet_type = name_ref U, %U.loc7_7.2 [symbolic = %U.loc7_7.1 (constants.%U.dc4)]
|
||||
// CHECK:STDOUT: %.loc7_49.3: %tuple.type.56f = tuple_literal (%U.ref.loc7_45, %U.ref.loc7_48) [symbolic = %tuple (constants.%tuple.f81)]
|
||||
// CHECK:STDOUT: %U.as_type.loc7_49.1: type = facet_access_type constants.%U.dc4 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %.loc7_49.4: type = converted constants.%U.dc4, %U.as_type.loc7_49.1 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %U.as_type.loc7_49.2: type = facet_access_type constants.%U.dc4 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %.loc7_49.5: type = converted constants.%U.dc4, %U.as_type.loc7_49.2 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %.loc7_49.6: type = converted %.loc7_49.3, constants.%tuple.type.7d0 [symbolic = %tuple.type (constants.%tuple.type.7d0)]
|
||||
// CHECK:STDOUT: %.loc7_49.7: Core.Form = init_form %.loc7_49.6 [symbolic = %.loc7_49.2 (constants.%.7db)]
|
||||
// CHECK:STDOUT: %.loc7_19.1: type = splice_block %.loc7_19.3 [concrete = constants.%facet_type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %Core.ref.loc7_9: <namespace> = name_ref Core, imports.%Core.048aa3.1 [concrete = imports.%Core.048aa3.1]
|
||||
// CHECK:STDOUT: %Copy.ref: type = name_ref Copy, imports.%Core.Copy [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: %Core.ref.loc7_21: <namespace> = name_ref Core, imports.%Core.048aa3.1 [concrete = imports.%Core.048aa3.1]
|
||||
// CHECK:STDOUT: %Destroy.ref: type = name_ref Destroy, imports.%Core.Destroy [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: %impl.elem0: %.b4e = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op]
|
||||
// CHECK:STDOUT: %bound_method.loc7_19: <bound method> = bound_method %Copy.ref, %impl.elem0 [concrete = constants.%type.as.BitAndWith.impl.Op.bound]
|
||||
// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call: init type = call %bound_method.loc7_19(%Copy.ref, %Destroy.ref) [concrete = constants.%facet_type]
|
||||
// CHECK:STDOUT: %.loc7_19.2: type = value_of_initializer %type.as.BitAndWith.impl.Op.call [concrete = constants.%facet_type]
|
||||
// CHECK:STDOUT: %.loc7_19.3: type = converted %type.as.BitAndWith.impl.Op.call, %.loc7_19.2 [concrete = constants.%facet_type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.loc7_7.2: %facet_type = symbolic_binding U, 0 [symbolic = %U.loc7_7.1 (constants.%U.dc4)]
|
||||
// CHECK:STDOUT: %u.param: @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7_38.1: type = splice_block %.loc7_38.2 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)] {
|
||||
// CHECK:STDOUT: %U.ref.loc7_38: %facet_type = name_ref U, %U.loc7_7.2 [symbolic = %U.loc7_7.1 (constants.%U.dc4)]
|
||||
// CHECK:STDOUT: %U.as_type.loc7_38.2: type = facet_access_type %U.ref.loc7_38 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %.loc7_38.2: type = converted %U.ref.loc7_38, %U.as_type.loc7_38.2 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %u: @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = wrapper_binding u, %u.param
|
||||
// CHECK:STDOUT: %return.param: ref @K.%tuple.type (%tuple.type.7d0) = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref @K.%tuple.type (%tuple.type.7d0) = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @J() -> out %return.param: %tuple.type.35f {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Pair.ref: %Pair.type = name_ref Pair, imports.%Main.Pair [concrete = constants.%Pair]
|
||||
// CHECK:STDOUT: %Id.ref: %Id.type = name_ref Id, imports.%Main.Id [concrete = constants.%Id]
|
||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %i32.loc6_44: 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.loc6_41.1: <bound method> = bound_method %int_0, %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.loc6_41.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i32 = call %bound_method.loc6_41.2(%int_0) [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %.loc6_41.1: %i32 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %.loc6_41.2: %i32 = converted %int_0, %.loc6_41.1 [concrete = constants.%int_0.753]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_47.1: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc6_47.1: %Copy.type = converted constants.%i32, %Copy.facet.loc6_47.1 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_47.2: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc6_47.2: %Copy.type = converted constants.%i32, %Copy.facet.loc6_47.2 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Id.specific_fn: <specific function> = specific_function %Id.ref, @Id(constants.%Copy.facet.95d) [concrete = constants.%Id.specific_fn.04c]
|
||||
// CHECK:STDOUT: %Id.call: init %i32 = call %Id.specific_fn(%.loc6_41.2)
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_48.1: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc6_48.1: %Copy.type = converted constants.%i32, %Copy.facet.loc6_48.1 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_48.2: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc6_48.2: %Copy.type = converted constants.%i32, %Copy.facet.loc6_48.2 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Pair.specific_fn: <specific function> = specific_function %Pair.ref, @Pair(constants.%Copy.facet.95d) [concrete = constants.%Pair.specific_fn.24c]
|
||||
// CHECK:STDOUT: %.loc6_20.1: ref %tuple.type.35f = splice_block %return.param {}
|
||||
// CHECK:STDOUT: %.loc6_47.3: %i32 = value_of_initializer %Id.call
|
||||
// CHECK:STDOUT: %.loc6_47.4: %i32 = converted %Id.call, %.loc6_47.3
|
||||
// CHECK:STDOUT: %Pair.call: init %tuple.type.35f to %.loc6_20.1 = call %Pair.specific_fn(%.loc6_47.4)
|
||||
// CHECK:STDOUT: return %Pair.call to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @K(%U.loc7_7.2: %facet_type) {
|
||||
// CHECK:STDOUT: %U.patt.loc7_7.2: %pattern_type.143 = symbolic_binding_pattern U, 0 [symbolic = %U.patt.loc7_7.2 (constants.%U.patt.256)]
|
||||
// CHECK:STDOUT: %U.loc7_7.1: %facet_type = symbolic_binding U, 0 [symbolic = %U.loc7_7.1 (constants.%U.dc4)]
|
||||
// CHECK:STDOUT: %U.as_type.loc7_38.1: type = facet_access_type %U.loc7_7.1 [symbolic = %U.as_type.loc7_38.1 (constants.%U.as_type.5d6)]
|
||||
// CHECK:STDOUT: %pattern_type.loc7_36: type = pattern_type %U.as_type.loc7_38.1 [symbolic = %pattern_type.loc7_36 (constants.%pattern_type.0e9)]
|
||||
// CHECK:STDOUT: %u.param_patt.loc7_36.2: @K.%pattern_type.loc7_36 (%pattern_type.0e9) = value_param_pattern [symbolic = %u.param_patt.loc7_36.2 (constants.%u.param_patt.f9a)]
|
||||
// CHECK:STDOUT: %u.patt.loc7_36.2: @K.%pattern_type.loc7_36 (%pattern_type.0e9) = wrapper_binding_pattern u, %u.param_patt.loc7_36.2 [symbolic = %u.patt.loc7_36.2 (constants.%u.patt.d30)]
|
||||
// CHECK:STDOUT: %tuple: %tuple.type.56f = tuple_value (%U.loc7_7.1, %U.loc7_7.1) [symbolic = %tuple (constants.%tuple.f81)]
|
||||
// CHECK:STDOUT: %tuple.type: type = tuple_type (%U.as_type.loc7_38.1, %U.as_type.loc7_38.1) [symbolic = %tuple.type (constants.%tuple.type.7d0)]
|
||||
// CHECK:STDOUT: %.loc7_49.2: Core.Form = init_form %tuple.type [symbolic = %.loc7_49.2 (constants.%.7db)]
|
||||
// CHECK:STDOUT: %pattern_type.loc7_49: type = pattern_type %tuple.type [symbolic = %pattern_type.loc7_49 (constants.%pattern_type.c29)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc7_49.2: @K.%pattern_type.loc7_49 (%pattern_type.c29) = out_param_pattern [symbolic = %return.param_patt.loc7_49.2 (constants.%return.param_patt.df9)]
|
||||
// CHECK:STDOUT: %return.patt.loc7_41.2: @K.%pattern_type.loc7_49 (%pattern_type.c29) = return_slot_pattern %return.param_patt.loc7_49.2, %tuple.type [symbolic = %return.patt.loc7_41.2 (constants.%return.patt.b82)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc7_36: <witness> = require_complete_type %U.as_type.loc7_38.1 [symbolic = %require_complete.loc7_36 (constants.%require_complete.091)]
|
||||
// CHECK:STDOUT: %require_complete.loc7_41: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc7_41 (constants.%require_complete.8f6)]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %U.loc7_7.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.fd8)]
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_69.3: %Copy.type = facet_value %U.as_type.loc7_38.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %Id.specific_fn.loc7_65.2: <specific function> = specific_function constants.%Id, @Id(%Copy.facet.loc7_69.3) [symbolic = %Id.specific_fn.loc7_65.2 (constants.%Id.specific_fn.e53)]
|
||||
// CHECK:STDOUT: %Pair.specific_fn.loc7_60.2: <specific function> = specific_function constants.%Pair, @Pair(%Copy.facet.loc7_69.3) [symbolic = %Pair.specific_fn.loc7_60.2 (constants.%Pair.specific_fn.540)]
|
||||
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %U.loc7_7.1, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.491)]
|
||||
// CHECK:STDOUT: %Destroy.facet.loc7_69.3: %Destroy.type = facet_value %U.as_type.loc7_38.1, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.loc7_69.3 (constants.%Destroy.facet.589)]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.loc7_69.3) [symbolic = %Destroy.WithSelf.SelfDestruct.type (constants.%Destroy.WithSelf.SelfDestruct.type.613)]
|
||||
// CHECK:STDOUT: %.loc7_69.8: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type, %Destroy.facet.loc7_69.3 [symbolic = %.loc7_69.8 (constants.%.a48)]
|
||||
// CHECK:STDOUT: %impl.elem2.loc7_69.2: @K.%.loc7_69.8 (%.a48) = impl_witness_access %Destroy.lookup_impl_witness, element2 [symbolic = %impl.elem2.loc7_69.2 (constants.%impl.elem2)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc7_69.2: <specific function> = specific_impl_function %impl.elem2.loc7_69.2, @Destroy.WithSelf.SelfDestruct.1(%Destroy.facet.loc7_69.3) [symbolic = %specific_impl_fn.loc7_69.2 (constants.%specific_impl_fn.eba)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%u.param: @K.%U.as_type.loc7_38.1 (%U.as_type.5d6)) -> out %return.param: @K.%tuple.type (%tuple.type.7d0) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Pair.ref: %Pair.type = name_ref Pair, imports.%Main.Pair [concrete = constants.%Pair]
|
||||
// CHECK:STDOUT: %Id.ref: %Id.type = name_ref Id, imports.%Main.Id [concrete = constants.%Id]
|
||||
// CHECK:STDOUT: %u.ref: @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = name_ref u, %u
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_69.1: %Copy.type = facet_value constants.%U.as_type.5d6, (constants.%Copy.lookup_impl_witness.fd8) [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %.loc7_69.1: %Copy.type = converted constants.%U.as_type.5d6, %Copy.facet.loc7_69.1 [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_69.2: %Copy.type = facet_value constants.%U.as_type.5d6, (constants.%Copy.lookup_impl_witness.fd8) [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %.loc7_69.2: %Copy.type = converted constants.%U.as_type.5d6, %Copy.facet.loc7_69.2 [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %Id.specific_fn.loc7_65.1: <specific function> = specific_function %Id.ref, @Id(constants.%Copy.facet.40c) [symbolic = %Id.specific_fn.loc7_65.2 (constants.%Id.specific_fn.e53)]
|
||||
// CHECK:STDOUT: %.loc7_69.3: ref @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = temporary_storage
|
||||
// CHECK:STDOUT: %Id.call: init @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) to %.loc7_69.3 = call %Id.specific_fn.loc7_65.1(%u.ref)
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_70.1: %Copy.type = facet_value constants.%U.as_type.5d6, (constants.%Copy.lookup_impl_witness.fd8) [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %.loc7_70.1: %Copy.type = converted constants.%U.as_type.5d6, %Copy.facet.loc7_70.1 [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_70.2: %Copy.type = facet_value constants.%U.as_type.5d6, (constants.%Copy.lookup_impl_witness.fd8) [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %.loc7_70.2: %Copy.type = converted constants.%U.as_type.5d6, %Copy.facet.loc7_70.2 [symbolic = %Copy.facet.loc7_69.3 (constants.%Copy.facet.40c)]
|
||||
// CHECK:STDOUT: %Pair.specific_fn.loc7_60.1: <specific function> = specific_function %Pair.ref, @Pair(constants.%Copy.facet.40c) [symbolic = %Pair.specific_fn.loc7_60.2 (constants.%Pair.specific_fn.540)]
|
||||
// CHECK:STDOUT: %.loc7_49.1: ref @K.%tuple.type (%tuple.type.7d0) = splice_block %return.param {}
|
||||
// CHECK:STDOUT: %.loc7_69.4: ref @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = temporary %.loc7_69.3, %Id.call
|
||||
// CHECK:STDOUT: %.loc7_69.5: @K.%U.as_type.loc7_38.1 (%U.as_type.5d6) = acquire_value %.loc7_69.4
|
||||
// CHECK:STDOUT: %Pair.call: init @K.%tuple.type (%tuple.type.7d0) to %.loc7_49.1 = call %Pair.specific_fn.loc7_60.1(%.loc7_69.5)
|
||||
// CHECK:STDOUT: %impl.elem2.loc7_69.1: @K.%.loc7_69.8 (%.a48) = impl_witness_access constants.%Destroy.lookup_impl_witness.491, element2 [symbolic = %impl.elem2.loc7_69.2 (constants.%impl.elem2)]
|
||||
// CHECK:STDOUT: %bound_method.loc7_69.1: <bound method> = bound_method %.loc7_69.4, %impl.elem2.loc7_69.1
|
||||
// CHECK:STDOUT: %Destroy.facet.loc7_69.1: %Destroy.type = facet_value constants.%U.as_type.5d6, (constants.%Destroy.lookup_impl_witness.491) [symbolic = %Destroy.facet.loc7_69.3 (constants.%Destroy.facet.589)]
|
||||
// CHECK:STDOUT: %.loc7_69.6: %Destroy.type = converted constants.%U.as_type.5d6, %Destroy.facet.loc7_69.1 [symbolic = %Destroy.facet.loc7_69.3 (constants.%Destroy.facet.589)]
|
||||
// CHECK:STDOUT: %Destroy.facet.loc7_69.2: %Destroy.type = facet_value constants.%U.as_type.5d6, (constants.%Destroy.lookup_impl_witness.491) [symbolic = %Destroy.facet.loc7_69.3 (constants.%Destroy.facet.589)]
|
||||
// CHECK:STDOUT: %.loc7_69.7: %Destroy.type = converted constants.%U.as_type.5d6, %Destroy.facet.loc7_69.2 [symbolic = %Destroy.facet.loc7_69.3 (constants.%Destroy.facet.589)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc7_69.1: <specific function> = specific_impl_function %impl.elem2.loc7_69.1, @Destroy.WithSelf.SelfDestruct.1(constants.%Destroy.facet.589) [symbolic = %specific_impl_fn.loc7_69.2 (constants.%specific_impl_fn.eba)]
|
||||
// CHECK:STDOUT: %bound_method.loc7_69.2: <bound method> = bound_method %.loc7_69.4, %specific_impl_fn.loc7_69.1
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %bound_method.loc7_69.2(%.loc7_69.4)
|
||||
// CHECK:STDOUT: return %Pair.call to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @K(constants.%U.dc4) {
|
||||
// CHECK:STDOUT: %U.patt.loc7_7.2 => constants.%U.patt.256
|
||||
// CHECK:STDOUT: %U.loc7_7.1 => constants.%U.dc4
|
||||
// CHECK:STDOUT: %U.as_type.loc7_38.1 => constants.%U.as_type.5d6
|
||||
// CHECK:STDOUT: %pattern_type.loc7_36 => constants.%pattern_type.0e9
|
||||
// CHECK:STDOUT: %u.param_patt.loc7_36.2 => constants.%u.param_patt.f9a
|
||||
// CHECK:STDOUT: %u.patt.loc7_36.2 => constants.%u.patt.d30
|
||||
// CHECK:STDOUT: %tuple => constants.%tuple.f81
|
||||
// CHECK:STDOUT: %tuple.type => constants.%tuple.type.7d0
|
||||
// CHECK:STDOUT: %.loc7_49.2 => constants.%.7db
|
||||
// CHECK:STDOUT: %pattern_type.loc7_49 => constants.%pattern_type.c29
|
||||
// CHECK:STDOUT: %return.param_patt.loc7_49.2 => constants.%return.param_patt.df9
|
||||
// CHECK:STDOUT: %return.patt.loc7_41.2 => constants.%return.patt.b82
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @K(constants.%facet_value) {
|
||||
// CHECK:STDOUT: %U.patt.loc7_7.2 => constants.%U.patt.256
|
||||
// CHECK:STDOUT: %U.loc7_7.1 => constants.%facet_value
|
||||
// CHECK:STDOUT: %U.as_type.loc7_38.1 => bool
|
||||
// CHECK:STDOUT: %pattern_type.loc7_36 => constants.%pattern_type.831
|
||||
// CHECK:STDOUT: %u.param_patt.loc7_36.2 => constants.%u.param_patt.56f
|
||||
// CHECK:STDOUT: %u.patt.loc7_36.2 => constants.%u.patt.0d7
|
||||
// CHECK:STDOUT: %tuple => constants.%tuple.6be
|
||||
// CHECK:STDOUT: %tuple.type => constants.%tuple.type.784
|
||||
// CHECK:STDOUT: %.loc7_49.2 => constants.%.7b8
|
||||
// CHECK:STDOUT: %pattern_type.loc7_49 => constants.%pattern_type.860
|
||||
// CHECK:STDOUT: %return.param_patt.loc7_49.2 => constants.%return.param_patt.3b7
|
||||
// CHECK:STDOUT: %return.patt.loc7_41.2 => constants.%return.patt.fc1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc7_36 => constants.%complete_type.127
|
||||
// CHECK:STDOUT: %require_complete.loc7_41 => constants.%complete_type.e0b
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.5e1
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_69.3 => constants.%Copy.facet.7af
|
||||
// CHECK:STDOUT: %Id.specific_fn.loc7_65.2 => constants.%Id.specific_fn.06a
|
||||
// CHECK:STDOUT: %Pair.specific_fn.loc7_60.2 => constants.%Pair.specific_fn.62b
|
||||
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%custom_witness.f8f
|
||||
// CHECK:STDOUT: %Destroy.facet.loc7_69.3 => constants.%Destroy.facet.75f
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type => constants.%Destroy.WithSelf.SelfDestruct.type.2a2
|
||||
// CHECK:STDOUT: %.loc7_69.8 => constants.%.fb9
|
||||
// CHECK:STDOUT: %impl.elem2.loc7_69.2 => constants.%Destroy.WithSelf.SelfDestruct.db3
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc7_69.2 => constants.%Destroy.WithSelf.SelfDestruct.db3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -0,0 +1,289 @@
|
||||
// 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/template.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/deduced_return/template.carbon
|
||||
|
||||
// --- member_access.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn F[template T: type](x: T) -> auto { return x.n; }
|
||||
//@dump-sem-ir-end
|
||||
|
||||
class C {
|
||||
var n: i32;
|
||||
}
|
||||
|
||||
fn G(c: C) -> i32 { return F(c); }
|
||||
fn H(s: {.n: bool}) -> bool { return F(s); }
|
||||
|
||||
// --- call_from_checked_generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[template T: type](x: T) -> auto { return x; }
|
||||
|
||||
fn G[U: Core.Copy](u: U) -> U { return F(u); }
|
||||
|
||||
fn H() -> i32 { return G(0 as i32); }
|
||||
|
||||
// --- fail_instantiation_error.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[template T: type](x: T) -> auto { return x.n; }
|
||||
|
||||
class D {
|
||||
var m: i32;
|
||||
}
|
||||
|
||||
// The definition of `F(D)` is needed to determine the return type, so it's
|
||||
// instantiated at the call.
|
||||
fn G(d: D) -> i32 {
|
||||
// CHECK:STDERR: fail_instantiation_error.carbon:[[@LINE+3]]:10-13: error: unable to monomorphize specific `F(D)` [ResolvingSpecificHere]
|
||||
// CHECK:STDERR: fail_instantiation_error.carbon:[[@LINE-10]]:47-49: note: member name `n` not found in `D` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR:
|
||||
return F(d);
|
||||
}
|
||||
|
||||
// --- fail_recursion_before_deduced.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[template T: type](x: T) -> auto {
|
||||
return F(x);
|
||||
}
|
||||
|
||||
fn G() {
|
||||
// CHECK:STDERR: fail_recursion_before_deduced.carbon:[[@LINE+4]]:3-13: error: unable to monomorphize specific `F(i32)` [ResolvingSpecificHere]
|
||||
// CHECK:STDERR: fail_recursion_before_deduced.carbon:[[@LINE-5]]:10-13: note: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_recursion_before_deduced.carbon:[[@LINE-7]]:1-38: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
F(0 as i32);
|
||||
}
|
||||
|
||||
// --- recursion_after_returned_var.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[template T: type](x: T, b: bool) -> auto {
|
||||
returned var r: T = x;
|
||||
if (b) {
|
||||
F(x, false);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
fn G() -> i32 { return F(0 as i32, true); }
|
||||
|
||||
// CHECK:STDOUT: --- member_access.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.3a0592.1: %pattern_type.9a5 = symbolic_binding_pattern T, 0, template [template]
|
||||
// CHECK:STDOUT: %T.67db0b.1: type = symbolic_binding T, 0, template [template]
|
||||
// CHECK:STDOUT: %pattern_type.51d: type = pattern_type %T.67db0b.1 [template]
|
||||
// CHECK:STDOUT: %x.param_patt.91d: %pattern_type.51d = value_param_pattern [template]
|
||||
// CHECK:STDOUT: %x.patt.260: %pattern_type.51d = wrapper_binding_pattern x, %x.param_patt.91d [template]
|
||||
// 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.67db0b.1 [template]
|
||||
// CHECK:STDOUT: %.237: type = type_of_inst @F.%.loc4_48.3 [template]
|
||||
// CHECK:STDOUT: %.f96: %.237 = splice_inst @F.%.loc4_48.3 [template]
|
||||
// CHECK:STDOUT: %.6c4: Core.Form = init_form %.237 [template]
|
||||
// CHECK:STDOUT: %pattern_type.940: type = pattern_type %.237 [template]
|
||||
// CHECK:STDOUT: %return.param_patt.bcf: %pattern_type.940 = out_param_pattern [template]
|
||||
// CHECK:STDOUT: %return.patt.690: %pattern_type.940 = return_slot_pattern %return.param_patt.bcf, %.237 [template]
|
||||
// CHECK:STDOUT: %require_complete.b43: <witness> = require_complete_type %.237 [template]
|
||||
// CHECK:STDOUT: %.458: %.237 = splice_inst @F.%.loc4_50.3 [template]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// 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: %C.elem: type = unbound_element_type %C, %i32 [concrete]
|
||||
// CHECK:STDOUT: %struct_type.n.4d4: type = struct_type {.n: %i32} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.31e: <witness> = complete_type_witness %struct_type.n.4d4 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.0b3: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.299: %pattern_type.d94 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt.0f9: %pattern_type.98b = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt.953: %pattern_type.98b = wrapper_binding_pattern x, %x.param_patt.0f9 [concrete]
|
||||
// CHECK:STDOUT: %inst.splice_block.426619.1: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.ab8: %i32 = splice_block %.5e4 {
|
||||
// CHECK:STDOUT: %.340: %C = specific_inst @F.%x.ref, @F(%C)
|
||||
// CHECK:STDOUT: %n.ref: %C.elem = name_ref n, @C.%field_decl [concrete = @C.%field_decl]
|
||||
// CHECK:STDOUT: %.a79: ref %i32 = class_element_access %.340, element0
|
||||
// CHECK:STDOUT: %.5e4: %i32 = acquire_value %.a79
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.648: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.cae: %Int.as.Copy.impl.Op.type.648 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet.95d: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet.95d [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %inst.splice_block.426619.2: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.c58: init %i32 = splice_block %Int.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0.5a8: %.2b9 = impl_witness_access %Copy.impl_witness.8af, element0 [concrete = %Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.ab3: <bound method> = bound_method %.ab8, %impl.elem0.5a8
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0.5a8, @Int.as.Copy.impl.Op(%int_32) [concrete = %Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.764: <bound method> = bound_method %.ab8, %specific_fn
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.764(%.ab8)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %struct_type.n.ff2: type = struct_type {.n: bool} [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.80d: type = pattern_type %struct_type.n.ff2 [concrete]
|
||||
// CHECK:STDOUT: %.f34: Core.Form = init_form bool [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.5a1: %pattern_type.831 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.c0c: %pattern_type.831 = return_slot_pattern %return.param_patt.5a1, bool [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt.6cb: %pattern_type.80d = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt.a4f: %pattern_type.80d = wrapper_binding_pattern x, %x.param_patt.6cb [concrete]
|
||||
// CHECK:STDOUT: %complete_type.ed1: <witness> = complete_type_witness %struct_type.n.ff2 [concrete]
|
||||
// CHECK:STDOUT: %inst.splice_block.426619.3: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.c30: bool = splice_block %.000 {
|
||||
// CHECK:STDOUT: %.ed5: %struct_type.n.ff2 = specific_inst @F.%x.ref, @F(%struct_type.n.ff2)
|
||||
// CHECK:STDOUT: %.000: bool = struct_access %.ed5, element0
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %complete_type.127: <witness> = complete_type_witness bool [concrete]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.5e1: <witness> = impl_witness imports.%Copy.impl_witness_table.bda [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet.7af: %Copy.type = facet_value bool, (%Copy.impl_witness.5e1) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.c98: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %.68a: type = fn_type_with_self_type %Copy.WithSelf.Op.type.c98, %Copy.facet.7af [concrete]
|
||||
// CHECK:STDOUT: %bool.as.Copy.impl.Op.type: type = fn_type @bool.as.Copy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %bool.as.Copy.impl.Op: %bool.as.Copy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %inst.splice_block.426619.4: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.d3f: init bool = splice_block %bool.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0.6df: %.68a = impl_witness_access %Copy.impl_witness.5e1, element0 [concrete = %bool.as.Copy.impl.Op]
|
||||
// CHECK:STDOUT: %bound_method.450: <bound method> = bound_method %.c30, %impl.elem0.6df
|
||||
// CHECK:STDOUT: %bool.as.Copy.impl.Op.call: init bool = call %bound_method.450(%.c30)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.import_ref.9c3: %bool.as.Copy.impl.Op.type = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [concrete = constants.%bool.as.Copy.impl.Op]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.bda = impl_witness_table (%Core.import_ref.9c3), @bool.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.loc4_16.1: %pattern_type.9a5 = symbolic_binding_pattern T, 0, template [template = %T.patt.loc4_16.2 (constants.%T.patt.3a0592.1)]
|
||||
// CHECK:STDOUT: %x.param_patt.loc4_25.1: @F.%pattern_type.loc4_25 (%pattern_type.51d) = value_param_pattern [template = %x.param_patt.loc4_25.2 (constants.%x.param_patt.91d)]
|
||||
// CHECK:STDOUT: %x.patt.loc4_25.1: @F.%pattern_type.loc4_25 (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc4_25.1 [template = %x.patt.loc4_25.2 (constants.%x.patt.260)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc4_48.1: @F.%pattern_type.loc4_48 (%pattern_type.940) = out_param_pattern [template = %return.param_patt.loc4_48.2 (constants.%return.param_patt.bcf)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_48.1: @F.%pattern_type.loc4_48 (%pattern_type.940) = return_slot_pattern %return.param_patt.loc4_48.1, %.loc4_48.7 [template = %return.patt.loc4_48.2 (constants.%return.patt.690)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc4_18.1: type = splice_block %.loc4_18.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %.loc4_18.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc4_16.2: type = symbolic_binding T, 0, template [template = %T.loc4_16.1 (constants.%T.67db0b.1)]
|
||||
// CHECK:STDOUT: %x.param: @F.%T.loc4_16.1 (%T.67db0b.1) = value_param call_param0
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_16.2 [template = %T.loc4_16.1 (constants.%T.67db0b.1)]
|
||||
// CHECK:STDOUT: %x: @F.%T.loc4_16.1 (%T.67db0b.1) = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %.loc4_48.7: type = type_literal constants.%.237 [template = %.loc4_48.4 (constants.%.237)]
|
||||
// CHECK:STDOUT: %.loc4_48.8: Core.Form = init_form %.loc4_48.7 [template = %.loc4_48.6 (constants.%.6c4)]
|
||||
// CHECK:STDOUT: %return.param: ref @F.%.loc4_48.4 (%.237) = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref @F.%.loc4_48.4 (%.237) = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc4_16.2: type) {
|
||||
// CHECK:STDOUT: %T.patt.loc4_16.2: %pattern_type.9a5 = symbolic_binding_pattern T, 0, template [template = %T.patt.loc4_16.2 (constants.%T.patt.3a0592.1)]
|
||||
// CHECK:STDOUT: %T.loc4_16.1: type = symbolic_binding T, 0, template [template = %T.loc4_16.1 (constants.%T.67db0b.1)]
|
||||
// CHECK:STDOUT: %pattern_type.loc4_25: type = pattern_type %T.loc4_16.1 [template = %pattern_type.loc4_25 (constants.%pattern_type.51d)]
|
||||
// CHECK:STDOUT: %x.param_patt.loc4_25.2: @F.%pattern_type.loc4_25 (%pattern_type.51d) = value_param_pattern [template = %x.param_patt.loc4_25.2 (constants.%x.param_patt.91d)]
|
||||
// CHECK:STDOUT: %x.patt.loc4_25.2: @F.%pattern_type.loc4_25 (%pattern_type.51d) = wrapper_binding_pattern x, %x.param_patt.loc4_25.2 [template = %x.patt.loc4_25.2 (constants.%x.patt.260)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc4_25: <witness> = require_complete_type %T.loc4_16.1 [template = %require_complete.loc4_25 (constants.%require_complete.944)]
|
||||
// CHECK:STDOUT: %.loc4_48.3: <instruction> = access_member_action %x.ref, n [template]
|
||||
// CHECK:STDOUT: %.loc4_48.4: type = type_of_inst %.loc4_48.3 [template = %.loc4_48.4 (constants.%.237)]
|
||||
// CHECK:STDOUT: %.loc4_48.5: @F.%.loc4_48.4 (%.237) = splice_inst %.loc4_48.3 [template = %.loc4_48.5 (constants.%.f96)]
|
||||
// CHECK:STDOUT: %.loc4_48.6: Core.Form = init_form %.loc4_48.4 [template = %.loc4_48.6 (constants.%.6c4)]
|
||||
// CHECK:STDOUT: %pattern_type.loc4_48: type = pattern_type %.loc4_48.4 [template = %pattern_type.loc4_48 (constants.%pattern_type.940)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc4_48.2: @F.%pattern_type.loc4_48 (%pattern_type.940) = out_param_pattern [template = %return.param_patt.loc4_48.2 (constants.%return.param_patt.bcf)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_48.2: @F.%pattern_type.loc4_48 (%pattern_type.940) = return_slot_pattern %return.param_patt.loc4_48.2, %.loc4_48.4 [template = %return.patt.loc4_48.2 (constants.%return.patt.690)]
|
||||
// CHECK:STDOUT: %require_complete.loc4_48: <witness> = require_complete_type %.loc4_48.4 [template = %require_complete.loc4_48 (constants.%require_complete.b43)]
|
||||
// CHECK:STDOUT: %.loc4_50.3: <instruction> = convert_to_category_action %.loc4_48.2, element10 [template]
|
||||
// CHECK:STDOUT: %.loc4_50.4: @F.%.loc4_48.4 (%.237) = splice_inst %.loc4_50.3 [template = %.loc4_50.4 (constants.%.458)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%x.param: @F.%T.loc4_16.1 (%T.67db0b.1)) -> out %return.param: @F.%.loc4_48.4 (%.237) [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: @F.%T.loc4_16.1 (%T.67db0b.1) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc4_48.1: type = type_of_inst %.loc4_48.3 [template = %.loc4_48.4 (constants.%.237)]
|
||||
// CHECK:STDOUT: %.loc4_48.2: @F.%.loc4_48.4 (%.237) = splice_inst %.loc4_48.3 [template = %.loc4_48.5 (constants.%.f96)]
|
||||
// CHECK:STDOUT: %.loc4_50.1: @F.%.loc4_48.4 (%.237) = splice_block %.loc4_50.2 [template = %.loc4_50.4 (constants.%.458)] {
|
||||
// CHECK:STDOUT: %.loc4_50.2: @F.%.loc4_48.4 (%.237) = splice_inst %.loc4_50.3 [template = %.loc4_50.4 (constants.%.458)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc4_50.1 to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T.67db0b.1) {
|
||||
// CHECK:STDOUT: %T.patt.loc4_16.2 => constants.%T.patt.3a0592.1
|
||||
// CHECK:STDOUT: %T.loc4_16.1 => constants.%T.67db0b.1
|
||||
// CHECK:STDOUT: %pattern_type.loc4_25 => constants.%pattern_type.51d
|
||||
// CHECK:STDOUT: %x.param_patt.loc4_25.2 => constants.%x.param_patt.91d
|
||||
// CHECK:STDOUT: %x.patt.loc4_25.2 => constants.%x.patt.260
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.patt.loc4_16.2 => constants.%T.patt.3a0592.1
|
||||
// CHECK:STDOUT: %T.loc4_16.1 => constants.%C
|
||||
// CHECK:STDOUT: %pattern_type.loc4_25 => constants.%pattern_type.98b
|
||||
// CHECK:STDOUT: %x.param_patt.loc4_25.2 => constants.%x.param_patt.0f9
|
||||
// CHECK:STDOUT: %x.patt.loc4_25.2 => constants.%x.patt.953
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc4_25 => constants.%complete_type.31e
|
||||
// CHECK:STDOUT: %.loc4_48.3 => constants.%inst.splice_block.426619.1
|
||||
// CHECK:STDOUT: %.loc4_48.4 => constants.%i32
|
||||
// CHECK:STDOUT: %.loc4_48.5 => <not constant>
|
||||
// CHECK:STDOUT: %.loc4_48.6 => constants.%.0b3
|
||||
// CHECK:STDOUT: %pattern_type.loc4_48 => constants.%pattern_type.d94
|
||||
// CHECK:STDOUT: %return.param_patt.loc4_48.2 => constants.%return.param_patt.299
|
||||
// CHECK:STDOUT: %return.patt.loc4_48.2 => constants.%return.patt.6fa
|
||||
// CHECK:STDOUT: %require_complete.loc4_48 => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: %.loc4_50.3 => constants.%inst.splice_block.426619.2
|
||||
// CHECK:STDOUT: %.loc4_50.4 => <not constant>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%struct_type.n.ff2) {
|
||||
// CHECK:STDOUT: %T.patt.loc4_16.2 => constants.%T.patt.3a0592.1
|
||||
// CHECK:STDOUT: %T.loc4_16.1 => constants.%struct_type.n.ff2
|
||||
// CHECK:STDOUT: %pattern_type.loc4_25 => constants.%pattern_type.80d
|
||||
// CHECK:STDOUT: %x.param_patt.loc4_25.2 => constants.%x.param_patt.6cb
|
||||
// CHECK:STDOUT: %x.patt.loc4_25.2 => constants.%x.patt.a4f
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc4_25 => constants.%complete_type.ed1
|
||||
// CHECK:STDOUT: %.loc4_48.3 => constants.%inst.splice_block.426619.3
|
||||
// CHECK:STDOUT: %.loc4_48.4 => bool
|
||||
// CHECK:STDOUT: %.loc4_48.5 => <not constant>
|
||||
// CHECK:STDOUT: %.loc4_48.6 => constants.%.f34
|
||||
// CHECK:STDOUT: %pattern_type.loc4_48 => constants.%pattern_type.831
|
||||
// CHECK:STDOUT: %return.param_patt.loc4_48.2 => constants.%return.param_patt.5a1
|
||||
// CHECK:STDOUT: %return.patt.loc4_48.2 => constants.%return.patt.c0c
|
||||
// CHECK:STDOUT: %require_complete.loc4_48 => constants.%complete_type.127
|
||||
// CHECK:STDOUT: %.loc4_50.3 => constants.%inst.splice_block.426619.4
|
||||
// CHECK:STDOUT: %.loc4_50.4 => <not constant>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -15,7 +15,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(b: bool) -> auto {
|
||||
if (b) {
|
||||
// CHECK:STDERR: fail_recursion.carbon:[[@LINE+3]]:12-19: error: call to `F` before its return type is deduced [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_recursion.carbon:[[@LINE+3]]:12-19: error: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_recursion.carbon:[[@LINE-3]]:1-23: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
return F(false);
|
||||
@@ -28,7 +28,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C {
|
||||
// The body of `F` is checked after the body of `G`.
|
||||
// CHECK:STDERR: fail_member_order.carbon:[[@LINE+1]]:26-28: error: call to `F` before its return type is deduced [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_member_order.carbon:[[@LINE+1]]:26-28: error: call to `F` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
fn G() -> i32 { return F(); }
|
||||
// CHECK:STDERR: fail_member_order.carbon:[[@LINE+2]]:3-18: note: return type of `F` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/function/export/deduced_return.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/function/export/deduced_return.carbon
|
||||
|
||||
// --- non_generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
fn F() -> auto { return 1 as i32; }
|
||||
|
||||
inline Cpp '''
|
||||
int CallF() { return Carbon::F(); }
|
||||
''';
|
||||
|
||||
// --- generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
fn PointerId[T: type](p: T*) -> auto { return p; }
|
||||
|
||||
inline Cpp '''
|
||||
int CallPointerId() {
|
||||
int x = 0;
|
||||
int* _Nonnull p = &x;
|
||||
return *Carbon::PointerId(p);
|
||||
}
|
||||
''';
|
||||
@@ -0,0 +1,286 @@
|
||||
// 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/full.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/function/generic/deduced_return.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/function/generic/deduced_return.carbon
|
||||
|
||||
// --- generic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Id[T: Core.Copy](x: T) -> auto { return x; }
|
||||
fn Pair[T: Core.Copy](x: T) -> auto { return (x, x); }
|
||||
fn IdFromGeneric[T: Core.Copy](x: T) -> T { return Id(x); }
|
||||
|
||||
fn Use(n: i32) -> i32 {
|
||||
let unused p: (i32, i32) = Pair(n);
|
||||
let unused b: bool = IdFromGeneric(true);
|
||||
return Id(n);
|
||||
}
|
||||
|
||||
// --- template.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Negate[template T: type](a: T) -> auto { return -a; }
|
||||
|
||||
fn CallNegate(a: i32) -> i32 { return Negate(a); }
|
||||
|
||||
// --- lib.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Pair[T: Core.Copy](x: T) -> auto { return (x, x); }
|
||||
|
||||
// --- use_lib.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import library "lib";
|
||||
|
||||
fn Use(n: i32) -> (i32, i32) { return Pair(n); }
|
||||
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'generic.carbon'
|
||||
// CHECK:STDOUT: source_filename = "generic.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CUse.Main(i32 %n) #0 !dbg !14 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc8_36.3.temp = alloca { i32, i32 }, align 4, !dbg !20
|
||||
// CHECK:STDOUT: %tuple = alloca { i32, i32 }, align 4, !dbg !20
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_36.3.temp), !dbg !20
|
||||
// CHECK:STDOUT: call void @_CPair.Main.2fad9574e050607e(ptr %.loc8_36.3.temp, i32 %n), !dbg !20
|
||||
// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc8_36.3.temp, i32 0, i32 0, !dbg !20
|
||||
// CHECK:STDOUT: %.loc8_36.5 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !20
|
||||
// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc8_36.3.temp, i32 0, i32 1, !dbg !20
|
||||
// CHECK:STDOUT: %.loc8_36.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !20
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %tuple), !dbg !20
|
||||
// CHECK:STDOUT: %tuple1 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple, i32 0, i32 0, !dbg !20
|
||||
// CHECK:STDOUT: store i32 %.loc8_36.5, ptr %tuple1, align 4, !dbg !20
|
||||
// CHECK:STDOUT: %tuple2 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple, i32 0, i32 1, !dbg !20
|
||||
// CHECK:STDOUT: store i32 %.loc8_36.6, ptr %tuple2, align 4, !dbg !20
|
||||
// CHECK:STDOUT: %IdFromGeneric.call = call i1 @_CIdFromGeneric.Main.1ac5a6b0e5910c46(i1 true), !dbg !25
|
||||
// CHECK:STDOUT: %Id.call = call i32 @_CId.Main.2fad9574e050607e(i32 %n), !dbg !31
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.35f6012581c5aabb:core.Destroy.Core"(ptr %.loc8_36.3.temp), !dbg !20
|
||||
// CHECK:STDOUT: ret i32 %Id.call, !dbg !32
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %self) #0 !dbg !34 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !36
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSubobjectDestroy.35f6012581c5aabb:core.Destroy.Core"(ptr %self) #0 !dbg !38 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 1, !dbg !40
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %tuple.elem1.tuple.elem), !dbg !40
|
||||
// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !40
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %tuple.elem0.tuple.elem), !dbg !40
|
||||
// CHECK:STDOUT: ret void, !dbg !40
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSelfDestruct.35f6012581c5aabb:core.Destroy.Core"(ptr %self) #0 !dbg !42 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @"_CSubobjectDestroy.35f6012581c5aabb:core.Destroy.Core"(ptr %self), !dbg !44
|
||||
// CHECK:STDOUT: ret void, !dbg !44
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @_CPair.Main.2fad9574e050607e(ptr sret({ i32, i32 }) %return, i32 %x) #0 !dbg !46 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 0, !dbg !49
|
||||
// CHECK:STDOUT: store i32 %x, ptr %tuple.elem0.tuple.elem, align 4, !dbg !49
|
||||
// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 1, !dbg !49
|
||||
// CHECK:STDOUT: store i32 %x, ptr %tuple.elem1.tuple.elem, align 4, !dbg !49
|
||||
// CHECK:STDOUT: ret void, !dbg !52
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr i1 @_CIdFromGeneric.Main.1ac5a6b0e5910c46(i1 %x) #0 !dbg !54 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %Id.call = call i1 @_CId.Main.1ac5a6b0e5910c46(i1 %x), !dbg !60
|
||||
// CHECK:STDOUT: ret i1 %Id.call, !dbg !61
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr i32 @_CId.Main.2fad9574e050607e(i32 %x) #0 !dbg !63 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !67
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr i1 @_CId.Main.1ac5a6b0e5910c46(i1 %x) #0 !dbg !69 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i1 %x, !dbg !73
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; uselistorder directives
|
||||
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// 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: !4 = !DIFile(filename: "generic.carbon", directory: "")
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// 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: !9 = !{null, !6}
|
||||
// CHECK:STDOUT: !10 = !DISubroutineType(types: !9)
|
||||
// CHECK:STDOUT: !11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
// CHECK:STDOUT: !12 = !{null, !11}
|
||||
// CHECK:STDOUT: !13 = !DISubroutineType(types: !12)
|
||||
// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Main", scope: null, file: !4, line: 7, type: !8, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !33)
|
||||
// CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !14, type: !6)
|
||||
// CHECK:STDOUT: !20 = !DILocation(line: 8, column: 30, scope: !14)
|
||||
// CHECK:STDOUT: !21 = !{!11, !6}
|
||||
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
|
||||
// CHECK:STDOUT: !25 = !DILocation(line: 9, column: 24, scope: !14)
|
||||
// CHECK:STDOUT: !26 = !{!11, !11}
|
||||
// CHECK:STDOUT: !27 = !DISubroutineType(types: !26)
|
||||
// CHECK:STDOUT: !31 = !DILocation(line: 10, column: 10, scope: !14)
|
||||
// CHECK:STDOUT: !32 = !DILocation(line: 10, column: 3, scope: !14)
|
||||
// CHECK:STDOUT: !33 = !{!15}
|
||||
// CHECK:STDOUT: !34 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core", scope: null, file: !4, line: 8, type: !10, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !37)
|
||||
// CHECK:STDOUT: !35 = !DILocalVariable(arg: 1, scope: !34, type: !6)
|
||||
// CHECK:STDOUT: !36 = !DILocation(line: 8, column: 30, scope: !34)
|
||||
// CHECK:STDOUT: !37 = !{!35}
|
||||
// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "SubobjectDestroy", linkageName: "_CSubobjectDestroy.35f6012581c5aabb:core.Destroy.Core", scope: null, file: !4, line: 8, type: !13, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !41)
|
||||
// CHECK:STDOUT: !39 = !DILocalVariable(arg: 1, scope: !38, type: !11)
|
||||
// CHECK:STDOUT: !40 = !DILocation(line: 8, column: 30, scope: !38)
|
||||
// CHECK:STDOUT: !41 = !{!39}
|
||||
// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.35f6012581c5aabb:core.Destroy.Core", scope: null, file: !4, line: 8, type: !13, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !45)
|
||||
// CHECK:STDOUT: !43 = !DILocalVariable(arg: 1, scope: !42, type: !11)
|
||||
// CHECK:STDOUT: !44 = !DILocation(line: 8, column: 30, scope: !42)
|
||||
// CHECK:STDOUT: !45 = !{!43}
|
||||
// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Pair", linkageName: "_CPair.Main.2fad9574e050607e", scope: null, file: !4, line: 4, type: !22, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !53)
|
||||
// CHECK:STDOUT: !47 = !DILocalVariable(arg: 1, scope: !46, type: !6)
|
||||
// CHECK:STDOUT: !49 = !DILocation(line: 4, column: 46, scope: !46)
|
||||
// CHECK:STDOUT: !52 = !DILocation(line: 4, column: 39, scope: !46)
|
||||
// CHECK:STDOUT: !53 = !{!47}
|
||||
// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "IdFromGeneric", linkageName: "_CIdFromGeneric.Main.1ac5a6b0e5910c46", scope: null, file: !4, line: 5, type: !27, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !62)
|
||||
// CHECK:STDOUT: !55 = !DILocalVariable(arg: 1, scope: !54, type: !11)
|
||||
// CHECK:STDOUT: !60 = !DILocation(line: 5, column: 52, scope: !54)
|
||||
// CHECK:STDOUT: !61 = !DILocation(line: 5, column: 45, scope: !54)
|
||||
// CHECK:STDOUT: !62 = !{!55}
|
||||
// CHECK:STDOUT: !63 = distinct !DISubprogram(name: "Id", linkageName: "_CId.Main.2fad9574e050607e", scope: null, file: !4, line: 3, type: !8, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !68)
|
||||
// CHECK:STDOUT: !64 = !DILocalVariable(arg: 1, scope: !63, type: !6)
|
||||
// CHECK:STDOUT: !67 = !DILocation(line: 3, column: 37, scope: !63)
|
||||
// CHECK:STDOUT: !68 = !{!64}
|
||||
// CHECK:STDOUT: !69 = distinct !DISubprogram(name: "Id", linkageName: "_CId.Main.1ac5a6b0e5910c46", scope: null, file: !4, line: 3, type: !27, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !74)
|
||||
// CHECK:STDOUT: !70 = !DILocalVariable(arg: 1, scope: !69, type: !11)
|
||||
// CHECK:STDOUT: !73 = !DILocation(line: 3, column: 37, scope: !69)
|
||||
// CHECK:STDOUT: !74 = !{!70}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'template.carbon'
|
||||
// CHECK:STDOUT: source_filename = "template.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CCallNegate.Main(i32 %a) #0 !dbg !77 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %Negate.call = call i32 @_CNegate.Main.55456748a8a2eb70(i32 %a), !dbg !83
|
||||
// CHECK:STDOUT: ret i32 %Negate.call, !dbg !84
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr i32 @_CNegate.Main.55456748a8a2eb70(i32 %a) #0 !dbg !86 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %Int.as.Negate.impl.Op.call = sub i32 0, %a, !dbg !89
|
||||
// CHECK:STDOUT: ret i32 %Int.as.Negate.impl.Op.call, !dbg !91
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!76}
|
||||
// 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: !75 = !DIFile(filename: "template.carbon", directory: "")
|
||||
// CHECK:STDOUT: !76 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !75, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !77 = distinct !DISubprogram(name: "CallNegate", linkageName: "_CCallNegate.Main", scope: null, file: !75, line: 5, type: !8, spFlags: DISPFlagDefinition, unit: !76, retainedNodes: !85)
|
||||
// CHECK:STDOUT: !78 = !DILocalVariable(arg: 1, scope: !77, type: !6)
|
||||
// CHECK:STDOUT: !83 = !DILocation(line: 5, column: 39, scope: !77)
|
||||
// CHECK:STDOUT: !84 = !DILocation(line: 5, column: 32, scope: !77)
|
||||
// CHECK:STDOUT: !85 = !{!78}
|
||||
// CHECK:STDOUT: !86 = distinct !DISubprogram(name: "Negate", linkageName: "_CNegate.Main.55456748a8a2eb70", scope: null, file: !75, line: 3, type: !8, spFlags: DISPFlagDefinition, unit: !76, retainedNodes: !92)
|
||||
// CHECK:STDOUT: !87 = !DILocalVariable(arg: 1, scope: !86, type: !6)
|
||||
// CHECK:STDOUT: !89 = !DILocation(line: 3, column: 52, scope: !86)
|
||||
// CHECK:STDOUT: !91 = !DILocation(line: 3, column: 45, scope: !86)
|
||||
// CHECK:STDOUT: !92 = !{!87}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'lib.carbon'
|
||||
// CHECK:STDOUT: source_filename = "lib.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!94}
|
||||
// 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: !93 = !DIFile(filename: "lib.carbon", directory: "")
|
||||
// CHECK:STDOUT: !94 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !93, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'use_lib.carbon'
|
||||
// CHECK:STDOUT: source_filename = "use_lib.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define void @_CUse.Main(ptr sret({ i32, i32 }) %return, i32 %n) #0 !dbg !97 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_CPair.Main.2fad9574e050607e(ptr %return, i32 %n), !dbg !103
|
||||
// CHECK:STDOUT: ret void, !dbg !104
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @_CPair.Main.2fad9574e050607e(ptr sret({ i32, i32 }) %return, i32 %x) #0 !dbg !106 {
|
||||
// CHECK:STDOUT: %tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 0, !dbg !109
|
||||
// CHECK:STDOUT: store i32 %x, ptr %tuple.elem, align 4, !dbg !109
|
||||
// CHECK:STDOUT: %tuple.elem1 = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 1, !dbg !109
|
||||
// CHECK:STDOUT: store i32 %x, ptr %tuple.elem1, align 4, !dbg !109
|
||||
// CHECK:STDOUT: ret void, !dbg !112
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!96}
|
||||
// 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: !11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
// CHECK:STDOUT: !21 = !{!11, !6}
|
||||
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
|
||||
// CHECK:STDOUT: !93 = !DIFile(filename: "lib.carbon", directory: "")
|
||||
// CHECK:STDOUT: !95 = !DIFile(filename: "use_lib.carbon", directory: "")
|
||||
// CHECK:STDOUT: !96 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !95, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !97 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Main", scope: null, file: !95, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !96, retainedNodes: !105)
|
||||
// CHECK:STDOUT: !98 = !DILocalVariable(arg: 1, scope: !97, type: !6)
|
||||
// CHECK:STDOUT: !103 = !DILocation(line: 5, column: 39, scope: !97)
|
||||
// CHECK:STDOUT: !104 = !DILocation(line: 5, column: 32, scope: !97)
|
||||
// CHECK:STDOUT: !105 = !{!98}
|
||||
// CHECK:STDOUT: !106 = distinct !DISubprogram(name: "Pair", linkageName: "_CPair.Main.2fad9574e050607e", scope: null, file: !93, line: 3, type: !22, spFlags: DISPFlagDefinition, unit: !96, retainedNodes: !113)
|
||||
// CHECK:STDOUT: !107 = !DILocalVariable(arg: 1, scope: !106, type: !6)
|
||||
// CHECK:STDOUT: !109 = !DILocation(line: 3, column: 46, scope: !106)
|
||||
// CHECK:STDOUT: !112 = !DILocation(line: 3, column: 39, scope: !106)
|
||||
// CHECK:STDOUT: !113 = !{!107}
|
||||
// CHECK:STDOUT:
|
||||
@@ -45,12 +45,36 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id,
|
||||
[&](SemIR::FunctionId function_id,
|
||||
SemIR::SpecificId resolved_specific_id) -> ExprCategory {
|
||||
const auto& function = ir->functions().Get(function_id);
|
||||
if (function.return_form_inst_id == ErrorInst::InstId) {
|
||||
return ExprCategory::Error;
|
||||
}
|
||||
|
||||
// For a deduced return type, we know the form independent of the
|
||||
// specific. Don't query the return form in the specific: in a generic,
|
||||
// it's computed by the definition's eval block, which might not have been
|
||||
// evaluated for this specific.
|
||||
// TODO: Once we support `->? auto`, we'll need the specific function
|
||||
// definition to be resolved here.
|
||||
CARBON_CHECK(!function.has_pending_deduced_return_type(),
|
||||
"Call to function before its return type is deduced");
|
||||
switch (function.deduced_return_kind) {
|
||||
case Function::DeducedReturnKind::None:
|
||||
break;
|
||||
case Function::DeducedReturnKind::Init:
|
||||
return ExprCategory::ReprInitializing;
|
||||
case Function::DeducedReturnKind::Ref:
|
||||
return ExprCategory::DurableRef;
|
||||
case Function::DeducedReturnKind::Value:
|
||||
return ExprCategory::Value;
|
||||
}
|
||||
|
||||
auto return_form_id =
|
||||
function.GetDeclaredReturnForm(*ir, resolved_specific_id);
|
||||
if (!return_form_id.has_value()) {
|
||||
// Treat as equivalent to `-> ()`.
|
||||
return ExprCategory::ReprInitializing;
|
||||
}
|
||||
|
||||
auto return_form = ir->insts().Get(return_form_id);
|
||||
CARBON_KIND_SWITCH(return_form) {
|
||||
case CARBON_KIND(InitForm _):
|
||||
@@ -358,6 +382,9 @@ auto FindStorageArgForInitializerInSpecific(const File& sem_ir, InstId init_id,
|
||||
case CARBON_KIND(RefForm _): {
|
||||
return {ir, InstId::None};
|
||||
}
|
||||
case CARBON_KIND(ValueForm _): {
|
||||
return {ir, InstId::None};
|
||||
}
|
||||
default:
|
||||
CARBON_FATAL("Unexpected inst kind: {0}", return_form);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user