mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Track and resolve the specific callee in a call to a generic function (#4395)
Add a new `specific_function` instruction that represents a generic function plus its deduced argument list as a callee in a function call. The new instruction can only appear as the immediate operand of a call instruction, so we give it a builtin placeholder type. At the end of each file, require definitions for all specific functions used in that file. Resolve the generic with the argument list to produce those specific function definitions as needed, and diagnose if the generic doesn't have a definition available. A few tests are updated in cases where they declared and used generic functions but didn't previously provide a function definition.
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/deduce.h"
|
||||
#include "toolchain/check/function.h"
|
||||
#include "toolchain/sem_ir/builtin_function_kind.h"
|
||||
#include "toolchain/sem_ir/builtin_inst_kind.h"
|
||||
#include "toolchain/sem_ir/entity_with_params_base.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
@@ -24,8 +26,8 @@ namespace Carbon::Check {
|
||||
// `self_id` and `arg_ids` are the self argument and explicit arguments in the
|
||||
// call.
|
||||
//
|
||||
// Returns a SpecificId for the specific callee, or `nullopt` if an error has
|
||||
// been diagnosed.
|
||||
// Returns a `SpecificId` for the specific callee, `SpecificId::Invalid` if the
|
||||
// callee is not generic, or `nullopt` if an error has been diagnosed.
|
||||
static auto ResolveCalleeInCall(Context& context, SemIR::LocId loc_id,
|
||||
const SemIR::EntityWithParamsBase& entity,
|
||||
llvm::StringLiteral entity_kind_for_diagnostic,
|
||||
@@ -141,10 +143,20 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
|
||||
// for the call.
|
||||
auto callee_specific_id = ResolveCalleeInCall(
|
||||
context, loc_id, callable, "function", callable.generic_id,
|
||||
callee_function.specific_id, callee_function.self_id, arg_ids);
|
||||
callee_function.enclosing_specific_id, callee_function.self_id, arg_ids);
|
||||
if (!callee_specific_id) {
|
||||
return SemIR::InstId::BuiltinError;
|
||||
}
|
||||
if (callee_specific_id->is_valid()) {
|
||||
callee_id =
|
||||
context.AddInst(context.insts().GetLocId(callee_id),
|
||||
SemIR::SpecificFunction{
|
||||
.type_id = context.GetBuiltinType(
|
||||
SemIR::BuiltinInstKind::SpecificFunctionType),
|
||||
.callee_id = callee_id,
|
||||
.specific_id = *callee_specific_id});
|
||||
context.definitions_required().push_back(callee_id);
|
||||
}
|
||||
|
||||
// If there is a return slot, build storage for the result.
|
||||
SemIR::InstId return_storage_id = SemIR::InstId::Invalid;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/diagnostic_helpers.h"
|
||||
#include "toolchain/check/function.h"
|
||||
#include "toolchain/check/generic.h"
|
||||
#include "toolchain/check/handle.h"
|
||||
#include "toolchain/check/import.h"
|
||||
#include "toolchain/check/import_ref.h"
|
||||
@@ -783,14 +784,18 @@ auto NodeIdTraversal::Next() -> std::optional<Parse::NodeId> {
|
||||
}
|
||||
}
|
||||
|
||||
// Emits a diagnostic for each declaration in context.definitions_required()
|
||||
// that doesn't have a definition.
|
||||
static auto DiagnoseMissingDefinitions(Context& context,
|
||||
Context::DiagnosticEmitter& emitter)
|
||||
// Checks that each required definition is available. If the definition can be
|
||||
// generated by resolving a specific, does so, otherwise emits a diagnostic for
|
||||
// each declaration in context.definitions_required() that doesn't have a
|
||||
// definition.
|
||||
static auto CheckRequiredDefinitions(Context& context,
|
||||
Context::DiagnosticEmitter& emitter)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(MissingDefinitionInImpl, Error,
|
||||
"no definition found for declaration in impl file");
|
||||
for (SemIR::InstId decl_inst_id : context.definitions_required()) {
|
||||
// Note that more required definitions can be added during this loop.
|
||||
for (size_t i = 0; i != context.definitions_required().size(); ++i) {
|
||||
SemIR::InstId decl_inst_id = context.definitions_required()[i];
|
||||
SemIR::Inst decl_inst = context.insts().Get(decl_inst_id);
|
||||
CARBON_KIND_SWITCH(context.insts().Get(decl_inst_id)) {
|
||||
case CARBON_KIND(SemIR::ClassDecl class_decl): {
|
||||
@@ -817,6 +822,25 @@ static auto DiagnoseMissingDefinitions(Context& context,
|
||||
// triggering https://github.com/carbon-language/carbon-lang/issues/4071
|
||||
CARBON_FATAL("TODO: Support interfaces in DiagnoseMissingDefinitions");
|
||||
}
|
||||
case CARBON_KIND(SemIR::SpecificFunction specific_function): {
|
||||
if (!ResolveSpecificDefinition(context,
|
||||
specific_function.specific_id)) {
|
||||
CARBON_DIAGNOSTIC(MissingGenericFunctionDefinition, Error,
|
||||
"use of undefined generic function");
|
||||
CARBON_DIAGNOSTIC(MissingGenericFunctionDefinitionHere, Note,
|
||||
"generic function declared here");
|
||||
auto generic_decl_id =
|
||||
context.generics()
|
||||
.Get(context.specifics()
|
||||
.Get(specific_function.specific_id)
|
||||
.generic_id)
|
||||
.decl_id;
|
||||
emitter.Build(decl_inst_id, MissingGenericFunctionDefinition)
|
||||
.Note(generic_decl_id, MissingGenericFunctionDefinitionHere)
|
||||
.Emit();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
CARBON_FATAL("Unexpected inst in definitions_required: {0}", decl_inst);
|
||||
}
|
||||
@@ -908,9 +932,9 @@ static auto CheckParseTree(
|
||||
return;
|
||||
}
|
||||
|
||||
context.Finalize();
|
||||
CheckRequiredDefinitions(context, emitter);
|
||||
|
||||
DiagnoseMissingDefinitions(context, emitter);
|
||||
context.Finalize();
|
||||
|
||||
context.VerifyOnFinish();
|
||||
|
||||
|
||||
@@ -918,6 +918,7 @@ class TypeCompleter {
|
||||
case SemIR::BuiltinInstKind::NamespaceType:
|
||||
case SemIR::BuiltinInstKind::BoundMethodType:
|
||||
case SemIR::BuiltinInstKind::WitnessType:
|
||||
case SemIR::BuiltinInstKind::SpecificFunctionType:
|
||||
return MakeCopyValueRepr(type_id);
|
||||
|
||||
case SemIR::BuiltinInstKind::StringType:
|
||||
|
||||
@@ -1190,8 +1190,9 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
return RebuildAndValidateIfFieldsAreConstant(
|
||||
eval_context, inst,
|
||||
[&](SemIR::IntType result) {
|
||||
return ValidateIntType(eval_context.context(),
|
||||
int_type.bit_width_id, result);
|
||||
return ValidateIntType(
|
||||
eval_context.context(),
|
||||
inst_id.is_valid() ? inst_id : int_type.bit_width_id, result);
|
||||
},
|
||||
&SemIR::IntType::bit_width_id);
|
||||
}
|
||||
@@ -1207,6 +1208,10 @@ static auto TryEvalInstInContext(EvalContext& eval_context,
|
||||
},
|
||||
&SemIR::FloatType::bit_width_id);
|
||||
}
|
||||
case SemIR::SpecificFunction::Kind:
|
||||
return RebuildIfFieldsAreConstant(eval_context, inst,
|
||||
&SemIR::SpecificFunction::callee_id,
|
||||
&SemIR::SpecificFunction::specific_id);
|
||||
case SemIR::StructType::Kind:
|
||||
return RebuildIfFieldsAreConstant(eval_context, inst,
|
||||
&SemIR::StructType::fields_id);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
// CHECK:STDOUT: instFloatType: {kind: BuiltinInst, arg0: FloatType, type: typeTypeType}
|
||||
// CHECK:STDOUT: instStringType: {kind: BuiltinInst, arg0: StringType, type: typeTypeType}
|
||||
// CHECK:STDOUT: instBoundMethodType: {kind: BuiltinInst, arg0: BoundMethodType, type: typeTypeType}
|
||||
// CHECK:STDOUT: instSpecificFunctionType: {kind: BuiltinInst, arg0: SpecificFunctionType, type: typeTypeType}
|
||||
// CHECK:STDOUT: instNamespaceType: {kind: BuiltinInst, arg0: NamespaceType, type: typeTypeType}
|
||||
// CHECK:STDOUT: instWitnessType: {kind: BuiltinInst, arg0: WitnessType, type: typeTypeType}
|
||||
// CHECK:STDOUT: 'inst+0': {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type(instNamespaceType)}
|
||||
@@ -47,6 +48,7 @@
|
||||
// CHECK:STDOUT: instFloatType: templateConstant(instFloatType)
|
||||
// CHECK:STDOUT: instStringType: templateConstant(instStringType)
|
||||
// CHECK:STDOUT: instBoundMethodType: templateConstant(instBoundMethodType)
|
||||
// CHECK:STDOUT: instSpecificFunctionType: templateConstant(instSpecificFunctionType)
|
||||
// CHECK:STDOUT: instNamespaceType: templateConstant(instNamespaceType)
|
||||
// CHECK:STDOUT: instWitnessType: templateConstant(instWitnessType)
|
||||
// CHECK:STDOUT: 'inst+0': templateConstant(inst+0)
|
||||
|
||||
+8
-4
@@ -419,6 +419,7 @@ class Class(U:! type) {
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %F.type.3: type = fn_type @F.2 [template]
|
||||
// CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.7: <specific function> = specific_function %F.2, @F.1(i32) [template]
|
||||
// CHECK:STDOUT: %UseField.type: type = fn_type @UseField [template]
|
||||
// CHECK:STDOUT: %UseField: %UseField.type = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -502,9 +503,10 @@ class Class(U:! type) {
|
||||
// CHECK:STDOUT: %F.call.loc6: init %CompleteClass.3 = call %F.ref.loc6() to %.loc6_7
|
||||
// CHECK:STDOUT: assign %v.var, %F.call.loc6
|
||||
// CHECK:STDOUT: %v.ref: ref %CompleteClass.3 = name_ref v, %v
|
||||
// CHECK:STDOUT: %.loc7_11: %F.type.2 = specific_constant imports.%import_ref.7, @CompleteClass(i32) [template = constants.%F.2]
|
||||
// CHECK:STDOUT: %F.ref.loc7: %F.type.2 = name_ref F, %.loc7_11 [template = constants.%F.2]
|
||||
// CHECK:STDOUT: %F.call.loc7: init i32 = call %F.ref.loc7()
|
||||
// CHECK:STDOUT: %.loc7_11.1: %F.type.2 = specific_constant imports.%import_ref.7, @CompleteClass(i32) [template = constants.%F.2]
|
||||
// CHECK:STDOUT: %F.ref.loc7: %F.type.2 = name_ref F, %.loc7_11.1 [template = constants.%F.2]
|
||||
// CHECK:STDOUT: %.loc7_11.2: <specific function> = specific_function %F.ref.loc7, @F.1(i32) [template = constants.%.7]
|
||||
// CHECK:STDOUT: %F.call.loc7: init i32 = call %.loc7_11.2()
|
||||
// CHECK:STDOUT: %.loc7_15.1: i32 = value_of_initializer %F.call.loc7
|
||||
// CHECK:STDOUT: %.loc7_15.2: i32 = converted %F.call.loc7, %.loc7_15.1
|
||||
// CHECK:STDOUT: return %.loc7_15.2
|
||||
@@ -564,7 +566,9 @@ class Class(U:! type) {
|
||||
// CHECK:STDOUT: %F => constants.%F.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.1(i32) {}
|
||||
// CHECK:STDOUT: specific @F.1(i32) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_generic_arg_mismatch.carbon
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+39
-20
@@ -268,7 +268,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %.loc15_11.1: %Get.type.2 = specific_constant @Class.%Get.decl, @Class(i32) [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %Get.ref: %Get.type.2 = name_ref Get, %.loc15_11.1 [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %.loc15_11.2: <bound method> = bound_method %x.ref, %Get.ref
|
||||
// CHECK:STDOUT: %Get.call: init i32 = call %.loc15_11.2(%x.ref)
|
||||
// CHECK:STDOUT: %.loc15_11.3: <specific function> = specific_function %.loc15_11.2, @Get(i32)
|
||||
// CHECK:STDOUT: %Get.call: init i32 = call %.loc15_11.3(%x.ref)
|
||||
// CHECK:STDOUT: %.loc15_17.1: i32 = value_of_initializer %Get.call
|
||||
// CHECK:STDOUT: %.loc15_17.2: i32 = converted %Get.call, %.loc15_17.1
|
||||
// CHECK:STDOUT: return %.loc15_17.2
|
||||
@@ -281,8 +282,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %.loc19_12.2: %GetAddr.type.2 = specific_constant @Class.%GetAddr.decl, @Class(i32) [template = constants.%GetAddr.2]
|
||||
// CHECK:STDOUT: %GetAddr.ref: %GetAddr.type.2 = name_ref GetAddr, %.loc19_12.2 [template = constants.%GetAddr.2]
|
||||
// CHECK:STDOUT: %.loc19_12.3: <bound method> = bound_method %.loc19_12.1, %GetAddr.ref
|
||||
// CHECK:STDOUT: %.loc19_12.4: %.12 = addr_of %.loc19_12.1
|
||||
// CHECK:STDOUT: %GetAddr.call: init %.13 = call %.loc19_12.3(%.loc19_12.4)
|
||||
// CHECK:STDOUT: %.loc19_12.4: <specific function> = specific_function %.loc19_12.3, @GetAddr(i32)
|
||||
// CHECK:STDOUT: %.loc19_12.5: %.12 = addr_of %.loc19_12.1
|
||||
// CHECK:STDOUT: %GetAddr.call: init %.13 = call %.loc19_12.4(%.loc19_12.5)
|
||||
// CHECK:STDOUT: %.loc19_21.1: %.13 = value_of_initializer %GetAddr.call
|
||||
// CHECK:STDOUT: %.loc19_21.2: %.13 = converted %GetAddr.call, %.loc19_21.1
|
||||
// CHECK:STDOUT: %.loc19_10.1: ref i32 = deref %.loc19_21.2
|
||||
@@ -345,6 +347,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: specific @Get(i32) {
|
||||
// CHECK:STDOUT: %T => i32
|
||||
// CHECK:STDOUT: %Class => constants.%Class.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc5_42.3 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @GetAddr(i32) {
|
||||
@@ -352,6 +357,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %Class => constants.%Class.3
|
||||
// CHECK:STDOUT: %.loc7_29.1 => constants.%.12
|
||||
// CHECK:STDOUT: %.loc7_38.1 => constants.%.13
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_54.3 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_static_member_fn_call.carbon
|
||||
@@ -370,6 +378,7 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %struct: %Class.2 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %StaticMemberFunctionCall.type: type = fn_type @StaticMemberFunctionCall [template]
|
||||
// CHECK:STDOUT: %StaticMemberFunctionCall: %StaticMemberFunctionCall.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %Make, @Make(%T) [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.1: type = generic_interface_type @ImplicitAs [template]
|
||||
// CHECK:STDOUT: %ImplicitAs: %ImplicitAs.type.1 = struct_value () [template]
|
||||
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic]
|
||||
@@ -378,14 +387,14 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %Self.2: %ImplicitAs.type.2 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.5: type = assoc_entity_type %ImplicitAs.type.2, %Convert.type.1 [symbolic]
|
||||
// CHECK:STDOUT: %.6: %.5 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %.6: type = assoc_entity_type %ImplicitAs.type.2, %Convert.type.1 [symbolic]
|
||||
// CHECK:STDOUT: %.7: %.6 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.3: type = interface_type @ImplicitAs, @ImplicitAs(%Class.2) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert, @ImplicitAs(%Class.2) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.7: type = assoc_entity_type %ImplicitAs.type.3, %Convert.type.2 [symbolic]
|
||||
// CHECK:STDOUT: %.8: %.7 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %.9: %.5 = assoc_entity element0, imports.%import_ref.6 [symbolic]
|
||||
// CHECK:STDOUT: %.8: type = assoc_entity_type %ImplicitAs.type.3, %Convert.type.2 [symbolic]
|
||||
// CHECK:STDOUT: %.9: %.8 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %.10: %.6 = assoc_entity element0, imports.%import_ref.6 [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -402,7 +411,7 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref.1: %ImplicitAs.type.1 = import_ref Core//prelude/operators/as, inst+40, loaded [template = constants.%ImplicitAs]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref Core//prelude/operators/as, inst+45, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.1 (%.5) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.9)]
|
||||
// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.1 (%.6) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.10)]
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
@@ -441,8 +450,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %Self: %ImplicitAs.type.2 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.2)]
|
||||
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
|
||||
// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.2), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.1 (constants.%.5)]
|
||||
// CHECK:STDOUT: %.2: @ImplicitAs.%.1 (%.5) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.2), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.1 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.2: @ImplicitAs.%.1 (%.6) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.2 (constants.%.7)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: !members:
|
||||
@@ -497,23 +506,25 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type: type = fn_type @Make, @Class(%T.loc8_29.2) [symbolic = %Make.type (constants.%Make.type)]
|
||||
// CHECK:STDOUT: %Make: @StaticMemberFunctionCall.%Make.type (%Make.type) = struct_value () [symbolic = %Make (constants.%Make)]
|
||||
// CHECK:STDOUT: %.loc15_18.3: <specific function> = specific_function %Make, @Make(%T.loc8_29.2) [symbolic = %.loc15_18.3 (constants.%.5)]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.loc15_25.2: type = interface_type @ImplicitAs, @ImplicitAs(%Class.loc8_47.2) [symbolic = %ImplicitAs.type.loc15_25.2 (constants.%ImplicitAs.type.3)]
|
||||
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%Class.loc8_47.2) [symbolic = %Convert.type (constants.%Convert.type.2)]
|
||||
// CHECK:STDOUT: %.loc15_25.3: type = assoc_entity_type @StaticMemberFunctionCall.%ImplicitAs.type.loc15_25.2 (%ImplicitAs.type.3), @StaticMemberFunctionCall.%Convert.type (%Convert.type.2) [symbolic = %.loc15_25.3 (constants.%.7)]
|
||||
// CHECK:STDOUT: %.loc15_25.4: @StaticMemberFunctionCall.%.loc15_25.3 (%.7) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.loc15_25.4 (constants.%.8)]
|
||||
// CHECK:STDOUT: %.loc15_25.3: type = assoc_entity_type @StaticMemberFunctionCall.%ImplicitAs.type.loc15_25.2 (%ImplicitAs.type.3), @StaticMemberFunctionCall.%Convert.type (%Convert.type.2) [symbolic = %.loc15_25.3 (constants.%.8)]
|
||||
// CHECK:STDOUT: %.loc15_25.4: @StaticMemberFunctionCall.%.loc15_25.3 (%.8) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.loc15_25.4 (constants.%.9)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc8_29.1: type) -> %return: @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Class.ref.loc15: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
|
||||
// CHECK:STDOUT: %T.ref.loc15: type = name_ref T, %T.loc8_29.1 [symbolic = %T.loc8_29.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %Class.loc15: type = class_type @Class, @Class(constants.%T) [symbolic = %Class.loc8_47.2 (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %.loc15_18: @StaticMemberFunctionCall.%Make.type (%Make.type) = specific_constant @Class.%Make.decl, @Class(constants.%T) [symbolic = %Make (constants.%Make)]
|
||||
// CHECK:STDOUT: %Make.ref: @StaticMemberFunctionCall.%Make.type (%Make.type) = name_ref Make, %.loc15_18 [symbolic = %Make (constants.%Make)]
|
||||
// CHECK:STDOUT: %.loc15_18.1: @StaticMemberFunctionCall.%Make.type (%Make.type) = specific_constant @Class.%Make.decl, @Class(constants.%T) [symbolic = %Make (constants.%Make)]
|
||||
// CHECK:STDOUT: %Make.ref: @StaticMemberFunctionCall.%Make.type (%Make.type) = name_ref Make, %.loc15_18.1 [symbolic = %Make (constants.%Make)]
|
||||
// CHECK:STDOUT: %.loc15_18.2: <specific function> = specific_function %Make.ref, @Make(constants.%T) [symbolic = %.loc15_18.3 (constants.%.5)]
|
||||
// CHECK:STDOUT: %.loc15_23.1: ref @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) = temporary_storage
|
||||
// CHECK:STDOUT: %Make.call: init @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) = call %Make.ref() to %.loc15_23.1
|
||||
// CHECK:STDOUT: %Make.call: init @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) = call %.loc15_18.2() to %.loc15_23.1
|
||||
// CHECK:STDOUT: %ImplicitAs.type.loc15_25.1: type = interface_type @ImplicitAs, @ImplicitAs(constants.%Class.2) [symbolic = %ImplicitAs.type.loc15_25.2 (constants.%ImplicitAs.type.3)]
|
||||
// CHECK:STDOUT: %.loc15_25.1: @StaticMemberFunctionCall.%.loc15_25.3 (%.7) = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%Class.2) [symbolic = %.loc15_25.4 (constants.%.8)]
|
||||
// CHECK:STDOUT: %Convert.ref: @StaticMemberFunctionCall.%.loc15_25.3 (%.7) = name_ref Convert, %.loc15_25.1 [symbolic = %.loc15_25.4 (constants.%.8)]
|
||||
// CHECK:STDOUT: %.loc15_25.1: @StaticMemberFunctionCall.%.loc15_25.3 (%.8) = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%Class.2) [symbolic = %.loc15_25.4 (constants.%.9)]
|
||||
// CHECK:STDOUT: %Convert.ref: @StaticMemberFunctionCall.%.loc15_25.3 (%.8) = name_ref Convert, %.loc15_25.1 [symbolic = %.loc15_25.4 (constants.%.9)]
|
||||
// CHECK:STDOUT: %.loc15_23.2: ref @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) = temporary %.loc15_23.1, %Make.call
|
||||
// CHECK:STDOUT: %.loc15_25.2: @StaticMemberFunctionCall.%Class.loc8_47.2 (%Class.2) = converted %Make.call, <error> [template = <error>]
|
||||
// CHECK:STDOUT: return <error> to %return
|
||||
@@ -543,6 +554,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: specific @Make(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class.loc5_21.1 => constants.%Class.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %struct => constants.%struct
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(@Class.%T.loc4_13.2) {
|
||||
@@ -584,8 +598,13 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
|
||||
// CHECK:STDOUT: %Self => constants.%Self.2
|
||||
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.2
|
||||
// CHECK:STDOUT: %Convert => constants.%Convert.2
|
||||
// CHECK:STDOUT: %.1 => constants.%.7
|
||||
// CHECK:STDOUT: %.2 => constants.%.8
|
||||
// CHECK:STDOUT: %.1 => constants.%.8
|
||||
// CHECK:STDOUT: %.2 => constants.%.9
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(@StaticMemberFunctionCall.%T.loc8_29.2) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class.loc5_21.1 => constants.%Class.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ImplicitAs(@StaticMemberFunctionCall.%Class.loc8_47.2) {
|
||||
|
||||
+132
-28
@@ -12,8 +12,8 @@ class A {}
|
||||
class B {}
|
||||
|
||||
class Class(T:! type) {
|
||||
fn Get(U:! type) -> (T, U);
|
||||
fn GetNoDeduce(x: T, U:! type) -> (T, U);
|
||||
fn Get(U:! type) -> (T, U) { return Get(U); }
|
||||
fn GetNoDeduce(x: T, U:! type) -> (T, U) { return GetNoDeduce(x, U); }
|
||||
}
|
||||
|
||||
fn CallGenericMethod(c: Class(A)) -> (A, B) {
|
||||
@@ -43,19 +43,24 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %Get.1: %Get.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %GetNoDeduce.type.1: type = fn_type @GetNoDeduce, @Class(%T) [symbolic]
|
||||
// CHECK:STDOUT: %GetNoDeduce.1: %GetNoDeduce.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.5 [symbolic]
|
||||
// CHECK:STDOUT: %.7: <specific function> = specific_function %Get.1, @Get(%T, %U) [symbolic]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %GetNoDeduce.1, @GetNoDeduce(%T, %U) [symbolic]
|
||||
// CHECK:STDOUT: %Class.3: type = class_type @Class, @Class(%A) [template]
|
||||
// CHECK:STDOUT: %.6: type = tuple_type (%A, %B) [template]
|
||||
// CHECK:STDOUT: %.9: type = tuple_type (%A, %B) [template]
|
||||
// CHECK:STDOUT: %CallGenericMethod.type: type = fn_type @CallGenericMethod [template]
|
||||
// CHECK:STDOUT: %CallGenericMethod: %CallGenericMethod.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.8: type = tuple_type (%.7, %.7) [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
|
||||
// CHECK:STDOUT: %.10: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.11: type = tuple_type (%.10, %.10) [template]
|
||||
// CHECK:STDOUT: %.12: type = ptr_type %.11 [template]
|
||||
// CHECK:STDOUT: %Get.type.2: type = fn_type @Get, @Class(%A) [template]
|
||||
// CHECK:STDOUT: %Get.2: %Get.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %GetNoDeduce.type.2: type = fn_type @GetNoDeduce, @Class(%A) [template]
|
||||
// CHECK:STDOUT: %GetNoDeduce.2: %GetNoDeduce.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.13: <specific function> = specific_function %Get.2, @Get(%A, %B) [template]
|
||||
// CHECK:STDOUT: %CallGenericMethodWithNonDeducedParam.type: type = fn_type @CallGenericMethodWithNonDeducedParam [template]
|
||||
// CHECK:STDOUT: %CallGenericMethodWithNonDeducedParam: %CallGenericMethodWithNonDeducedParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.14: <specific function> = specific_function %GetNoDeduce.2, @GetNoDeduce(%A, %B) [template]
|
||||
// CHECK:STDOUT: %struct: %A = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -101,8 +106,8 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %A.ref.loc19_39: type = name_ref A, file.%A.decl [template = constants.%A]
|
||||
// CHECK:STDOUT: %B.ref.loc19: type = name_ref B, file.%B.decl [template = constants.%B]
|
||||
// CHECK:STDOUT: %.loc19_43.1: %.4 = tuple_literal (%A.ref.loc19_39, %B.ref.loc19)
|
||||
// CHECK:STDOUT: %.loc19_43.2: type = converted %.loc19_43.1, constants.%.6 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %return: ref %.6 = var <return slot>
|
||||
// CHECK:STDOUT: %.loc19_43.2: type = converted %.loc19_43.1, constants.%.9 [template = constants.%.9]
|
||||
// CHECK:STDOUT: %return: ref %.9 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallGenericMethodWithNonDeducedParam.decl: %CallGenericMethodWithNonDeducedParam.type = fn_decl @CallGenericMethodWithNonDeducedParam [template = constants.%CallGenericMethodWithNonDeducedParam] {
|
||||
// CHECK:STDOUT: %c.patt: %Class.3 = binding_pattern c
|
||||
@@ -115,8 +120,8 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %A.ref.loc23_58: type = name_ref A, file.%A.decl [template = constants.%A]
|
||||
// CHECK:STDOUT: %B.ref.loc23: type = name_ref B, file.%B.decl [template = constants.%B]
|
||||
// CHECK:STDOUT: %.loc23_62.1: %.4 = tuple_literal (%A.ref.loc23_58, %B.ref.loc23)
|
||||
// CHECK:STDOUT: %.loc23_62.2: type = converted %.loc23_62.1, constants.%.6 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %return: ref %.6 = var <return slot>
|
||||
// CHECK:STDOUT: %.loc23_62.2: type = converted %.loc23_62.1, constants.%.9 [template = constants.%.9]
|
||||
// CHECK:STDOUT: %return: ref %.9 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -150,8 +155,8 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %U.param: type = param U, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %U.loc15_10.1: type = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc15_10.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, @Class.%T.loc14_13.1 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %U.ref: type = name_ref U, %U.loc15_10.1 [symbolic = %U.loc15_10.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc15_28.2: %.4 = tuple_literal (%T.ref, %U.ref)
|
||||
// CHECK:STDOUT: %U.ref.loc15_27: type = name_ref U, %U.loc15_10.1 [symbolic = %U.loc15_10.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc15_28.2: %.4 = tuple_literal (%T.ref, %U.ref.loc15_27)
|
||||
// CHECK:STDOUT: %.loc15_28.3: type = converted %.loc15_28.2, constants.%.5 [symbolic = %.loc15_28.1 (constants.%.5)]
|
||||
// CHECK:STDOUT: %return: ref @Get.%.loc15_28.1 (%.5) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -165,8 +170,8 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %U.param: type = param U, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %U.loc16_24.1: type = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc16_24.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %T.ref.loc16_38: type = name_ref T, @Class.%T.loc14_13.1 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %U.ref: type = name_ref U, %U.loc16_24.1 [symbolic = %U.loc16_24.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc16_42.2: %.4 = tuple_literal (%T.ref.loc16_38, %U.ref)
|
||||
// CHECK:STDOUT: %U.ref.loc16_41: type = name_ref U, %U.loc16_24.1 [symbolic = %U.loc16_24.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc16_42.2: %.4 = tuple_literal (%T.ref.loc16_38, %U.ref.loc16_41)
|
||||
// CHECK:STDOUT: %.loc16_42.3: type = converted %.loc16_42.2, constants.%.5 [symbolic = %.loc16_42.1 (constants.%.5)]
|
||||
// CHECK:STDOUT: %return: ref @GetNoDeduce.%.loc16_42.1 (%.5) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -184,7 +189,32 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc15_28.1: type = tuple_type (@Get.%T (%T), @Get.%U.loc15_10.2 (%U)) [symbolic = %.loc15_28.1 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%U.loc15_10.1: type) -> @Get.%.loc15_28.1 (%.5);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Get.type: type = fn_type @Get, @Class(%T) [symbolic = %Get.type (constants.%Get.type.1)]
|
||||
// CHECK:STDOUT: %Get: @Get.%Get.type (%Get.type.1) = struct_value () [symbolic = %Get (constants.%Get.1)]
|
||||
// CHECK:STDOUT: %.loc15_39.3: <specific function> = specific_function %Get, @Get(%T, %U.loc15_10.2) [symbolic = %.loc15_39.3 (constants.%.7)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%U.loc15_10.1: type) -> %return: @Get.%.loc15_28.1 (%.5) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc15_39.1: @Get.%Get.type (%Get.type.1) = specific_constant @Class.%Get.decl, @Class(constants.%T) [symbolic = %Get (constants.%Get.1)]
|
||||
// CHECK:STDOUT: %Get.ref: @Get.%Get.type (%Get.type.1) = name_ref Get, %.loc15_39.1 [symbolic = %Get (constants.%Get.1)]
|
||||
// CHECK:STDOUT: %U.ref.loc15_43: type = name_ref U, %U.loc15_10.1 [symbolic = %U.loc15_10.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc15_39.2: <specific function> = specific_function %Get.ref, @Get(constants.%T, constants.%U) [symbolic = %.loc15_39.3 (constants.%.7)]
|
||||
// CHECK:STDOUT: %.loc15_42.1: ref @Get.%.loc15_28.1 (%.5) = temporary_storage
|
||||
// CHECK:STDOUT: %Get.call: init @Get.%.loc15_28.1 (%.5) = call %.loc15_39.2() to %.loc15_42.1
|
||||
// CHECK:STDOUT: %.loc15_42.2: ref @Get.%.loc15_28.1 (%.5) = temporary %.loc15_42.1, %Get.call
|
||||
// CHECK:STDOUT: %.loc15_42.3: ref @Get.%T (%T) = tuple_access %.loc15_42.2, element0
|
||||
// CHECK:STDOUT: %.loc15_42.4: @Get.%T (%T) = bind_value %.loc15_42.3
|
||||
// CHECK:STDOUT: %.loc15_42.5: ref @Get.%T (%T) = tuple_access %return, element0
|
||||
// CHECK:STDOUT: %.loc15_42.6: init @Get.%T (%T) = initialize_from %.loc15_42.4 to %.loc15_42.5
|
||||
// CHECK:STDOUT: %.loc15_42.7: ref @Get.%U.loc15_10.2 (%U) = tuple_access %.loc15_42.2, element1
|
||||
// CHECK:STDOUT: %.loc15_42.8: @Get.%U.loc15_10.2 (%U) = bind_value %.loc15_42.7
|
||||
// CHECK:STDOUT: %.loc15_42.9: ref @Get.%U.loc15_10.2 (%U) = tuple_access %return, element1
|
||||
// CHECK:STDOUT: %.loc15_42.10: init @Get.%U.loc15_10.2 (%U) = initialize_from %.loc15_42.8 to %.loc15_42.9
|
||||
// CHECK:STDOUT: %.loc15_42.11: init @Get.%.loc15_28.1 (%.5) = tuple_init (%.loc15_42.6, %.loc15_42.10) to %return
|
||||
// CHECK:STDOUT: %.loc15_45: init @Get.%.loc15_28.1 (%.5) = converted %Get.call, %.loc15_42.11
|
||||
// CHECK:STDOUT: return %.loc15_45 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @GetNoDeduce(@Class.%T.loc14_13.1: type, %U.loc16_24.1: type) {
|
||||
@@ -192,57 +222,121 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: %U.loc16_24.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc16_24.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc16_42.1: type = tuple_type (@GetNoDeduce.%T (%T), @GetNoDeduce.%U.loc16_24.2 (%U)) [symbolic = %.loc16_42.1 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%x: @GetNoDeduce.%T (%T), %U.loc16_24.1: type) -> @GetNoDeduce.%.loc16_42.1 (%.5);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %GetNoDeduce.type: type = fn_type @GetNoDeduce, @Class(%T) [symbolic = %GetNoDeduce.type (constants.%GetNoDeduce.type.1)]
|
||||
// CHECK:STDOUT: %GetNoDeduce: @GetNoDeduce.%GetNoDeduce.type (%GetNoDeduce.type.1) = struct_value () [symbolic = %GetNoDeduce (constants.%GetNoDeduce.1)]
|
||||
// CHECK:STDOUT: %.loc16_53.3: <specific function> = specific_function %GetNoDeduce, @GetNoDeduce(%T, %U.loc16_24.2) [symbolic = %.loc16_53.3 (constants.%.8)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%x: @GetNoDeduce.%T (%T), %U.loc16_24.1: type) -> %return: @GetNoDeduce.%.loc16_42.1 (%.5) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc16_53.1: @GetNoDeduce.%GetNoDeduce.type (%GetNoDeduce.type.1) = specific_constant @Class.%GetNoDeduce.decl, @Class(constants.%T) [symbolic = %GetNoDeduce (constants.%GetNoDeduce.1)]
|
||||
// CHECK:STDOUT: %GetNoDeduce.ref: @GetNoDeduce.%GetNoDeduce.type (%GetNoDeduce.type.1) = name_ref GetNoDeduce, %.loc16_53.1 [symbolic = %GetNoDeduce (constants.%GetNoDeduce.1)]
|
||||
// CHECK:STDOUT: %x.ref: @GetNoDeduce.%T (%T) = name_ref x, %x
|
||||
// CHECK:STDOUT: %U.ref.loc16_68: type = name_ref U, %U.loc16_24.1 [symbolic = %U.loc16_24.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc16_53.2: <specific function> = specific_function %GetNoDeduce.ref, @GetNoDeduce(constants.%T, constants.%U) [symbolic = %.loc16_53.3 (constants.%.8)]
|
||||
// CHECK:STDOUT: %.loc16_64.1: ref @GetNoDeduce.%.loc16_42.1 (%.5) = temporary_storage
|
||||
// CHECK:STDOUT: %GetNoDeduce.call: init @GetNoDeduce.%.loc16_42.1 (%.5) = call %.loc16_53.2(%x.ref) to %.loc16_64.1
|
||||
// CHECK:STDOUT: %.loc16_64.2: ref @GetNoDeduce.%.loc16_42.1 (%.5) = temporary %.loc16_64.1, %GetNoDeduce.call
|
||||
// CHECK:STDOUT: %.loc16_64.3: ref @GetNoDeduce.%T (%T) = tuple_access %.loc16_64.2, element0
|
||||
// CHECK:STDOUT: %.loc16_64.4: @GetNoDeduce.%T (%T) = bind_value %.loc16_64.3
|
||||
// CHECK:STDOUT: %.loc16_64.5: ref @GetNoDeduce.%T (%T) = tuple_access %return, element0
|
||||
// CHECK:STDOUT: %.loc16_64.6: init @GetNoDeduce.%T (%T) = initialize_from %.loc16_64.4 to %.loc16_64.5
|
||||
// CHECK:STDOUT: %.loc16_64.7: ref @GetNoDeduce.%U.loc16_24.2 (%U) = tuple_access %.loc16_64.2, element1
|
||||
// CHECK:STDOUT: %.loc16_64.8: @GetNoDeduce.%U.loc16_24.2 (%U) = bind_value %.loc16_64.7
|
||||
// CHECK:STDOUT: %.loc16_64.9: ref @GetNoDeduce.%U.loc16_24.2 (%U) = tuple_access %return, element1
|
||||
// CHECK:STDOUT: %.loc16_64.10: init @GetNoDeduce.%U.loc16_24.2 (%U) = initialize_from %.loc16_64.8 to %.loc16_64.9
|
||||
// CHECK:STDOUT: %.loc16_64.11: init @GetNoDeduce.%.loc16_42.1 (%.5) = tuple_init (%.loc16_64.6, %.loc16_64.10) to %return
|
||||
// CHECK:STDOUT: %.loc16_70: init @GetNoDeduce.%.loc16_42.1 (%.5) = converted %GetNoDeduce.call, %.loc16_64.11
|
||||
// CHECK:STDOUT: return %.loc16_70 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallGenericMethod(%c: %Class.3) -> %return: %.6 {
|
||||
// CHECK:STDOUT: fn @CallGenericMethod(%c: %Class.3) -> %return: %.9 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %c.ref: %Class.3 = name_ref c, %c
|
||||
// CHECK:STDOUT: %.loc20: %Get.type.2 = specific_constant @Class.%Get.decl, @Class(constants.%A) [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %Get.ref: %Get.type.2 = name_ref Get, %.loc20 [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %.loc20_11.1: %Get.type.2 = specific_constant @Class.%Get.decl, @Class(constants.%A) [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %Get.ref: %Get.type.2 = name_ref Get, %.loc20_11.1 [template = constants.%Get.2]
|
||||
// CHECK:STDOUT: %B.ref.loc20: type = name_ref B, file.%B.decl [template = constants.%B]
|
||||
// CHECK:STDOUT: %.loc19_35: ref %.6 = splice_block %return {}
|
||||
// CHECK:STDOUT: %Get.call: init %.6 = call %Get.ref() to %.loc19_35
|
||||
// CHECK:STDOUT: %.loc20_11.2: <specific function> = specific_function %Get.ref, @Get(constants.%A, constants.%B) [template = constants.%.13]
|
||||
// CHECK:STDOUT: %.loc19_35: ref %.9 = splice_block %return {}
|
||||
// CHECK:STDOUT: %Get.call: init %.9 = call %.loc20_11.2() to %.loc19_35
|
||||
// CHECK:STDOUT: return %Get.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallGenericMethodWithNonDeducedParam(%c: %Class.3) -> %return: %.6 {
|
||||
// CHECK:STDOUT: fn @CallGenericMethodWithNonDeducedParam(%c: %Class.3) -> %return: %.9 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %c.ref: %Class.3 = name_ref c, %c
|
||||
// CHECK:STDOUT: %.loc24_11: %GetNoDeduce.type.2 = specific_constant @Class.%GetNoDeduce.decl, @Class(constants.%A) [template = constants.%GetNoDeduce.2]
|
||||
// CHECK:STDOUT: %GetNoDeduce.ref: %GetNoDeduce.type.2 = name_ref GetNoDeduce, %.loc24_11 [template = constants.%GetNoDeduce.2]
|
||||
// CHECK:STDOUT: %.loc24_11.1: %GetNoDeduce.type.2 = specific_constant @Class.%GetNoDeduce.decl, @Class(constants.%A) [template = constants.%GetNoDeduce.2]
|
||||
// CHECK:STDOUT: %GetNoDeduce.ref: %GetNoDeduce.type.2 = name_ref GetNoDeduce, %.loc24_11.1 [template = constants.%GetNoDeduce.2]
|
||||
// CHECK:STDOUT: %.loc24_25.1: %.1 = struct_literal ()
|
||||
// CHECK:STDOUT: %B.ref.loc24: type = name_ref B, file.%B.decl [template = constants.%B]
|
||||
// CHECK:STDOUT: %.loc23_54: ref %.6 = splice_block %return {}
|
||||
// CHECK:STDOUT: %.loc24_11.2: <specific function> = specific_function %GetNoDeduce.ref, @GetNoDeduce(constants.%A, constants.%B) [template = constants.%.14]
|
||||
// CHECK:STDOUT: %.loc23_54: ref %.9 = splice_block %return {}
|
||||
// CHECK:STDOUT: %.loc24_25.2: ref %A = temporary_storage
|
||||
// CHECK:STDOUT: %.loc24_25.3: init %A = class_init (), %.loc24_25.2 [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc24_25.4: ref %A = temporary %.loc24_25.2, %.loc24_25.3
|
||||
// CHECK:STDOUT: %.loc24_23.1: ref %A = converted %.loc24_25.1, %.loc24_25.4
|
||||
// CHECK:STDOUT: %.loc24_23.2: %A = bind_value %.loc24_23.1
|
||||
// CHECK:STDOUT: %GetNoDeduce.call: init %.6 = call %GetNoDeduce.ref(%.loc24_23.2) to %.loc23_54
|
||||
// CHECK:STDOUT: %GetNoDeduce.call: init %.9 = call %.loc24_11.2(%.loc24_23.2) to %.loc23_54
|
||||
// CHECK:STDOUT: return %GetNoDeduce.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc14_13.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Get.type => constants.%Get.type.1
|
||||
// CHECK:STDOUT: %Get => constants.%Get.1
|
||||
// CHECK:STDOUT: %GetNoDeduce.type => constants.%GetNoDeduce.type.1
|
||||
// CHECK:STDOUT: %GetNoDeduce => constants.%GetNoDeduce.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Get(constants.%T, constants.%U) {
|
||||
// CHECK:STDOUT: %U.loc15_10.2 => constants.%U
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %.loc15_28.1 => constants.%.5
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Get.type => constants.%Get.type.1
|
||||
// CHECK:STDOUT: %Get => constants.%Get.1
|
||||
// CHECK:STDOUT: %.loc15_39.3 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @GetNoDeduce(constants.%T, constants.%U) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %U.loc16_24.2 => constants.%U
|
||||
// CHECK:STDOUT: %.loc16_42.1 => constants.%.5
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %GetNoDeduce.type => constants.%GetNoDeduce.type.1
|
||||
// CHECK:STDOUT: %GetNoDeduce => constants.%GetNoDeduce.1
|
||||
// CHECK:STDOUT: %.loc16_53.3 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(@Class.%T.loc14_13.2) {
|
||||
// CHECK:STDOUT: %T.loc14_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(@Get.%T) {
|
||||
// CHECK:STDOUT: %T.loc14_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Get(@Get.%T, @Get.%U.loc15_10.2) {
|
||||
// CHECK:STDOUT: %U.loc15_10.2 => constants.%U
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %.loc15_28.1 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(@GetNoDeduce.%T) {
|
||||
// CHECK:STDOUT: %T.loc14_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @GetNoDeduce(@GetNoDeduce.%T, @GetNoDeduce.%U.loc16_24.2) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %U.loc16_24.2 => constants.%U
|
||||
// CHECK:STDOUT: %.loc16_42.1 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(constants.%A) {
|
||||
// CHECK:STDOUT: %T.loc14_13.2 => constants.%A
|
||||
// CHECK:STDOUT:
|
||||
@@ -256,12 +350,22 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
|
||||
// CHECK:STDOUT: specific @Get(constants.%A, constants.%B) {
|
||||
// CHECK:STDOUT: %U.loc15_10.2 => constants.%B
|
||||
// CHECK:STDOUT: %T => constants.%A
|
||||
// CHECK:STDOUT: %.loc15_28.1 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc15_28.1 => constants.%.9
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Get.type => constants.%Get.type.2
|
||||
// CHECK:STDOUT: %Get => constants.%Get.2
|
||||
// CHECK:STDOUT: %.loc15_39.3 => constants.%.13
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @GetNoDeduce(constants.%A, constants.%B) {
|
||||
// CHECK:STDOUT: %T => constants.%A
|
||||
// CHECK:STDOUT: %U.loc16_24.2 => constants.%B
|
||||
// CHECK:STDOUT: %.loc16_42.1 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc16_42.1 => constants.%.9
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %GetNoDeduce.type => constants.%GetNoDeduce.type.2
|
||||
// CHECK:STDOUT: %GetNoDeduce => constants.%GetNoDeduce.2
|
||||
// CHECK:STDOUT: %.loc16_53.3 => constants.%.14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+53
-12
@@ -11,8 +11,8 @@
|
||||
class Class(T:! type) {
|
||||
// `Self` is the same as `Class(T)` here.
|
||||
// TODO: Find a better way to test two types are the same.
|
||||
fn MakeSelf() -> Self;
|
||||
fn MakeClass() -> Class(T);
|
||||
fn MakeSelf() -> Self { return {}; }
|
||||
fn MakeClass() -> Class(T) { return {}; }
|
||||
fn F() {
|
||||
var c: Class(T) = MakeSelf();
|
||||
var s: Self = MakeClass();
|
||||
@@ -36,6 +36,9 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: %.2: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = complete_type_witness %.2 [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %struct: %Class.2 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %MakeSelf, @MakeSelf(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %MakeClass, @MakeClass(%T) [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -78,8 +81,8 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class {
|
||||
// CHECK:STDOUT: %MakeSelf.decl: @Class.%MakeSelf.type (%MakeSelf.type) = fn_decl @MakeSelf [symbolic = @Class.%MakeSelf (constants.%MakeSelf)] {} {
|
||||
// CHECK:STDOUT: %.loc14: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = %Class (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14 [symbolic = %Class (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %.loc14_20: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = %Class (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14_20 [symbolic = %Class (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %return: ref @MakeSelf.%Class (%Class.2) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %MakeClass.decl: @Class.%MakeClass.type (%MakeClass.type) = fn_decl @MakeClass [symbolic = @Class.%MakeClass (constants.%MakeClass)] {} {
|
||||
@@ -103,14 +106,32 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> @MakeSelf.%Class (%Class.2);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %struct: @MakeSelf.%Class (%Class.2) = struct_value () [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> %return: @MakeSelf.%Class (%Class.2) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc14_35.1: %.2 = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc14_35.2: init @MakeSelf.%Class (%Class.2) = class_init (), %return [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT: %.loc14_36: init @MakeSelf.%Class (%Class.2) = converted %.loc14_35.1, %.loc14_35.2 [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT: return %.loc14_36 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @MakeClass(@Class.%T.loc11_13.1: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %Class.loc15_26.1: type = class_type @Class, @Class(%T) [symbolic = %Class.loc15_26.1 (constants.%Class.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> @MakeClass.%Class.loc15_26.1 (%Class.2);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %struct: @MakeClass.%Class.loc15_26.1 (%Class.2) = struct_value () [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> %return: @MakeClass.%Class.loc15_26.1 (%Class.2) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc15_40.1: %.2 = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc15_40.2: init @MakeClass.%Class.loc15_26.1 (%Class.2) = class_init (), %return [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT: %.loc15_41: init @MakeClass.%Class.loc15_26.1 (%Class.2) = converted %.loc15_40.1, %.loc15_40.2 [symbolic = %struct (constants.%struct)]
|
||||
// CHECK:STDOUT: return %.loc15_41 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(@Class.%T.loc11_13.1: type) {
|
||||
@@ -119,8 +140,10 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: %Class.loc17_17.2: type = class_type @Class, @Class(%T) [symbolic = %Class.loc17_17.2 (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %MakeSelf.type: type = fn_type @MakeSelf, @Class(%T) [symbolic = %MakeSelf.type (constants.%MakeSelf.type)]
|
||||
// CHECK:STDOUT: %MakeSelf: @F.%MakeSelf.type (%MakeSelf.type) = struct_value () [symbolic = %MakeSelf (constants.%MakeSelf)]
|
||||
// CHECK:STDOUT: %.loc17_23.3: <specific function> = specific_function %MakeSelf, @MakeSelf(%T) [symbolic = %.loc17_23.3 (constants.%.5)]
|
||||
// CHECK:STDOUT: %MakeClass.type: type = fn_type @MakeClass, @Class(%T) [symbolic = %MakeClass.type (constants.%MakeClass.type)]
|
||||
// CHECK:STDOUT: %MakeClass: @F.%MakeClass.type (%MakeClass.type) = struct_value () [symbolic = %MakeClass (constants.%MakeClass)]
|
||||
// CHECK:STDOUT: %.loc18_19.3: <specific function> = specific_function %MakeClass, @MakeClass(%T) [symbolic = %.loc18_19.3 (constants.%.6)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
@@ -129,19 +152,21 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: %Class.loc17_17.1: type = class_type @Class, @Class(constants.%T) [symbolic = %Class.loc17_17.2 (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %c.var: ref @F.%Class.loc17_17.2 (%Class.2) = var c
|
||||
// CHECK:STDOUT: %c: ref @F.%Class.loc17_17.2 (%Class.2) = bind_name c, %c.var
|
||||
// CHECK:STDOUT: %.loc17_23: @F.%MakeSelf.type (%MakeSelf.type) = specific_constant @Class.%MakeSelf.decl, @Class(constants.%T) [symbolic = %MakeSelf (constants.%MakeSelf)]
|
||||
// CHECK:STDOUT: %MakeSelf.ref: @F.%MakeSelf.type (%MakeSelf.type) = name_ref MakeSelf, %.loc17_23 [symbolic = %MakeSelf (constants.%MakeSelf)]
|
||||
// CHECK:STDOUT: %.loc17_23.1: @F.%MakeSelf.type (%MakeSelf.type) = specific_constant @Class.%MakeSelf.decl, @Class(constants.%T) [symbolic = %MakeSelf (constants.%MakeSelf)]
|
||||
// CHECK:STDOUT: %MakeSelf.ref: @F.%MakeSelf.type (%MakeSelf.type) = name_ref MakeSelf, %.loc17_23.1 [symbolic = %MakeSelf (constants.%MakeSelf)]
|
||||
// CHECK:STDOUT: %.loc17_23.2: <specific function> = specific_function %MakeSelf.ref, @MakeSelf(constants.%T) [symbolic = %.loc17_23.3 (constants.%.5)]
|
||||
// CHECK:STDOUT: %.loc17_9: ref @F.%Class.loc17_17.2 (%Class.2) = splice_block %c.var {}
|
||||
// CHECK:STDOUT: %MakeSelf.call: init @F.%Class.loc17_17.2 (%Class.2) = call %MakeSelf.ref() to %.loc17_9
|
||||
// CHECK:STDOUT: %MakeSelf.call: init @F.%Class.loc17_17.2 (%Class.2) = call %.loc17_23.2() to %.loc17_9
|
||||
// CHECK:STDOUT: assign %c.var, %MakeSelf.call
|
||||
// CHECK:STDOUT: %.loc18_12: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = %Class.loc17_17.2 (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc18_12 [symbolic = %Class.loc17_17.2 (constants.%Class.2)]
|
||||
// CHECK:STDOUT: %s.var: ref @F.%Class.loc17_17.2 (%Class.2) = var s
|
||||
// CHECK:STDOUT: %s: ref @F.%Class.loc17_17.2 (%Class.2) = bind_name s, %s.var
|
||||
// CHECK:STDOUT: %.loc18_19: @F.%MakeClass.type (%MakeClass.type) = specific_constant @Class.%MakeClass.decl, @Class(constants.%T) [symbolic = %MakeClass (constants.%MakeClass)]
|
||||
// CHECK:STDOUT: %MakeClass.ref: @F.%MakeClass.type (%MakeClass.type) = name_ref MakeClass, %.loc18_19 [symbolic = %MakeClass (constants.%MakeClass)]
|
||||
// CHECK:STDOUT: %.loc18_19.1: @F.%MakeClass.type (%MakeClass.type) = specific_constant @Class.%MakeClass.decl, @Class(constants.%T) [symbolic = %MakeClass (constants.%MakeClass)]
|
||||
// CHECK:STDOUT: %MakeClass.ref: @F.%MakeClass.type (%MakeClass.type) = name_ref MakeClass, %.loc18_19.1 [symbolic = %MakeClass (constants.%MakeClass)]
|
||||
// CHECK:STDOUT: %.loc18_19.2: <specific function> = specific_function %MakeClass.ref, @MakeClass(constants.%T) [symbolic = %.loc18_19.3 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.loc18_9: ref @F.%Class.loc17_17.2 (%Class.2) = splice_block %s.var {}
|
||||
// CHECK:STDOUT: %MakeClass.call: init @F.%Class.loc17_17.2 (%Class.2) = call %MakeClass.ref() to %.loc18_9
|
||||
// CHECK:STDOUT: %MakeClass.call: init @F.%Class.loc17_17.2 (%Class.2) = call %.loc18_19.2() to %.loc18_9
|
||||
// CHECK:STDOUT: assign %s.var, %MakeClass.call
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -166,6 +191,9 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: specific @MakeSelf(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class => constants.%Class.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %struct => constants.%struct
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Class(@MakeClass.%T) {
|
||||
@@ -175,6 +203,9 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: specific @MakeClass(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class.loc15_26.1 => constants.%Class.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %struct => constants.%struct
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {}
|
||||
@@ -187,3 +218,13 @@ class Class(T:! type) {
|
||||
// CHECK:STDOUT: %T.loc11_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @MakeSelf(@F.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class => constants.%Class.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @MakeClass(@F.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Class.loc15_26.1 => constants.%Class.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+24
-16
@@ -121,6 +121,7 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: %.12: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %.13: i32 = int_literal 2 [template]
|
||||
// CHECK:STDOUT: %array: %.9 = tuple_value (%struct, %struct, %struct) [template]
|
||||
// CHECK:STDOUT: %.14: <specific function> = specific_function %F, @F(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -217,9 +218,10 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: assign %a.var, %.loc9_31
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %a.ref: ref %.9 = name_ref a, %a
|
||||
// CHECK:STDOUT: %.loc10_10: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.14]
|
||||
// CHECK:STDOUT: %.loc8: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %.loc10: %.9 = bind_value %a.ref
|
||||
// CHECK:STDOUT: %F.call: init %C = call %F.ref(%.loc10) to %.loc8
|
||||
// CHECK:STDOUT: %.loc10_12: %.9 = bind_value %a.ref
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc10_10(%.loc10_12) to %.loc8
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -231,6 +233,8 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %.loc6_24.2 => constants.%.9
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_bound_only.carbon
|
||||
@@ -518,7 +522,8 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: %.13: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %array: %.10 = tuple_value (%struct, %struct, %struct) [template]
|
||||
// CHECK:STDOUT: %.14: type = array_type %.3, %C [template]
|
||||
// CHECK:STDOUT: %.15: type = ptr_type %.14 [template]
|
||||
// CHECK:STDOUT: %.15: <specific function> = specific_function %F, @F(%C) [template]
|
||||
// CHECK:STDOUT: %.16: type = ptr_type %.14 [template]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.1: type = generic_interface_type @ImplicitAs [template]
|
||||
// CHECK:STDOUT: %ImplicitAs: %ImplicitAs.type.1 = struct_value () [template]
|
||||
// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic]
|
||||
@@ -527,14 +532,14 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: %Self.2: %ImplicitAs.type.2 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.1: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.1: %Convert.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.16: type = assoc_entity_type %ImplicitAs.type.2, %Convert.type.1 [symbolic]
|
||||
// CHECK:STDOUT: %.17: %.16 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %.17: type = assoc_entity_type %ImplicitAs.type.2, %Convert.type.1 [symbolic]
|
||||
// CHECK:STDOUT: %.18: %.17 = assoc_entity element0, imports.%import_ref.5 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.3: type = interface_type @ImplicitAs, @ImplicitAs(%.14) [template]
|
||||
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert, @ImplicitAs(%.14) [template]
|
||||
// CHECK:STDOUT: %Convert.2: %Convert.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.18: type = assoc_entity_type %ImplicitAs.type.3, %Convert.type.2 [template]
|
||||
// CHECK:STDOUT: %.19: %.18 = assoc_entity element0, imports.%import_ref.5 [template]
|
||||
// CHECK:STDOUT: %.20: %.16 = assoc_entity element0, imports.%import_ref.6 [symbolic]
|
||||
// CHECK:STDOUT: %.19: type = assoc_entity_type %ImplicitAs.type.3, %Convert.type.2 [template]
|
||||
// CHECK:STDOUT: %.20: %.19 = assoc_entity element0, imports.%import_ref.5 [template]
|
||||
// CHECK:STDOUT: %.21: %.17 = assoc_entity element0, imports.%import_ref.6 [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -551,7 +556,7 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref.1: %ImplicitAs.type.1 = import_ref Core//prelude/operators/as, inst+40, loaded [template = constants.%ImplicitAs]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref Core//prelude/operators/as, inst+45, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.1 (%.16) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.20)]
|
||||
// CHECK:STDOUT: %import_ref.3: @ImplicitAs.%.1 (%.17) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.21)]
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
@@ -594,8 +599,8 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: %Self: %ImplicitAs.type.2 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.2)]
|
||||
// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic = %Convert.type (constants.%Convert.type.1)]
|
||||
// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.1) = struct_value () [symbolic = %Convert (constants.%Convert.1)]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.2), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.1 (constants.%.16)]
|
||||
// CHECK:STDOUT: %.2: @ImplicitAs.%.1 (%.16) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.2 (constants.%.17)]
|
||||
// CHECK:STDOUT: %.1: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.2), @ImplicitAs.%Convert.type (%Convert.type.1) [symbolic = %.1 (constants.%.17)]
|
||||
// CHECK:STDOUT: %.2: @ImplicitAs.%.1 (%.17) = assoc_entity element0, imports.%import_ref.5 [symbolic = %.2 (constants.%.18)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: !members:
|
||||
@@ -657,12 +662,13 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: assign %a.var, %.loc10_31
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %a.ref: ref %.10 = name_ref a, %a
|
||||
// CHECK:STDOUT: %.loc21_10: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.15]
|
||||
// CHECK:STDOUT: %.loc21_11.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %ImplicitAs.type: type = interface_type @ImplicitAs, @ImplicitAs(constants.%.14) [template = constants.%ImplicitAs.type.3]
|
||||
// CHECK:STDOUT: %.loc21_11.2: %.18 = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%.14) [template = constants.%.19]
|
||||
// CHECK:STDOUT: %Convert.ref: %.18 = name_ref Convert, %.loc21_11.2 [template = constants.%.19]
|
||||
// CHECK:STDOUT: %.loc21_11.2: %.19 = specific_constant imports.%import_ref.3, @ImplicitAs(constants.%.14) [template = constants.%.20]
|
||||
// CHECK:STDOUT: %Convert.ref: %.19 = name_ref Convert, %.loc21_11.2 [template = constants.%.20]
|
||||
// CHECK:STDOUT: %.loc21_11.3: %.14 = converted %a.ref, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %F.call: init %C = call %F.ref(<invalid>) [template = <error>]
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc21_10(<invalid>) [template = <error>]
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -682,6 +688,8 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %.loc6_24.2 => constants.%.14
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ImplicitAs(constants.%Dest) {
|
||||
@@ -710,8 +718,8 @@ fn G() -> C {
|
||||
// CHECK:STDOUT: %Self => constants.%Self.2
|
||||
// CHECK:STDOUT: %Convert.type => constants.%Convert.type.2
|
||||
// CHECK:STDOUT: %Convert => constants.%Convert.2
|
||||
// CHECK:STDOUT: %.1 => constants.%.18
|
||||
// CHECK:STDOUT: %.2 => constants.%.19
|
||||
// CHECK:STDOUT: %.1 => constants.%.19
|
||||
// CHECK:STDOUT: %.2 => constants.%.20
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_type_mismatch.carbon
|
||||
|
||||
+123
-20
@@ -15,7 +15,7 @@ library "[[@TEST_NAME]]";
|
||||
class C(T:! type) {}
|
||||
class D {}
|
||||
|
||||
fn F[T:! type](p: C(T)) -> T;
|
||||
fn F[T:! type](p: C(T)) -> T { return F(p); }
|
||||
|
||||
fn G(p: C(D)) -> D {
|
||||
return F(p);
|
||||
@@ -28,7 +28,7 @@ library "[[@TEST_NAME]]";
|
||||
class I(T:! type) {}
|
||||
class C {}
|
||||
|
||||
fn F[T:! type](p: I(T)) -> C;
|
||||
fn F[T:! type](p: I(T)) -> C { return F(p); }
|
||||
|
||||
fn G(p: I(C)) -> C {
|
||||
return F(p);
|
||||
@@ -47,7 +47,7 @@ class D {}
|
||||
|
||||
// C++ doesn't permit deducing `T` here because `Outer` might be specialized.
|
||||
// But that's not possible in Carbon, so we can deduce `T`.
|
||||
fn F[T:! type, U:! type](p: Outer(T).Inner(U)) -> (T, U);
|
||||
fn F[T:! type, U:! type](p: Outer(T).Inner(U)) -> (T, U) { return F(p); }
|
||||
|
||||
fn G(p: Outer(C).Inner(D)) -> (C, D) {
|
||||
return F(p);
|
||||
@@ -78,10 +78,12 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %D: type = class_type @D [template]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %C.3: type = class_type @C, @C(%D) [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %F, @F(%D) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -164,20 +166,35 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %T.loc7_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %C.loc7_20.2: type = class_type @C, @C(%T.loc7_6.2) [symbolic = %C.loc7_20.2 (constants.%C.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type](%p: @F.%C.loc7_20.2 (%C.2)) -> @F.%T.loc7_6.2 (%T);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.2) [symbolic = %.loc7_39.2 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type](%p: @F.%C.loc7_20.2 (%C.2)) -> @F.%T.loc7_6.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%C.loc7_20.2 (%C.2) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc7_39.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc7_39.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%T.loc7_6.2 (%T) = call %.loc7_39.1(%p.ref)
|
||||
// CHECK:STDOUT: %.loc7_43.1: @F.%T.loc7_6.2 (%T) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc7_43.2: @F.%T.loc7_6.2 (%T) = converted %F.call, %.loc7_43.1
|
||||
// CHECK:STDOUT: return %.loc7_43.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %C.3) -> %return: %D {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %C.3 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc10: <specific function> = specific_function %F.ref, @F(constants.%D) [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc9: ref %D = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %D = call %F.ref(%p.ref) to %.loc9
|
||||
// CHECK:STDOUT: %F.call: init %D = call %.loc10(%p.ref) to %.loc9
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @C(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_9.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @C(@F.%T.loc7_6.2) {
|
||||
@@ -187,6 +204,14 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %C.loc7_20.2 => constants.%C.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc7_6.2) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %C.loc7_20.2 => constants.%C.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @C(constants.%D) {
|
||||
@@ -198,6 +223,9 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%D) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%D
|
||||
// CHECK:STDOUT: %C.loc7_20.2 => constants.%C.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- interface.carbon
|
||||
@@ -213,10 +241,12 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %I.3: type = class_type @I, @I(%C) [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %F, @F(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -299,20 +329,34 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %T.loc7_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %I.loc7_20.2: type = class_type @I, @I(%T.loc7_6.2) [symbolic = %I.loc7_20.2 (constants.%I.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type](%p: @F.%I.loc7_20.2 (%I.2)) -> %C;
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.2) [symbolic = %.loc7_39.2 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type](%p: @F.%I.loc7_20.2 (%I.2)) -> %return: %C {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%I.loc7_20.2 (%I.2) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc7_39.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc7_39.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %.loc7_25: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc7_39.1(%p.ref) to %.loc7_25
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %I.3) -> %return: %C {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %I.3 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc10: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc9: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %C = call %F.ref(%p.ref) to %.loc9
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc10(%p.ref) to %.loc9
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_9.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I(@F.%T.loc7_6.2) {
|
||||
@@ -322,6 +366,14 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %I.loc7_20.2 => constants.%I.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc7_6.2) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %I.loc7_20.2 => constants.%I.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I(constants.%C) {
|
||||
@@ -333,6 +385,9 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %I.loc7_20.2 => constants.%I.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_39.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- nested.carbon
|
||||
@@ -356,15 +411,18 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %.6: type = tuple_type (%T, %U) [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.6 [symbolic]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %F, @F(%T, %U) [symbolic]
|
||||
// CHECK:STDOUT: %Outer.3: type = class_type @Outer, @Outer(%C) [template]
|
||||
// CHECK:STDOUT: %Inner.type.2: type = generic_class_type @Inner, @Outer(%C) [template]
|
||||
// CHECK:STDOUT: %Inner.3: %Inner.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %Inner.4: type = class_type @Inner, @Inner(%C, %D) [template]
|
||||
// CHECK:STDOUT: %.7: type = tuple_type (%C, %D) [template]
|
||||
// CHECK:STDOUT: %.9: type = tuple_type (%C, %D) [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: type = tuple_type (%.4, %.4) [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
|
||||
// CHECK:STDOUT: %.10: type = tuple_type (%.4, %.4) [template]
|
||||
// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
|
||||
// CHECK:STDOUT: %.12: <specific function> = specific_function %F, @F(%C, %D) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -437,8 +495,8 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %C.ref.loc15_32: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %D.ref.loc15_35: type = name_ref D, file.%D.decl [template = constants.%D]
|
||||
// CHECK:STDOUT: %.loc15_36.1: %.5 = tuple_literal (%C.ref.loc15_32, %D.ref.loc15_35)
|
||||
// CHECK:STDOUT: %.loc15_36.2: type = converted %.loc15_36.1, constants.%.7 [template = constants.%.7]
|
||||
// CHECK:STDOUT: %return: ref %.7 = var <return slot>
|
||||
// CHECK:STDOUT: %.loc15_36.2: type = converted %.loc15_36.1, constants.%.9 [template = constants.%.9]
|
||||
// CHECK:STDOUT: %return: ref %.9 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -500,15 +558,38 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %Inner.loc13_43.2: type = class_type @Inner, @Inner(%T.loc13_6.2, %U.loc13_16.2) [symbolic = %Inner.loc13_43.2 (constants.%Inner.2)]
|
||||
// CHECK:STDOUT: %.loc13_56.3: type = tuple_type (@F.%T.loc13_6.2 (%T), @F.%U.loc13_16.2 (%U)) [symbolic = %.loc13_56.3 (constants.%.6)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc13_6.1: type, %U.loc13_16.1: type](%p: @F.%Inner.loc13_43.2 (%Inner.2)) -> @F.%.loc13_56.3 (%.6);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc13_67.2: <specific function> = specific_function constants.%F, @F(%T.loc13_6.2, %U.loc13_16.2) [symbolic = %.loc13_67.2 (constants.%.8)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc13_6.1: type, %U.loc13_16.1: type](%p: @F.%Inner.loc13_43.2 (%Inner.2)) -> %return: @F.%.loc13_56.3 (%.6) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%Inner.loc13_43.2 (%Inner.2) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc13_67.1: <specific function> = specific_function %F.ref, @F(constants.%T, constants.%U) [symbolic = %.loc13_67.2 (constants.%.8)]
|
||||
// CHECK:STDOUT: %.loc13_68.1: ref @F.%.loc13_56.3 (%.6) = temporary_storage
|
||||
// CHECK:STDOUT: %F.call: init @F.%.loc13_56.3 (%.6) = call %.loc13_67.1(%p.ref) to %.loc13_68.1
|
||||
// CHECK:STDOUT: %.loc13_68.2: ref @F.%.loc13_56.3 (%.6) = temporary %.loc13_68.1, %F.call
|
||||
// CHECK:STDOUT: %.loc13_68.3: ref @F.%T.loc13_6.2 (%T) = tuple_access %.loc13_68.2, element0
|
||||
// CHECK:STDOUT: %.loc13_68.4: @F.%T.loc13_6.2 (%T) = bind_value %.loc13_68.3
|
||||
// CHECK:STDOUT: %.loc13_68.5: ref @F.%T.loc13_6.2 (%T) = tuple_access %return, element0
|
||||
// CHECK:STDOUT: %.loc13_68.6: init @F.%T.loc13_6.2 (%T) = initialize_from %.loc13_68.4 to %.loc13_68.5
|
||||
// CHECK:STDOUT: %.loc13_68.7: ref @F.%U.loc13_16.2 (%U) = tuple_access %.loc13_68.2, element1
|
||||
// CHECK:STDOUT: %.loc13_68.8: @F.%U.loc13_16.2 (%U) = bind_value %.loc13_68.7
|
||||
// CHECK:STDOUT: %.loc13_68.9: ref @F.%U.loc13_16.2 (%U) = tuple_access %return, element1
|
||||
// CHECK:STDOUT: %.loc13_68.10: init @F.%U.loc13_16.2 (%U) = initialize_from %.loc13_68.8 to %.loc13_68.9
|
||||
// CHECK:STDOUT: %.loc13_68.11: init @F.%.loc13_56.3 (%.6) = tuple_init (%.loc13_68.6, %.loc13_68.10) to %return
|
||||
// CHECK:STDOUT: %.loc13_71: init @F.%.loc13_56.3 (%.6) = converted %F.call, %.loc13_68.11
|
||||
// CHECK:STDOUT: return %.loc13_71 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %Inner.4) -> %return: %.7 {
|
||||
// CHECK:STDOUT: fn @G(%p: %Inner.4) -> %return: %.9 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %Inner.4 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc15_28: ref %.7 = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %.7 = call %F.ref(%p.ref) to %.loc15_28
|
||||
// CHECK:STDOUT: %.loc16: <specific function> = specific_function %F.ref, @F(constants.%C, constants.%D) [template = constants.%.12]
|
||||
// CHECK:STDOUT: %.loc15_28: ref %.9 = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %.9 = call %.loc16(%p.ref) to %.loc15_28
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -522,6 +603,8 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Inner(constants.%T, constants.%U) {
|
||||
// CHECK:STDOUT: %U.loc5_15.2 => constants.%U
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Outer(@Outer.%T.loc4_13.2) {
|
||||
@@ -544,6 +627,19 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %Inner.loc13_37 => constants.%Inner.1
|
||||
// CHECK:STDOUT: %Inner.loc13_43.2 => constants.%Inner.2
|
||||
// CHECK:STDOUT: %.loc13_56.3 => constants.%.6
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc13_67.2 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc13_6.2, @F.%U.loc13_16.2) {
|
||||
// CHECK:STDOUT: %T.loc13_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %U.loc13_16.2 => constants.%U
|
||||
// CHECK:STDOUT: %Outer.loc13_34.2 => constants.%Outer.2
|
||||
// CHECK:STDOUT: %Inner.type => constants.%Inner.type.1
|
||||
// CHECK:STDOUT: %Inner.loc13_37 => constants.%Inner.1
|
||||
// CHECK:STDOUT: %Inner.loc13_43.2 => constants.%Inner.2
|
||||
// CHECK:STDOUT: %.loc13_56.3 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Outer(constants.%C) {
|
||||
@@ -567,7 +663,10 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %Inner.type => constants.%Inner.type.2
|
||||
// CHECK:STDOUT: %Inner.loc13_37 => constants.%Inner.3
|
||||
// CHECK:STDOUT: %Inner.loc13_43.2 => constants.%Inner.4
|
||||
// CHECK:STDOUT: %.loc13_56.3 => constants.%.7
|
||||
// CHECK:STDOUT: %.loc13_56.3 => constants.%.9
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc13_67.2 => constants.%.12
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- nontype.carbon
|
||||
@@ -590,6 +689,7 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %.5: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: %WithNontype.3: type = class_type @WithNontype, @WithNontype(%.5) [template]
|
||||
// CHECK:STDOUT: %struct: %WithNontype.3 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %F, @F(%.5) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -690,8 +790,9 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: %.loc9_13.3: init %WithNontype.3 = class_init (), %.loc9_13.2 [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc9_13.4: ref %WithNontype.3 = temporary %.loc9_13.2, %.loc9_13.3
|
||||
// CHECK:STDOUT: %.loc9_15.1: ref %WithNontype.3 = converted %.loc9_13.1, %.loc9_13.4
|
||||
// CHECK:STDOUT: %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.5) [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc9_15.2: %WithNontype.3 = bind_value %.loc9_15.1
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %F.ref(%.loc9_15.2)
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %.loc9_10(%.loc9_15.2)
|
||||
// CHECK:STDOUT: %.loc9_33.1: i32 = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc9_33.2: i32 = converted %F.call, %.loc9_33.1
|
||||
// CHECK:STDOUT: return %.loc9_33.2
|
||||
@@ -721,5 +822,7 @@ fn G() -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%.5) {
|
||||
// CHECK:STDOUT: %N.loc6_6.2 => constants.%.5
|
||||
// CHECK:STDOUT: %WithNontype.loc6_29.2 => constants.%WithNontype.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+5
-1
@@ -52,6 +52,7 @@ fn G(a: f64) -> i32 {
|
||||
// CHECK:STDOUT: %.4: type = int_type signed, %.3 [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %F, @F(%.3) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -137,7 +138,8 @@ fn G(a: f64) -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %a.ref: %.4 = name_ref a, %a
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %F.ref(%a.ref)
|
||||
// CHECK:STDOUT: %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.3) [template = constants.%.5]
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %.loc9_10(%a.ref)
|
||||
// CHECK:STDOUT: %.loc9_14.1: i32 = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc9_14.2: i32 = converted %F.call, %.loc9_14.1
|
||||
// CHECK:STDOUT: return %.loc9_14.2
|
||||
@@ -151,6 +153,8 @@ fn G(a: f64) -> i32 {
|
||||
// CHECK:STDOUT: specific @F(constants.%.3) {
|
||||
// CHECK:STDOUT: %N.loc4_6.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc4_26 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_float.carbon
|
||||
|
||||
+47
-15
@@ -15,7 +15,7 @@ library "[[@TEST_NAME]]";
|
||||
class C {}
|
||||
class D {}
|
||||
|
||||
fn F[T:! type, U:! type](pair: (T, U)) -> U;
|
||||
fn F[T:! type, U:! type](pair: (T, U)) -> U { return F(pair); }
|
||||
|
||||
fn G(pair: (C, D)) -> D {
|
||||
return F(pair);
|
||||
@@ -66,12 +66,15 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.5: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: type = tuple_type (%C, %D) [template]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.4 [symbolic]
|
||||
// CHECK:STDOUT: %.7: <specific function> = specific_function %F, @F(%T, %U) [symbolic]
|
||||
// CHECK:STDOUT: %.8: type = tuple_type (%C, %D) [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.8: type = tuple_type (%.7, %.7) [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.8 [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.10: type = tuple_type (%.9, %.9) [template]
|
||||
// CHECK:STDOUT: %.11: type = ptr_type %.10 [template]
|
||||
// CHECK:STDOUT: %.12: <specific function> = specific_function %F, @F(%C, %D) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -117,14 +120,14 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %return: ref @F.%U.loc7_16.2 (%U) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %pair.patt: %.6 = binding_pattern pair
|
||||
// CHECK:STDOUT: %pair.patt: %.8 = binding_pattern pair
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %D.ref.loc9_16: type = name_ref D, file.%D.decl [template = constants.%D]
|
||||
// CHECK:STDOUT: %.loc9_17.1: %.3 = tuple_literal (%C.ref, %D.ref.loc9_16)
|
||||
// CHECK:STDOUT: %.loc9_17.2: type = converted %.loc9_17.1, constants.%.6 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %pair.param: %.6 = param pair, runtime_param0
|
||||
// CHECK:STDOUT: %pair: %.6 = bind_name pair, %pair.param
|
||||
// CHECK:STDOUT: %.loc9_17.2: type = converted %.loc9_17.1, constants.%.8 [template = constants.%.8]
|
||||
// CHECK:STDOUT: %pair.param: %.8 = param pair, runtime_param0
|
||||
// CHECK:STDOUT: %pair: %.8 = bind_name pair, %pair.param
|
||||
// CHECK:STDOUT: %D.ref.loc9_23: type = name_ref D, file.%D.decl [template = constants.%D]
|
||||
// CHECK:STDOUT: %return: ref %D = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -149,15 +152,28 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %U.loc7_16.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc7_16.2 (constants.%U)]
|
||||
// CHECK:STDOUT: %.loc7_37.3: type = tuple_type (@F.%T.loc7_6.2 (%T), @F.%U.loc7_16.2 (%U)) [symbolic = %.loc7_37.3 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type, %U.loc7_16.1: type](%pair: @F.%.loc7_37.3 (%.4)) -> @F.%U.loc7_16.2 (%U);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_54.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.2, %U.loc7_16.2) [symbolic = %.loc7_54.2 (constants.%.7)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc7_6.1: type, %U.loc7_16.1: type](%pair: @F.%.loc7_37.3 (%.4)) -> @F.%U.loc7_16.2 (%U) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %pair.ref: @F.%.loc7_37.3 (%.4) = name_ref pair, %pair
|
||||
// CHECK:STDOUT: %.loc7_54.1: <specific function> = specific_function %F.ref, @F(constants.%T, constants.%U) [symbolic = %.loc7_54.2 (constants.%.7)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%U.loc7_16.2 (%U) = call %.loc7_54.1(%pair.ref)
|
||||
// CHECK:STDOUT: %.loc7_61.1: @F.%U.loc7_16.2 (%U) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc7_61.2: @F.%U.loc7_16.2 (%U) = converted %F.call, %.loc7_61.1
|
||||
// CHECK:STDOUT: return %.loc7_61.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%pair: %.6) -> %return: %D {
|
||||
// CHECK:STDOUT: fn @G(%pair: %.8) -> %return: %D {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %pair.ref: %.6 = name_ref pair, %pair
|
||||
// CHECK:STDOUT: %pair.ref: %.8 = name_ref pair, %pair
|
||||
// CHECK:STDOUT: %.loc10: <specific function> = specific_function %F.ref, @F(constants.%C, constants.%D) [template = constants.%.12]
|
||||
// CHECK:STDOUT: %.loc9_20: ref %D = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %D = call %F.ref(%pair.ref) to %.loc9_20
|
||||
// CHECK:STDOUT: %F.call: init %D = call %.loc10(%pair.ref) to %.loc9_20
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -165,12 +181,24 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %U.loc7_16.2 => constants.%U
|
||||
// CHECK:STDOUT: %.loc7_37.3 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_54.2 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc7_6.2, @F.%U.loc7_16.2) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %U.loc7_16.2 => constants.%U
|
||||
// CHECK:STDOUT: %.loc7_37.3 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%C, constants.%D) {
|
||||
// CHECK:STDOUT: %T.loc7_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %U.loc7_16.2 => constants.%D
|
||||
// CHECK:STDOUT: %.loc7_37.3 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc7_37.3 => constants.%.8
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_54.2 => constants.%.12
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- tuple_value.carbon
|
||||
@@ -201,6 +229,7 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %HasPair.4: type = class_type @HasPair, @HasPair(%tuple.2) [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.10: <specific function> = specific_function %F, @F(%.8, %.9) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -322,7 +351,8 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %h.ref: %HasPair.4 = name_ref h, %h
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %F.ref(%h.ref)
|
||||
// CHECK:STDOUT: %.loc9_10: <specific function> = specific_function %F.ref, @F(constants.%.8, constants.%.9) [template = constants.%.10]
|
||||
// CHECK:STDOUT: %F.call: init i32 = call %.loc9_10(%h.ref)
|
||||
// CHECK:STDOUT: %.loc9_14.1: i32 = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc9_14.2: i32 = converted %F.call, %.loc9_14.1
|
||||
// CHECK:STDOUT: return %.loc9_14.2
|
||||
@@ -360,6 +390,8 @@ fn G(pair: (C, D)) -> D {
|
||||
// CHECK:STDOUT: %B.loc6_15.2 => constants.%.9
|
||||
// CHECK:STDOUT: %tuple.loc6_40.2 => constants.%tuple.2
|
||||
// CHECK:STDOUT: %HasPair.loc6_34.2 => constants.%HasPair.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_inconsistent.carbon
|
||||
|
||||
+328
-227
@@ -14,7 +14,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C {}
|
||||
|
||||
fn F[T:! type](p: T*) -> T;
|
||||
fn F[T:! type](p: T*) -> T { return F(p); }
|
||||
|
||||
fn G(p: C*) -> C {
|
||||
return F(p);
|
||||
@@ -26,7 +26,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C {}
|
||||
|
||||
fn F[T:! type](p: const T*) -> T;
|
||||
fn F[T:! type](p: const T*) -> T { return F(p); }
|
||||
|
||||
fn G(p: const C*) -> C {
|
||||
return F(p);
|
||||
@@ -38,7 +38,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C {}
|
||||
|
||||
fn F[T:! type](p: T*) -> T;
|
||||
fn F[T:! type](p: T*) -> T { return F(p); }
|
||||
|
||||
fn G(p: const C*) -> const C {
|
||||
return F(p);
|
||||
@@ -50,15 +50,15 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C {}
|
||||
|
||||
fn F[T:! type](p: const T*) -> T;
|
||||
fn F[T:! type](p: const T*) -> T { return F(p); }
|
||||
|
||||
fn G(p: C*) -> const C {
|
||||
// CHECK:STDERR: fail_const_from_nonconst.carbon:[[@LINE+6]]:10: error: cannot deduce value for generic parameter `T`
|
||||
// CHECK:STDERR: return F(p);
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_const_from_nonconst.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here
|
||||
// CHECK:STDERR: fn F[T:! type](p: const T*) -> T;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fn F[T:! type](p: const T*) -> T { return F(p); }
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
return F(p);
|
||||
}
|
||||
|
||||
@@ -73,10 +73,12 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.4: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: type = ptr_type %C [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %C [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %F, @F(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -115,12 +117,12 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.5 = binding_pattern p
|
||||
// CHECK:STDOUT: %p.patt: %.6 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_9: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_10: type = ptr_type %C [template = constants.%.5]
|
||||
// CHECK:STDOUT: %p.param: %.5 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.5 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %.loc8_10: type = ptr_type %C [template = constants.%.6]
|
||||
// CHECK:STDOUT: %p.param: %.6 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.6 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_16: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %return: ref %C = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -137,26 +139,50 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_20.2: type = ptr_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_20.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_20.2 (%.3)) -> @F.%T.loc6_6.2 (%T);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.2) [symbolic = %.loc6_37.2 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_20.2 (%.3)) -> @F.%T.loc6_6.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%.loc6_20.2 (%.3) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc6_37.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc6_37.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.2 (%T) = call %.loc6_37.1(%p.ref)
|
||||
// CHECK:STDOUT: %.loc6_41.1: @F.%T.loc6_6.2 (%T) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc6_41.2: @F.%T.loc6_6.2 (%T) = converted %F.call, %.loc6_41.1
|
||||
// CHECK:STDOUT: return %.loc6_41.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.5) -> %return: %C {
|
||||
// CHECK:STDOUT: fn @G(%p: %.6) -> %return: %C {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.5 = name_ref p, %p
|
||||
// CHECK:STDOUT: %p.ref: %.6 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc9: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.8]
|
||||
// CHECK:STDOUT: %.loc8_13: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %C = call %F.ref(%p.ref) to %.loc8_13
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc9(%p.ref) to %.loc8_13
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc6_6.2) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.5
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.6
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- const.carbon
|
||||
@@ -171,11 +197,269 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.5: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.7: type = const_type %C [template]
|
||||
// CHECK:STDOUT: %.8: type = ptr_type %.7 [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.10: <specific function> = specific_function %F, @F(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %p.patt: @F.%.loc6_26.2 (%.4) = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_19.1: type = const_type %T [symbolic = %.loc6_19.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc6_26.1: type = ptr_type %.3 [symbolic = %.loc6_26.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %p.param: @F.%.loc6_26.2 (%.4) = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: @F.%.loc6_26.2 (%.4) = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %T.ref.loc6_32: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.8 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_15: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_9: type = const_type %C [template = constants.%.7]
|
||||
// CHECK:STDOUT: %.loc8_16: type = ptr_type %.7 [template = constants.%.8]
|
||||
// CHECK:STDOUT: %p.param: %.8 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.8 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %return: ref %C = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc4: <witness> = complete_type_witness %.1 [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_19.2: type = const_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_19.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc6_26.2: type = ptr_type @F.%.loc6_19.2 (%.3) [symbolic = %.loc6_26.2 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.2) [symbolic = %.loc6_43.2 (constants.%.6)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_26.2 (%.4)) -> @F.%T.loc6_6.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%.loc6_26.2 (%.4) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc6_43.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc6_43.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.2 (%T) = call %.loc6_43.1(%p.ref)
|
||||
// CHECK:STDOUT: %.loc6_47.1: @F.%T.loc6_6.2 (%T) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc6_47.2: @F.%T.loc6_6.2 (%T) = converted %F.call, %.loc6_47.1
|
||||
// CHECK:STDOUT: return %.loc6_47.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.8) -> %return: %C {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.8 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc9: <specific function> = specific_function %F.ref, @F(constants.%C) [template = constants.%.10]
|
||||
// CHECK:STDOUT: %.loc8_19: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %C = call %.loc9(%p.ref) to %.loc8_19
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_43.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc6_6.2) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.7
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.8
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_43.2 => constants.%.10
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- nonconst_from_const.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.2: <witness> = complete_type_witness %.1 [template]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.4: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.6: type = const_type %C [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.6 [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: %.9: <specific function> = specific_function %F, @F(%.6) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %p.patt: @F.%.loc6_20.2 (%.3) = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc6_19: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_20.1: type = ptr_type %T [symbolic = %.loc6_20.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %p.param: @F.%.loc6_20.2 (%.3) = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: @F.%.loc6_20.2 (%.3) = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %T.ref.loc6_26: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.7 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_15: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_9: type = const_type %C [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc8_16: type = ptr_type %.6 [template = constants.%.7]
|
||||
// CHECK:STDOUT: %p.param: %.7 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.7 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_28: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_22: type = const_type %C [template = constants.%.6]
|
||||
// CHECK:STDOUT: %return: ref %.6 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc4: <witness> = complete_type_witness %.1 [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_20.2: type = ptr_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_20.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.2) [symbolic = %.loc6_37.2 (constants.%.5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_20.2 (%.3)) -> @F.%T.loc6_6.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%.loc6_20.2 (%.3) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc6_37.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc6_37.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.2 (%T) = call %.loc6_37.1(%p.ref)
|
||||
// CHECK:STDOUT: %.loc6_41.1: @F.%T.loc6_6.2 (%T) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc6_41.2: @F.%T.loc6_6.2 (%T) = converted %F.call, %.loc6_41.1
|
||||
// CHECK:STDOUT: return %.loc6_41.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.7) -> %return: %.6 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.7 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc9: <specific function> = specific_function %F.ref, @F(constants.%.6) [template = constants.%.9]
|
||||
// CHECK:STDOUT: %.loc8_19: ref %.6 = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %.6 = call %.loc9(%p.ref) to %.loc8_19
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc6_6.2) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%.6) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.7
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_37.2 => constants.%.9
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_const_from_nonconst.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.2: <witness> = complete_type_witness %.1 [template]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = const_type %T [symbolic]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.3 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.5: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %C [template]
|
||||
// CHECK:STDOUT: %.8: type = const_type %C [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -217,13 +501,13 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.7 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_15: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_9: type = const_type %C [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc8_16: type = ptr_type %.6 [template = constants.%.7]
|
||||
// CHECK:STDOUT: %C.ref.loc8_9: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_10: type = ptr_type %C [template = constants.%.7]
|
||||
// CHECK:STDOUT: %p.param: %.7 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.7 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %return: ref %C = var <return slot>
|
||||
// CHECK:STDOUT: %.loc8_16: type = const_type %C [template = constants.%.8]
|
||||
// CHECK:STDOUT: %return: ref %.8 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -239,217 +523,25 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %.loc6_19.2: type = const_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_19.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc6_26.2: type = ptr_type @F.%.loc6_19.2 (%.3) [symbolic = %.loc6_26.2 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_26.2 (%.4)) -> @F.%T.loc6_6.2 (%T);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.2) [symbolic = %.loc6_43.2 (constants.%.6)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_26.2 (%.4)) -> @F.%T.loc6_6.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: @F.%.loc6_26.2 (%.4) = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc6_43.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc6_43.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.2 (%T) = call %.loc6_43.1(%p.ref)
|
||||
// CHECK:STDOUT: %.loc6_47.1: @F.%T.loc6_6.2 (%T) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc6_47.2: @F.%T.loc6_6.2 (%T) = converted %F.call, %.loc6_47.1
|
||||
// CHECK:STDOUT: return %.loc6_47.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.7) -> %return: %C {
|
||||
// CHECK:STDOUT: fn @G(%p: %.7) -> %return: %.8 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.7 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc8_19: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %C = call %F.ref(%p.ref) to %.loc8_19
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%C
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- nonconst_from_const.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.2: <witness> = complete_type_witness %.1 [template]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.4: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: type = const_type %C [template]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.5 [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %p.patt: @F.%.loc6_20.2 (%.3) = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc6_19: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_20.1: type = ptr_type %T [symbolic = %.loc6_20.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %p.param: @F.%.loc6_20.2 (%.3) = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: @F.%.loc6_20.2 (%.3) = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %T.ref.loc6_26: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.6 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_15: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_9: type = const_type %C [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc8_16: type = ptr_type %.5 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %p.param: %.6 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.6 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_28: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_22: type = const_type %C [template = constants.%.5]
|
||||
// CHECK:STDOUT: %return: ref %.5 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc4: <witness> = complete_type_witness %.1 [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_20.2: type = ptr_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_20.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_20.2 (%.3)) -> @F.%T.loc6_6.2 (%T);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.6) -> %return: %.5 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.6 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc8_19: ref %.5 = splice_block %return {}
|
||||
// CHECK:STDOUT: %F.call: init %.5 = call %F.ref(%p.ref) to %.loc8_19
|
||||
// CHECK:STDOUT: return %F.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%.5) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%.5
|
||||
// CHECK:STDOUT: %.loc6_20.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_const_from_nonconst.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.2: <witness> = complete_type_witness %.1 [template]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = const_type %T [symbolic]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.3 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.5: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %C [template]
|
||||
// CHECK:STDOUT: %.7: type = const_type %C [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: type = ptr_type %.1 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %p.patt: @F.%.loc6_26.2 (%.4) = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_19.1: type = const_type %T [symbolic = %.loc6_19.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc6_26.1: type = ptr_type %.3 [symbolic = %.loc6_26.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %p.param: @F.%.loc6_26.2 (%.4) = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: @F.%.loc6_26.2 (%.4) = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %T.ref.loc6_32: type = name_ref T, %T.loc6_6.1 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @F.%T.loc6_6.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
|
||||
// CHECK:STDOUT: %p.patt: %.6 = binding_pattern p
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %C.ref.loc8_9: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_10: type = ptr_type %C [template = constants.%.6]
|
||||
// CHECK:STDOUT: %p.param: %.6 = param p, runtime_param0
|
||||
// CHECK:STDOUT: %p: %.6 = bind_name p, %p.param
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_16: type = const_type %C [template = constants.%.7]
|
||||
// CHECK:STDOUT: %return: ref %.7 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc4: <witness> = complete_type_witness %.1 [template = constants.%.2]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%T.loc6_6.1: type) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc6_19.2: type = const_type @F.%T.loc6_6.2 (%T) [symbolic = %.loc6_19.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.loc6_26.2: type = ptr_type @F.%.loc6_19.2 (%.3) [symbolic = %.loc6_26.2 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc6_6.1: type](%p: @F.%.loc6_26.2 (%.4)) -> @F.%T.loc6_6.2 (%T);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%p: %.6) -> %return: %.7 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [template = constants.%F]
|
||||
// CHECK:STDOUT: %p.ref: %.6 = name_ref p, %p
|
||||
// CHECK:STDOUT: return <error> to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -457,5 +549,14 @@ fn G(p: C*) -> const C {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc6_43.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc6_6.2) {
|
||||
// CHECK:STDOUT: %T.loc6_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc6_19.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc6_26.2 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+141
-62
@@ -12,7 +12,7 @@
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn ExplicitGenericParam(T:! type) -> T*;
|
||||
fn ExplicitGenericParam(T:! type) -> T* { return ExplicitGenericParam(T); }
|
||||
|
||||
fn CallExplicitGenericParam() -> i32* {
|
||||
return ExplicitGenericParam(i32);
|
||||
@@ -46,7 +46,7 @@ fn CallExplicitAndAlsoDeduced(n: i32) -> i32* {
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn ImplicitGenericParam[T:! type](x: T) -> T*;
|
||||
fn ImplicitGenericParam[T:! type](x: T) -> T* { return ImplicitGenericParam(x); }
|
||||
|
||||
fn CallImplicitGenericParam(n: i32) -> i32* {
|
||||
return ImplicitGenericParam(n);
|
||||
@@ -56,7 +56,7 @@ fn CallImplicitGenericParam(n: i32) -> i32* {
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn TupleParam[T:! type](x: (T, i32));
|
||||
fn TupleParam[T:! type](x: (T, i32)) {}
|
||||
|
||||
fn CallTupleParam() {
|
||||
TupleParam((1, 2));
|
||||
@@ -66,15 +66,15 @@ fn CallTupleParam() {
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn StructParam[T:! type](x: {.a: T, .b: i32});
|
||||
fn StructParam[T:! type](x: {.a: T, .b: i32}) {}
|
||||
|
||||
fn CallStructParam() {
|
||||
// CHECK:STDERR: fail_todo_deduce_nested_struct.carbon:[[@LINE+7]]:3: error: cannot deduce value for generic parameter `T`
|
||||
// CHECK:STDERR: StructParam({.a = 1, .b = 2});
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_deduce_nested_struct.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here
|
||||
// CHECK:STDERR: fn StructParam[T:! type](x: {.a: T, .b: i32});
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fn StructParam[T:! type](x: {.a: T, .b: i32}) {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
StructParam({.a = 1, .b = 2});
|
||||
}
|
||||
@@ -122,15 +122,18 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.type: type = fn_type @ExplicitGenericParam [template]
|
||||
// CHECK:STDOUT: %.2: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam: %ExplicitGenericParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %ExplicitGenericParam, @ExplicitGenericParam(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type i32 [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type i32 [template]
|
||||
// CHECK:STDOUT: %CallExplicitGenericParam.type: type = fn_type @CallExplicitGenericParam [template]
|
||||
// CHECK:STDOUT: %CallExplicitGenericParam: %CallExplicitGenericParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = struct_type {.a: %T} [symbolic]
|
||||
// CHECK:STDOUT: %.5: type = ptr_type %.4 [symbolic]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %ExplicitGenericParam, @ExplicitGenericParam(i32) [template]
|
||||
// CHECK:STDOUT: %.6: type = struct_type {.a: %T} [symbolic]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.6 [symbolic]
|
||||
// CHECK:STDOUT: %CallExplicitGenericParamWithGenericArg.type: type = fn_type @CallExplicitGenericParamWithGenericArg [template]
|
||||
// CHECK:STDOUT: %CallExplicitGenericParamWithGenericArg: %CallExplicitGenericParamWithGenericArg.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %ExplicitGenericParam, @ExplicitGenericParam(%.6) [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -161,7 +164,7 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc4_25.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_25.1 [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc4_38: type = name_ref T, %T.loc4_25.1 [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_39.1: type = ptr_type %T [symbolic = %.loc4_39.2 (constants.%.1)]
|
||||
// CHECK:STDOUT: %return: ref @ExplicitGenericParam.%.loc4_39.2 (%.1) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -169,8 +172,8 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %int.make_type_32.loc6: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_37.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_37.2: type = converted %int.make_type_32.loc6, %.loc6_37.1 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_37.3: type = ptr_type i32 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %return: ref %.3 = var <return slot>
|
||||
// CHECK:STDOUT: %.loc6_37.3: type = ptr_type i32 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %return: ref %.4 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallExplicitGenericParamWithGenericArg.decl: %CallExplicitGenericParamWithGenericArg.type = fn_decl @CallExplicitGenericParamWithGenericArg [template = constants.%CallExplicitGenericParamWithGenericArg] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
@@ -178,9 +181,9 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc10_43.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc10_43.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc10: type = name_ref T, %T.loc10_43.1 [symbolic = %T.loc10_43.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc10_62.1: type = struct_type {.a: %T} [symbolic = %.loc10_62.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %.loc10_63.1: type = ptr_type %.4 [symbolic = %.loc10_63.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %return: ref @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.5) = var <return slot>
|
||||
// CHECK:STDOUT: %.loc10_62.1: type = struct_type {.a: %T} [symbolic = %.loc10_62.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.loc10_63.1: type = ptr_type %.6 [symbolic = %.loc10_63.2 (constants.%.7)]
|
||||
// CHECK:STDOUT: %return: ref @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.7) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -188,38 +191,53 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %T.loc4_25.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_39.2: type = ptr_type @ExplicitGenericParam.%T.loc4_25.2 (%T) [symbolic = %.loc4_39.2 (constants.%.1)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc4_25.1: type) -> @ExplicitGenericParam.%.loc4_39.2 (%.1);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_50.2: <specific function> = specific_function constants.%ExplicitGenericParam, @ExplicitGenericParam(%T.loc4_25.2) [symbolic = %.loc4_50.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc4_25.1: type) -> @ExplicitGenericParam.%.loc4_39.2 (%.1) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.ref: %ExplicitGenericParam.type = name_ref ExplicitGenericParam, file.%ExplicitGenericParam.decl [template = constants.%ExplicitGenericParam]
|
||||
// CHECK:STDOUT: %T.ref.loc4_71: type = name_ref T, %T.loc4_25.1 [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_50.1: <specific function> = specific_function %ExplicitGenericParam.ref, @ExplicitGenericParam(constants.%T) [symbolic = %.loc4_50.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.call: init @ExplicitGenericParam.%.loc4_39.2 (%.1) = call %.loc4_50.1()
|
||||
// CHECK:STDOUT: %.loc4_73.1: @ExplicitGenericParam.%.loc4_39.2 (%.1) = value_of_initializer %ExplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc4_73.2: @ExplicitGenericParam.%.loc4_39.2 (%.1) = converted %ExplicitGenericParam.call, %.loc4_73.1
|
||||
// CHECK:STDOUT: return %.loc4_73.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallExplicitGenericParam() -> %.3 {
|
||||
// CHECK:STDOUT: fn @CallExplicitGenericParam() -> %.4 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.ref: %ExplicitGenericParam.type = name_ref ExplicitGenericParam, file.%ExplicitGenericParam.decl [template = constants.%ExplicitGenericParam]
|
||||
// CHECK:STDOUT: %int.make_type_32.loc7: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc7_30.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
|
||||
// CHECK:STDOUT: %.loc7_30.2: type = converted %int.make_type_32.loc7, %.loc7_30.1 [template = i32]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.call: init %.3 = call %ExplicitGenericParam.ref()
|
||||
// CHECK:STDOUT: %.loc7_35.1: %.3 = value_of_initializer %ExplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc7_35.2: %.3 = converted %ExplicitGenericParam.call, %.loc7_35.1
|
||||
// CHECK:STDOUT: %.loc7_10: <specific function> = specific_function %ExplicitGenericParam.ref, @ExplicitGenericParam(i32) [template = constants.%.5]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.call: init %.4 = call %.loc7_10()
|
||||
// CHECK:STDOUT: %.loc7_35.1: %.4 = value_of_initializer %ExplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc7_35.2: %.4 = converted %ExplicitGenericParam.call, %.loc7_35.1
|
||||
// CHECK:STDOUT: return %.loc7_35.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @CallExplicitGenericParamWithGenericArg(%T.loc10_43.1: type) {
|
||||
// CHECK:STDOUT: %T.loc10_43.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc10_43.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc10_62.2: type = struct_type {.a: @CallExplicitGenericParamWithGenericArg.%T.loc10_43.2 (%T)} [symbolic = %.loc10_62.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %.loc10_63.2: type = ptr_type @CallExplicitGenericParamWithGenericArg.%.loc10_62.2 (%.4) [symbolic = %.loc10_63.2 (constants.%.5)]
|
||||
// CHECK:STDOUT: %.loc10_62.2: type = struct_type {.a: @CallExplicitGenericParamWithGenericArg.%T.loc10_43.2 (%T)} [symbolic = %.loc10_62.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.loc10_63.2: type = ptr_type @CallExplicitGenericParamWithGenericArg.%.loc10_62.2 (%.6) [symbolic = %.loc10_63.2 (constants.%.7)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc11_10.2: <specific function> = specific_function constants.%ExplicitGenericParam, @ExplicitGenericParam(%.loc10_62.2) [symbolic = %.loc11_10.2 (constants.%.8)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc10_43.1: type) -> @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.5) {
|
||||
// CHECK:STDOUT: fn(%T.loc10_43.1: type) -> @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.7) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.ref: %ExplicitGenericParam.type = name_ref ExplicitGenericParam, file.%ExplicitGenericParam.decl [template = constants.%ExplicitGenericParam]
|
||||
// CHECK:STDOUT: %T.ref.loc11: type = name_ref T, %T.loc10_43.1 [symbolic = %T.loc10_43.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc11_37: type = struct_type {.a: %T} [symbolic = %.loc10_62.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.call: init @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.5) = call %ExplicitGenericParam.ref()
|
||||
// CHECK:STDOUT: %.loc11_39.1: @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.5) = value_of_initializer %ExplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc11_39.2: @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.5) = converted %ExplicitGenericParam.call, %.loc11_39.1
|
||||
// CHECK:STDOUT: %.loc11_37: type = struct_type {.a: %T} [symbolic = %.loc10_62.2 (constants.%.6)]
|
||||
// CHECK:STDOUT: %.loc11_10.1: <specific function> = specific_function %ExplicitGenericParam.ref, @ExplicitGenericParam(constants.%.6) [symbolic = %.loc11_10.2 (constants.%.8)]
|
||||
// CHECK:STDOUT: %ExplicitGenericParam.call: init @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.7) = call %.loc11_10.1()
|
||||
// CHECK:STDOUT: %.loc11_39.1: @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.7) = value_of_initializer %ExplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc11_39.2: @CallExplicitGenericParamWithGenericArg.%.loc10_63.2 (%.7) = converted %ExplicitGenericParam.call, %.loc11_39.1
|
||||
// CHECK:STDOUT: return %.loc11_39.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -227,22 +245,41 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_50.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(@ExplicitGenericParam.%T.loc4_25.2) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => i32
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_50.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @CallExplicitGenericParamWithGenericArg(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc10_43.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc10_62.2 => constants.%.4
|
||||
// CHECK:STDOUT: %.loc10_63.2 => constants.%.5
|
||||
// CHECK:STDOUT: %.loc10_62.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc10_63.2 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(constants.%.4) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%.4
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.5
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(constants.%.6) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.7
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_50.2 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ExplicitGenericParam(@CallExplicitGenericParamWithGenericArg.%.loc10_62.2) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc4_39.2 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_explicit_vs_deduced.carbon
|
||||
@@ -353,11 +390,13 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.type: type = fn_type @ImplicitGenericParam [template]
|
||||
// CHECK:STDOUT: %.2: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %ImplicitGenericParam: %ImplicitGenericParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %ImplicitGenericParam, @ImplicitGenericParam(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type i32 [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type i32 [template]
|
||||
// CHECK:STDOUT: %CallImplicitGenericParam.type: type = fn_type @CallImplicitGenericParam [template]
|
||||
// CHECK:STDOUT: %CallImplicitGenericParam: %CallImplicitGenericParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %ImplicitGenericParam, @ImplicitGenericParam(i32) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -406,8 +445,8 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %int.make_type_32.loc6_40: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_43.1: type = value_of_initializer %int.make_type_32.loc6_40 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_43.2: type = converted %int.make_type_32.loc6_40, %.loc6_43.1 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_43.3: type = ptr_type i32 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %return: ref %.3 = var <return slot>
|
||||
// CHECK:STDOUT: %.loc6_43.3: type = ptr_type i32 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %return: ref %.4 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -415,29 +454,53 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %T.loc4_25.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_25.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_45.2: type = ptr_type @ImplicitGenericParam.%T.loc4_25.2 (%T) [symbolic = %.loc4_45.2 (constants.%.1)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_25.1: type](%x: @ImplicitGenericParam.%T.loc4_25.2 (%T)) -> @ImplicitGenericParam.%.loc4_45.2 (%.1);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_56.2: <specific function> = specific_function constants.%ImplicitGenericParam, @ImplicitGenericParam(%T.loc4_25.2) [symbolic = %.loc4_56.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_25.1: type](%x: @ImplicitGenericParam.%T.loc4_25.2 (%T)) -> @ImplicitGenericParam.%.loc4_45.2 (%.1) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.ref: %ImplicitGenericParam.type = name_ref ImplicitGenericParam, file.%ImplicitGenericParam.decl [template = constants.%ImplicitGenericParam]
|
||||
// CHECK:STDOUT: %x.ref: @ImplicitGenericParam.%T.loc4_25.2 (%T) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc4_56.1: <specific function> = specific_function %ImplicitGenericParam.ref, @ImplicitGenericParam(constants.%T) [symbolic = %.loc4_56.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.call: init @ImplicitGenericParam.%.loc4_45.2 (%.1) = call %.loc4_56.1(%x.ref)
|
||||
// CHECK:STDOUT: %.loc4_79.1: @ImplicitGenericParam.%.loc4_45.2 (%.1) = value_of_initializer %ImplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc4_79.2: @ImplicitGenericParam.%.loc4_45.2 (%.1) = converted %ImplicitGenericParam.call, %.loc4_79.1
|
||||
// CHECK:STDOUT: return %.loc4_79.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallImplicitGenericParam(%n: i32) -> %.3 {
|
||||
// CHECK:STDOUT: fn @CallImplicitGenericParam(%n: i32) -> %.4 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.ref: %ImplicitGenericParam.type = name_ref ImplicitGenericParam, file.%ImplicitGenericParam.decl [template = constants.%ImplicitGenericParam]
|
||||
// CHECK:STDOUT: %n.ref: i32 = name_ref n, %n
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.call: init %.3 = call %ImplicitGenericParam.ref(%n.ref)
|
||||
// CHECK:STDOUT: %.loc7_33.1: %.3 = value_of_initializer %ImplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc7_33.2: %.3 = converted %ImplicitGenericParam.call, %.loc7_33.1
|
||||
// CHECK:STDOUT: %.loc7_10: <specific function> = specific_function %ImplicitGenericParam.ref, @ImplicitGenericParam(i32) [template = constants.%.5]
|
||||
// CHECK:STDOUT: %ImplicitGenericParam.call: init %.4 = call %.loc7_10(%n.ref)
|
||||
// CHECK:STDOUT: %.loc7_33.1: %.4 = value_of_initializer %ImplicitGenericParam.call
|
||||
// CHECK:STDOUT: %.loc7_33.2: %.4 = converted %ImplicitGenericParam.call, %.loc7_33.1
|
||||
// CHECK:STDOUT: return %.loc7_33.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ImplicitGenericParam(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_45.2 => constants.%.1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_56.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ImplicitGenericParam(@ImplicitGenericParam.%T.loc4_25.2) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_45.2 => constants.%.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ImplicitGenericParam(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_25.2 => i32
|
||||
// CHECK:STDOUT: %.loc4_45.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.loc4_45.2 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc4_56.2 => constants.%.5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- deduce_nested_tuple.carbon
|
||||
@@ -451,13 +514,15 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %.3: type = tuple_type (%T, i32) [symbolic]
|
||||
// CHECK:STDOUT: %TupleParam.type: type = fn_type @TupleParam [template]
|
||||
// CHECK:STDOUT: %TupleParam: %TupleParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.3 [symbolic]
|
||||
// CHECK:STDOUT: %CallTupleParam.type: type = fn_type @CallTupleParam [template]
|
||||
// CHECK:STDOUT: %CallTupleParam: %CallTupleParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
|
||||
// CHECK:STDOUT: %.6: type = tuple_type (i32, i32) [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.6 [template]
|
||||
// CHECK:STDOUT: %tuple: %.6 = tuple_value (%.4, %.5) [template]
|
||||
// CHECK:STDOUT: %.5: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %.6: i32 = int_literal 2 [template]
|
||||
// CHECK:STDOUT: %.7: type = tuple_type (i32, i32) [template]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %TupleParam, @TupleParam(i32) [template]
|
||||
// CHECK:STDOUT: %.9: type = ptr_type %.7 [template]
|
||||
// CHECK:STDOUT: %tuple: %.7 = tuple_value (%.5, %.6) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -506,18 +571,24 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %T.loc4_15.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_35.5: type = tuple_type (@TupleParam.%T.loc4_15.2 (%T), i32) [symbolic = %.loc4_35.5 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_15.1: type](%x: @TupleParam.%.loc4_35.5 (%.3));
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_15.1: type](%x: @TupleParam.%.loc4_35.5 (%.3)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallTupleParam() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %TupleParam.ref: %TupleParam.type = name_ref TupleParam, file.%TupleParam.decl [template = constants.%TupleParam]
|
||||
// CHECK:STDOUT: %.loc7_15: i32 = int_literal 1 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc7_18: i32 = int_literal 2 [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc7_19: %.6 = tuple_literal (%.loc7_15, %.loc7_18)
|
||||
// CHECK:STDOUT: %tuple: %.6 = tuple_value (%.loc7_15, %.loc7_18) [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc7_13: %.6 = converted %.loc7_19, %tuple [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %TupleParam.call: init %.1 = call %TupleParam.ref(%.loc7_13)
|
||||
// CHECK:STDOUT: %.loc7_15: i32 = int_literal 1 [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc7_18: i32 = int_literal 2 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc7_19: %.7 = tuple_literal (%.loc7_15, %.loc7_18)
|
||||
// CHECK:STDOUT: %.loc7_3: <specific function> = specific_function %TupleParam.ref, @TupleParam(i32) [template = constants.%.8]
|
||||
// CHECK:STDOUT: %tuple: %.7 = tuple_value (%.loc7_15, %.loc7_18) [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc7_13: %.7 = converted %.loc7_19, %tuple [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %TupleParam.call: init %.1 = call %.loc7_3(%.loc7_13)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -528,7 +599,9 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @TupleParam(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_15.2 => i32
|
||||
// CHECK:STDOUT: %.loc4_35.5 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc4_35.5 => constants.%.7
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_deduce_nested_struct.carbon
|
||||
@@ -541,11 +614,12 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %.2: type = struct_type {.a: %T, .b: i32} [symbolic]
|
||||
// CHECK:STDOUT: %StructParam.type: type = fn_type @StructParam [template]
|
||||
// CHECK:STDOUT: %StructParam: %StructParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type %.2 [symbolic]
|
||||
// CHECK:STDOUT: %CallStructParam.type: type = fn_type @CallStructParam [template]
|
||||
// CHECK:STDOUT: %CallStructParam: %CallStructParam.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %.4: i32 = int_literal 2 [template]
|
||||
// CHECK:STDOUT: %.5: type = struct_type {.a: i32, .b: i32} [template]
|
||||
// CHECK:STDOUT: %.4: i32 = int_literal 1 [template]
|
||||
// CHECK:STDOUT: %.5: i32 = int_literal 2 [template]
|
||||
// CHECK:STDOUT: %.6: type = struct_type {.a: i32, .b: i32} [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -593,15 +667,20 @@ fn CallImplicitNotDeducible() {
|
||||
// CHECK:STDOUT: %T.loc4_16.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_16.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc4_44.2: type = struct_type {.a: @StructParam.%T.loc4_16.2 (%T), .b: i32} [symbolic = %.loc4_44.2 (constants.%.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_16.1: type](%x: @StructParam.%.loc4_44.2 (%.2));
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_16.1: type](%x: @StructParam.%.loc4_44.2 (%.2)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallStructParam() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %StructParam.ref: %StructParam.type = name_ref StructParam, file.%StructParam.decl [template = constants.%StructParam]
|
||||
// CHECK:STDOUT: %.loc14_21: i32 = int_literal 1 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc14_29: i32 = int_literal 2 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc14_30: %.5 = struct_literal (%.loc14_21, %.loc14_29)
|
||||
// CHECK:STDOUT: %.loc14_21: i32 = int_literal 1 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc14_29: i32 = int_literal 2 [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc14_30: %.6 = struct_literal (%.loc14_21, %.loc14_29)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -61,15 +61,18 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: %Function: %Function.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [template]
|
||||
// CHECK:STDOUT: %CallGeneric: %CallGeneric.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %.2: <specific function> = specific_function %Function, @Function(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %CallGenericPtr.type: type = fn_type @CallGenericPtr [template]
|
||||
// CHECK:STDOUT: %CallGenericPtr: %CallGenericPtr.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: <specific function> = specific_function %Function, @Function(%.3) [symbolic]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.3: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.4: <witness> = complete_type_witness %.3 [template]
|
||||
// CHECK:STDOUT: %.5: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.6: <witness> = complete_type_witness %.5 [template]
|
||||
// CHECK:STDOUT: %CallSpecific.type: type = fn_type @CallSpecific [template]
|
||||
// CHECK:STDOUT: %CallSpecific: %CallSpecific.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.5 [template]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %Function, @Function(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -106,17 +109,17 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallGenericPtr.decl: %CallGenericPtr.type = fn_decl @CallGenericPtr [template = constants.%CallGenericPtr] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: @CallGenericPtr.%.loc12_33.2 (%.2) = binding_pattern x
|
||||
// CHECK:STDOUT: %x.patt: @CallGenericPtr.%.loc12_33.2 (%.3) = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc12_19.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc12_32: type = name_ref T, %T.loc12_19.1 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_33.1: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %x.param: @CallGenericPtr.%.loc12_33.2 (%.2) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallGenericPtr.%.loc12_33.2 (%.2) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %.loc12_33.1: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %x.param: @CallGenericPtr.%.loc12_33.2 (%.3) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallGenericPtr.%.loc12_33.2 (%.3) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %T.ref.loc12_39: type = name_ref T, %T.loc12_19.1 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_40: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %return: ref @CallGenericPtr.%.loc12_33.2 (%.2) = var <return slot>
|
||||
// CHECK:STDOUT: %.loc12_40: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %return: ref @CallGenericPtr.%.loc12_33.2 (%.3) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %CallSpecific.decl: %CallSpecific.type = fn_decl @CallSpecific [template = constants.%CallSpecific] {
|
||||
@@ -131,7 +134,7 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc16: <witness> = complete_type_witness %.3 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc16: <witness> = complete_type_witness %.5 [template = constants.%.6]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
@@ -153,13 +156,15 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: %T.loc8_16.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_16.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc9_10.2: <specific function> = specific_function constants.%Function, @Function(%T.loc8_16.2) [symbolic = %.loc9_10.2 (constants.%.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc8_16.1: type, %x: @CallGeneric.%T.loc8_16.2 (%T)) -> @CallGeneric.%T.loc8_16.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %T.ref.loc9: type = name_ref T, %T.loc8_16.1 [symbolic = %T.loc8_16.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %x.ref: @CallGeneric.%T.loc8_16.2 (%T) = name_ref x, %x
|
||||
// CHECK:STDOUT: %Function.call: init @CallGeneric.%T.loc8_16.2 (%T) = call %Function.ref(%x.ref)
|
||||
// CHECK:STDOUT: %.loc9_10.1: <specific function> = specific_function %Function.ref, @Function(constants.%T) [symbolic = %.loc9_10.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %Function.call: init @CallGeneric.%T.loc8_16.2 (%T) = call %.loc9_10.1(%x.ref)
|
||||
// CHECK:STDOUT: %.loc9_24.1: @CallGeneric.%T.loc8_16.2 (%T) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc9_24.2: @CallGeneric.%T.loc8_16.2 (%T) = converted %Function.call, %.loc9_24.1
|
||||
// CHECK:STDOUT: return %.loc9_24.2
|
||||
@@ -168,19 +173,21 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @CallGenericPtr(%T.loc12_19.1: type) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_33.2: type = ptr_type @CallGenericPtr.%T.loc12_19.2 (%T) [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc12_33.2: type = ptr_type @CallGenericPtr.%T.loc12_19.2 (%T) [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc13_10.2: <specific function> = specific_function constants.%Function, @Function(%.loc12_33.2) [symbolic = %.loc13_10.2 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc12_19.1: type, %x: @CallGenericPtr.%.loc12_33.2 (%.2)) -> @CallGenericPtr.%.loc12_33.2 (%.2) {
|
||||
// CHECK:STDOUT: fn(%T.loc12_19.1: type, %x: @CallGenericPtr.%.loc12_33.2 (%.3)) -> @CallGenericPtr.%.loc12_33.2 (%.3) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %T.ref.loc13: type = name_ref T, %T.loc12_19.1 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc13_20: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %x.ref: @CallGenericPtr.%.loc12_33.2 (%.2) = name_ref x, %x
|
||||
// CHECK:STDOUT: %Function.call: init @CallGenericPtr.%.loc12_33.2 (%.2) = call %Function.ref(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_25.1: @CallGenericPtr.%.loc12_33.2 (%.2) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc13_25.2: @CallGenericPtr.%.loc12_33.2 (%.2) = converted %Function.call, %.loc13_25.1
|
||||
// CHECK:STDOUT: %.loc13_20: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %x.ref: @CallGenericPtr.%.loc12_33.2 (%.3) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc13_10.1: <specific function> = specific_function %Function.ref, @Function(constants.%.3) [symbolic = %.loc13_10.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %Function.call: init @CallGenericPtr.%.loc12_33.2 (%.3) = call %.loc13_10.1(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_25.1: @CallGenericPtr.%.loc12_33.2 (%.3) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc13_25.2: @CallGenericPtr.%.loc12_33.2 (%.3) = converted %Function.call, %.loc13_25.1
|
||||
// CHECK:STDOUT: return %.loc13_25.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -190,30 +197,45 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %C.ref.loc19: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %x.ref: %C = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc19: <specific function> = specific_function %Function.ref, @Function(constants.%C) [template = constants.%.8]
|
||||
// CHECK:STDOUT: %.loc18: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %Function.call: init %C = call %Function.ref(%x.ref) to %.loc18
|
||||
// CHECK:STDOUT: %Function.call: init %C = call %.loc19(%x.ref) to %.loc18
|
||||
// CHECK:STDOUT: return %Function.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @CallGeneric(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc8_16.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @CallGenericPtr(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc12_33.2 => constants.%.2
|
||||
// CHECK:STDOUT: specific @Function(@CallGeneric.%T.loc8_16.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.2
|
||||
// CHECK:STDOUT: specific @CallGenericPtr(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc12_33.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%.3) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(@CallGenericPtr.%.loc12_33.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%C
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- deduced.carbon
|
||||
@@ -225,15 +247,18 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: %Function: %Function.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [template]
|
||||
// CHECK:STDOUT: %CallGeneric: %CallGeneric.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %.2: <specific function> = specific_function %Function, @Function(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = ptr_type %T [symbolic]
|
||||
// CHECK:STDOUT: %CallGenericPtr.type: type = fn_type @CallGenericPtr [template]
|
||||
// CHECK:STDOUT: %CallGenericPtr: %CallGenericPtr.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: <specific function> = specific_function %Function, @Function(%.3) [symbolic]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.3: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.4: <witness> = complete_type_witness %.3 [template]
|
||||
// CHECK:STDOUT: %.5: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.6: <witness> = complete_type_witness %.5 [template]
|
||||
// CHECK:STDOUT: %CallSpecific.type: type = fn_type @CallSpecific [template]
|
||||
// CHECK:STDOUT: %CallSpecific: %CallSpecific.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.5: type = ptr_type %.3 [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.5 [template]
|
||||
// CHECK:STDOUT: %.8: <specific function> = specific_function %Function, @Function(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -270,17 +295,17 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallGenericPtr.decl: %CallGenericPtr.type = fn_decl @CallGenericPtr [template = constants.%CallGenericPtr] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: @CallGenericPtr.%.loc12_33.2 (%.2) = binding_pattern x
|
||||
// CHECK:STDOUT: %x.patt: @CallGenericPtr.%.loc12_33.2 (%.3) = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc12_19.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc12_32: type = name_ref T, %T.loc12_19.1 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_33.1: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %x.param: @CallGenericPtr.%.loc12_33.2 (%.2) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallGenericPtr.%.loc12_33.2 (%.2) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %.loc12_33.1: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %x.param: @CallGenericPtr.%.loc12_33.2 (%.3) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @CallGenericPtr.%.loc12_33.2 (%.3) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %T.ref.loc12_39: type = name_ref T, %T.loc12_19.1 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_40: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %return: ref @CallGenericPtr.%.loc12_33.2 (%.2) = var <return slot>
|
||||
// CHECK:STDOUT: %.loc12_40: type = ptr_type %T [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %return: ref @CallGenericPtr.%.loc12_33.2 (%.3) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %CallSpecific.decl: %CallSpecific.type = fn_decl @CallSpecific [template = constants.%CallSpecific] {
|
||||
@@ -295,7 +320,7 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %.loc16: <witness> = complete_type_witness %.3 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc16: <witness> = complete_type_witness %.5 [template = constants.%.6]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
@@ -317,12 +342,14 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: %T.loc8_16.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_16.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc9_10.2: <specific function> = specific_function constants.%Function, @Function(%T.loc8_16.2) [symbolic = %.loc9_10.2 (constants.%.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc8_16.1: type, %x: @CallGeneric.%T.loc8_16.2 (%T)) -> @CallGeneric.%T.loc8_16.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %x.ref: @CallGeneric.%T.loc8_16.2 (%T) = name_ref x, %x
|
||||
// CHECK:STDOUT: %Function.call: init @CallGeneric.%T.loc8_16.2 (%T) = call %Function.ref(%x.ref)
|
||||
// CHECK:STDOUT: %.loc9_10.1: <specific function> = specific_function %Function.ref, @Function(constants.%T) [symbolic = %.loc9_10.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %Function.call: init @CallGeneric.%T.loc8_16.2 (%T) = call %.loc9_10.1(%x.ref)
|
||||
// CHECK:STDOUT: %.loc9_21.1: @CallGeneric.%T.loc8_16.2 (%T) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc9_21.2: @CallGeneric.%T.loc8_16.2 (%T) = converted %Function.call, %.loc9_21.1
|
||||
// CHECK:STDOUT: return %.loc9_21.2
|
||||
@@ -331,17 +358,19 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @CallGenericPtr(%T.loc12_19.1: type) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc12_19.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc12_33.2: type = ptr_type @CallGenericPtr.%T.loc12_19.2 (%T) [symbolic = %.loc12_33.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc12_33.2: type = ptr_type @CallGenericPtr.%T.loc12_19.2 (%T) [symbolic = %.loc12_33.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc13_10.2: <specific function> = specific_function constants.%Function, @Function(%.loc12_33.2) [symbolic = %.loc13_10.2 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc12_19.1: type, %x: @CallGenericPtr.%.loc12_33.2 (%.2)) -> @CallGenericPtr.%.loc12_33.2 (%.2) {
|
||||
// CHECK:STDOUT: fn(%T.loc12_19.1: type, %x: @CallGenericPtr.%.loc12_33.2 (%.3)) -> @CallGenericPtr.%.loc12_33.2 (%.3) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %x.ref: @CallGenericPtr.%.loc12_33.2 (%.2) = name_ref x, %x
|
||||
// CHECK:STDOUT: %Function.call: init @CallGenericPtr.%.loc12_33.2 (%.2) = call %Function.ref(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_21.1: @CallGenericPtr.%.loc12_33.2 (%.2) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc13_21.2: @CallGenericPtr.%.loc12_33.2 (%.2) = converted %Function.call, %.loc13_21.1
|
||||
// CHECK:STDOUT: %x.ref: @CallGenericPtr.%.loc12_33.2 (%.3) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc13_10.1: <specific function> = specific_function %Function.ref, @Function(constants.%.3) [symbolic = %.loc13_10.2 (constants.%.4)]
|
||||
// CHECK:STDOUT: %Function.call: init @CallGenericPtr.%.loc12_33.2 (%.3) = call %.loc13_10.1(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_21.1: @CallGenericPtr.%.loc12_33.2 (%.3) = value_of_initializer %Function.call
|
||||
// CHECK:STDOUT: %.loc13_21.2: @CallGenericPtr.%.loc12_33.2 (%.3) = converted %Function.call, %.loc13_21.1
|
||||
// CHECK:STDOUT: return %.loc13_21.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -350,29 +379,44 @@ fn CallSpecific(x: C) -> C {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [template = constants.%Function]
|
||||
// CHECK:STDOUT: %x.ref: %C = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc19: <specific function> = specific_function %Function.ref, @Function(constants.%C) [template = constants.%.8]
|
||||
// CHECK:STDOUT: %.loc18: ref %C = splice_block %return {}
|
||||
// CHECK:STDOUT: %Function.call: init %C = call %Function.ref(%x.ref) to %.loc18
|
||||
// CHECK:STDOUT: %Function.call: init %C = call %.loc19(%x.ref) to %.loc18
|
||||
// CHECK:STDOUT: return %Function.call to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @CallGeneric(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc8_16.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @CallGenericPtr(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc12_33.2 => constants.%.2
|
||||
// CHECK:STDOUT: specific @Function(@CallGeneric.%T.loc8_16.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.2
|
||||
// CHECK:STDOUT: specific @CallGenericPtr(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc12_19.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc12_33.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%.3) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(@CallGenericPtr.%.loc12_33.2) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Function(constants.%C) {
|
||||
// CHECK:STDOUT: %T.loc4_13.2 => constants.%C
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+12
-1
@@ -97,6 +97,7 @@ fn F(U:! type, T:! type) -> U* {
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
|
||||
// CHECK:STDOUT: %.2: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %F, @F(%T) [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -143,12 +144,14 @@ fn F(U:! type, T:! type) -> U* {
|
||||
// CHECK:STDOUT: %.loc4_20.2: type = ptr_type @F.%T.loc4_6.2 (%T) [symbolic = %.loc4_20.2 (constants.%.1)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_10.2: <specific function> = specific_function constants.%F, @F(%T.loc4_6.2) [symbolic = %.loc7_10.2 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc6: type) -> %.1 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl.loc4 [template = constants.%F]
|
||||
// CHECK:STDOUT: %T.ref.loc7: type = name_ref T, %T.loc6 [symbolic = %T.loc4_6.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%.loc4_20.2 (%.1) = call %F.ref()
|
||||
// CHECK:STDOUT: %.loc7_10.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %.loc7_10.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %F.call: init @F.%.loc4_20.2 (%.1) = call %.loc7_10.1()
|
||||
// CHECK:STDOUT: %.loc7_14.1: @F.%.loc4_20.2 (%.1) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc7_14.2: @F.%.loc4_20.2 (%.1) = converted %F.call, %.loc7_14.1
|
||||
// CHECK:STDOUT: return %.loc7_14.2
|
||||
@@ -158,6 +161,14 @@ fn F(U:! type, T:! type) -> U* {
|
||||
// CHECK:STDOUT: specific @F(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_20.2 => constants.%.1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc7_10.2 => constants.%.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(@F.%T.loc4_6.2) {
|
||||
// CHECK:STDOUT: %T.loc4_6.2 => constants.%T
|
||||
// CHECK:STDOUT: %.loc4_20.2 => constants.%.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_different_return_type.carbon
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/generic/resolve_used.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/resolve_used.carbon
|
||||
|
||||
// --- fail_call_monomorphization_error.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn ErrorIfNIsZero(N:! i32) {
|
||||
// Check that we resolve the definition of a used specific function by
|
||||
// ensuring we produce an error when doing so. Notionally this error is
|
||||
// produced as a result of instantiating the `Core.Int` template, although
|
||||
// that's not how we currently model `Core.Int`.
|
||||
// CHECK:STDERR: fail_call_monomorphization_error.carbon:[[@LINE+3]]:10: error: integer type width of 0 is not positive
|
||||
// CHECK:STDERR: var v: Core.Int(N);
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
var v: Core.Int(N);
|
||||
}
|
||||
|
||||
fn CallNegative() {
|
||||
ErrorIfNIsZero(0);
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- fail_call_monomorphization_error.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %N: i32 = bind_symbolic_name N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %ErrorIfNIsZero.type: type = fn_type @ErrorIfNIsZero [template]
|
||||
// CHECK:STDOUT: %ErrorIfNIsZero: %ErrorIfNIsZero.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Int.type: type = fn_type @Int [template]
|
||||
// CHECK:STDOUT: %Int: %Int.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: type = int_type signed, %N [symbolic]
|
||||
// CHECK:STDOUT: %CallNegative.type: type = fn_type @CallNegative [template]
|
||||
// CHECK:STDOUT: %CallNegative: %CallNegative.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.3: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: %.4: <specific function> = specific_function %ErrorIfNIsZero, @ErrorIfNIsZero(%.3) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Int32 = %import_ref.1
|
||||
// CHECK:STDOUT: .Int = %import_ref.2
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
|
||||
// CHECK:STDOUT: %import_ref.2: %Int.type = import_ref Core//prelude/types, inst+15, loaded [template = constants.%Int]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .ErrorIfNIsZero = %ErrorIfNIsZero.decl
|
||||
// CHECK:STDOUT: .CallNegative = %CallNegative.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %ErrorIfNIsZero.decl: %ErrorIfNIsZero.type = fn_decl @ErrorIfNIsZero [template = constants.%ErrorIfNIsZero] {
|
||||
// CHECK:STDOUT: %N.patt: i32 = symbolic_binding_pattern N, 0
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc4_23.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc4_23.2: type = converted %int.make_type_32, %.loc4_23.1 [template = i32]
|
||||
// CHECK:STDOUT: %N.param: i32 = param N, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %N.loc4_19.1: i32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc4_19.2 (constants.%N)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallNegative.decl: %CallNegative.type = fn_decl @CallNegative [template = constants.%CallNegative] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @ErrorIfNIsZero(%N.loc4_19.1: i32) {
|
||||
// CHECK:STDOUT: %N.loc4_19.2: i32 = bind_symbolic_name N, 0 [symbolic = %N.loc4_19.2 (constants.%N)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc12_18: type = int_type signed, %N.loc4_19.2 [symbolic = %.loc12_18 (constants.%.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%N.loc4_19.1: i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
|
||||
// CHECK:STDOUT: %Int.ref: %Int.type = name_ref Int, imports.%import_ref.2 [template = constants.%Int]
|
||||
// CHECK:STDOUT: %N.ref: i32 = name_ref N, %N.loc4_19.1 [symbolic = %N.loc4_19.2 (constants.%N)]
|
||||
// CHECK:STDOUT: %int.make_type_signed: init type = call %Int.ref(%N.ref) [symbolic = %.loc12_18 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc12_20.1: type = value_of_initializer %int.make_type_signed [symbolic = %.loc12_18 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc12_20.2: type = converted %int.make_type_signed, %.loc12_20.1 [symbolic = %.loc12_18 (constants.%.2)]
|
||||
// CHECK:STDOUT: %v.var: ref @ErrorIfNIsZero.%.loc12_18 (%.2) = var v
|
||||
// CHECK:STDOUT: %v: ref @ErrorIfNIsZero.%.loc12_18 (%.2) = bind_name v, %v.var
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int(%size: i32) -> type = "int.make_type_signed";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallNegative() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %ErrorIfNIsZero.ref: %ErrorIfNIsZero.type = name_ref ErrorIfNIsZero, file.%ErrorIfNIsZero.decl [template = constants.%ErrorIfNIsZero]
|
||||
// CHECK:STDOUT: %.loc16_18: i32 = int_literal 0 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc16_3: <specific function> = specific_function %ErrorIfNIsZero.ref, @ErrorIfNIsZero(constants.%.3) [template = constants.%.4]
|
||||
// CHECK:STDOUT: %ErrorIfNIsZero.call: init %.1 = call %.loc16_3()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ErrorIfNIsZero(constants.%N) {
|
||||
// CHECK:STDOUT: %N.loc4_19.2 => constants.%N
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @ErrorIfNIsZero(constants.%.3) {
|
||||
// CHECK:STDOUT: %N.loc4_19.2 => constants.%.3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc12_18 => <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
+77
-24
@@ -9,7 +9,7 @@
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/return_slot.carbon
|
||||
|
||||
class Wrap(T:! type) {
|
||||
fn Make() -> T;
|
||||
fn Make() -> T { return Make(); }
|
||||
}
|
||||
|
||||
class C { var arr: [i32; 100]; }
|
||||
@@ -32,29 +32,33 @@ fn G() {
|
||||
// CHECK:STDOUT: %Make.1: %Make.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.2: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.3: <witness> = complete_type_witness %.2 [template]
|
||||
// CHECK:STDOUT: %.4: <specific function> = specific_function %Make.1, @Make(%T) [symbolic]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: i32 = int_literal 100 [template]
|
||||
// CHECK:STDOUT: %.5: type = array_type %.4, i32 [template]
|
||||
// CHECK:STDOUT: %.6: type = ptr_type %.5 [template]
|
||||
// CHECK:STDOUT: %.7: type = unbound_element_type %C, %.5 [template]
|
||||
// CHECK:STDOUT: %.8: type = struct_type {.arr: %.5} [template]
|
||||
// CHECK:STDOUT: %.9: <witness> = complete_type_witness %.8 [template]
|
||||
// CHECK:STDOUT: %.5: i32 = int_literal 100 [template]
|
||||
// CHECK:STDOUT: %.6: type = array_type %.5, i32 [template]
|
||||
// CHECK:STDOUT: %.7: type = ptr_type %.6 [template]
|
||||
// CHECK:STDOUT: %.8: type = unbound_element_type %C, %.6 [template]
|
||||
// CHECK:STDOUT: %.9: type = struct_type {.arr: %.6} [template]
|
||||
// CHECK:STDOUT: %.10: <witness> = complete_type_witness %.9 [template]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Wrap.3: type = class_type @Wrap, @Wrap(i32) [template]
|
||||
// CHECK:STDOUT: %Make.type.2: type = fn_type @Make, @Wrap(i32) [template]
|
||||
// CHECK:STDOUT: %Make.2: %Make.type.2 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.10: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.11: type = ptr_type %.2 [template]
|
||||
// CHECK:STDOUT: %.12: <specific function> = specific_function %Make.2, @Make(i32) [template]
|
||||
// CHECK:STDOUT: %Wrap.4: type = class_type @Wrap, @Wrap(%.1) [template]
|
||||
// CHECK:STDOUT: %Make.type.3: type = fn_type @Make, @Wrap(%.1) [template]
|
||||
// CHECK:STDOUT: %Make.3: %Make.type.3 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.11: type = struct_type {.arr: %.6} [template]
|
||||
// CHECK:STDOUT: %.12: type = ptr_type %.8 [template]
|
||||
// CHECK:STDOUT: %.13: <specific function> = specific_function %Make.3, @Make(%.1) [template]
|
||||
// CHECK:STDOUT: %.14: type = struct_type {.arr: %.7} [template]
|
||||
// CHECK:STDOUT: %.15: type = ptr_type %.9 [template]
|
||||
// CHECK:STDOUT: %Wrap.5: type = class_type @Wrap, @Wrap(%C) [template]
|
||||
// CHECK:STDOUT: %Make.type.4: type = fn_type @Make, @Wrap(%C) [template]
|
||||
// CHECK:STDOUT: %Make.4: %Make.type.4 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.16: <specific function> = specific_function %Make.4, @Make(%C) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -112,12 +116,12 @@ fn G() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc15_26: i32 = int_literal 100 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %.loc15_26: i32 = int_literal 100 [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc15_21.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc15_21.2: type = converted %int.make_type_32, %.loc15_21.1 [template = i32]
|
||||
// CHECK:STDOUT: %.loc15_29: type = array_type %.loc15_26, i32 [template = constants.%.5]
|
||||
// CHECK:STDOUT: %.loc15_18: %.7 = field_decl arr, element0 [template]
|
||||
// CHECK:STDOUT: %.loc15_32: <witness> = complete_type_witness %.8 [template = constants.%.9]
|
||||
// CHECK:STDOUT: %.loc15_29: type = array_type %.loc15_26, i32 [template = constants.%.6]
|
||||
// CHECK:STDOUT: %.loc15_18: %.8 = field_decl arr, element0 [template]
|
||||
// CHECK:STDOUT: %.loc15_32: <witness> = complete_type_witness %.9 [template = constants.%.10]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
@@ -127,7 +131,21 @@ fn G() {
|
||||
// CHECK:STDOUT: generic fn @Make(@Wrap.%T.loc11_12.1: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> @Make.%T (%T);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type: type = fn_type @Make, @Wrap(%T) [symbolic = %Make.type (constants.%Make.type.1)]
|
||||
// CHECK:STDOUT: %Make: @Make.%Make.type (%Make.type.1) = struct_value () [symbolic = %Make (constants.%Make.1)]
|
||||
// CHECK:STDOUT: %.loc12_27.3: <specific function> = specific_function %Make, @Make(%T) [symbolic = %.loc12_27.3 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> @Make.%T (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc12_27.1: @Make.%Make.type (%Make.type.1) = specific_constant @Wrap.%Make.decl, @Wrap(constants.%T) [symbolic = %Make (constants.%Make.1)]
|
||||
// CHECK:STDOUT: %Make.ref: @Make.%Make.type (%Make.type.1) = name_ref Make, %.loc12_27.1 [symbolic = %Make (constants.%Make.1)]
|
||||
// CHECK:STDOUT: %.loc12_27.2: <specific function> = specific_function %Make.ref, @Make(constants.%T) [symbolic = %.loc12_27.3 (constants.%.4)]
|
||||
// CHECK:STDOUT: %Make.call: init @Make.%T (%T) = call %.loc12_27.2()
|
||||
// CHECK:STDOUT: %.loc12_33.1: @Make.%T (%T) = value_of_initializer %Make.call
|
||||
// CHECK:STDOUT: %.loc12_33.2: @Make.%T (%T) = converted %Make.call, %.loc12_33.1
|
||||
// CHECK:STDOUT: return %.loc12_33.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
@@ -144,9 +162,10 @@ fn G() {
|
||||
// CHECK:STDOUT: %.loc18_20.1: type = value_of_initializer %int.make_type_32.loc18_21 [template = i32]
|
||||
// CHECK:STDOUT: %.loc18_20.2: type = converted %int.make_type_32.loc18_21, %.loc18_20.1 [template = i32]
|
||||
// CHECK:STDOUT: %Wrap.loc18: type = class_type @Wrap, @Wrap(i32) [template = constants.%Wrap.3]
|
||||
// CHECK:STDOUT: %.loc18_25: %Make.type.2 = specific_constant @Wrap.%Make.decl, @Wrap(i32) [template = constants.%Make.2]
|
||||
// CHECK:STDOUT: %Make.ref.loc18: %Make.type.2 = name_ref Make, %.loc18_25 [template = constants.%Make.2]
|
||||
// CHECK:STDOUT: %Make.call.loc18: init i32 = call %Make.ref.loc18()
|
||||
// CHECK:STDOUT: %.loc18_25.1: %Make.type.2 = specific_constant @Wrap.%Make.decl, @Wrap(i32) [template = constants.%Make.2]
|
||||
// CHECK:STDOUT: %Make.ref.loc18: %Make.type.2 = name_ref Make, %.loc18_25.1 [template = constants.%Make.2]
|
||||
// CHECK:STDOUT: %.loc18_25.2: <specific function> = specific_function %Make.ref.loc18, @Make(i32) [template = constants.%.12]
|
||||
// CHECK:STDOUT: %Make.call.loc18: init i32 = call %.loc18_25.2()
|
||||
// CHECK:STDOUT: assign %a.var, %Make.call.loc18
|
||||
// CHECK:STDOUT: %.loc19_11.1: %.1 = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc19_11.2: type = converted %.loc19_11.1, constants.%.1 [template = constants.%.1]
|
||||
@@ -156,9 +175,10 @@ fn G() {
|
||||
// CHECK:STDOUT: %.loc19_21: %.1 = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc19_19: type = converted %.loc19_21, constants.%.1 [template = constants.%.1]
|
||||
// CHECK:STDOUT: %Wrap.loc19: type = class_type @Wrap, @Wrap(constants.%.1) [template = constants.%Wrap.4]
|
||||
// CHECK:STDOUT: %.loc19_23: %Make.type.3 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%.1) [template = constants.%Make.3]
|
||||
// CHECK:STDOUT: %Make.ref.loc19: %Make.type.3 = name_ref Make, %.loc19_23 [template = constants.%Make.3]
|
||||
// CHECK:STDOUT: %Make.call.loc19: init %.1 = call %Make.ref.loc19()
|
||||
// CHECK:STDOUT: %.loc19_23.1: %Make.type.3 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%.1) [template = constants.%Make.3]
|
||||
// CHECK:STDOUT: %Make.ref.loc19: %Make.type.3 = name_ref Make, %.loc19_23.1 [template = constants.%Make.3]
|
||||
// CHECK:STDOUT: %.loc19_23.2: <specific function> = specific_function %Make.ref.loc19, @Make(constants.%.1) [template = constants.%.13]
|
||||
// CHECK:STDOUT: %Make.call.loc19: init %.1 = call %.loc19_23.2()
|
||||
// CHECK:STDOUT: assign %b.var, %Make.call.loc19
|
||||
// CHECK:STDOUT: %C.ref.loc20_10: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %c.var: ref %C = var c
|
||||
@@ -166,26 +186,44 @@ fn G() {
|
||||
// CHECK:STDOUT: %Wrap.ref.loc20: %Wrap.type = name_ref Wrap, file.%Wrap.decl [template = constants.%Wrap.1]
|
||||
// CHECK:STDOUT: %C.ref.loc20_19: type = name_ref C, file.%C.decl [template = constants.%C]
|
||||
// CHECK:STDOUT: %Wrap.loc20: type = class_type @Wrap, @Wrap(constants.%C) [template = constants.%Wrap.5]
|
||||
// CHECK:STDOUT: %.loc20_21: %Make.type.4 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%C) [template = constants.%Make.4]
|
||||
// CHECK:STDOUT: %Make.ref.loc20: %Make.type.4 = name_ref Make, %.loc20_21 [template = constants.%Make.4]
|
||||
// CHECK:STDOUT: %.loc20_21.1: %Make.type.4 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%C) [template = constants.%Make.4]
|
||||
// CHECK:STDOUT: %Make.ref.loc20: %Make.type.4 = name_ref Make, %.loc20_21.1 [template = constants.%Make.4]
|
||||
// CHECK:STDOUT: %.loc20_21.2: <specific function> = specific_function %Make.ref.loc20, @Make(constants.%C) [template = constants.%.16]
|
||||
// CHECK:STDOUT: %.loc20_7: ref %C = splice_block %c.var {}
|
||||
// CHECK:STDOUT: %Make.call.loc20: init %C = call %Make.ref.loc20() to %.loc20_7
|
||||
// CHECK:STDOUT: %Make.call.loc20: init %C = call %.loc20_21.2() to %.loc20_7
|
||||
// CHECK:STDOUT: assign %c.var, %Make.call.loc20
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc11_12.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type => constants.%Make.type.1
|
||||
// CHECK:STDOUT: %Make => constants.%Make.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type => constants.%Make.type.1
|
||||
// CHECK:STDOUT: %Make => constants.%Make.1
|
||||
// CHECK:STDOUT: %.loc12_27.3 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(@Wrap.%T.loc11_12.2) {
|
||||
// CHECK:STDOUT: %T.loc11_12.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(@Make.%T) {
|
||||
// CHECK:STDOUT: %T.loc11_12.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(@Make.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(i32) {
|
||||
// CHECK:STDOUT: %T.loc11_12.2 => i32
|
||||
// CHECK:STDOUT:
|
||||
@@ -196,6 +234,11 @@ fn G() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(i32) {
|
||||
// CHECK:STDOUT: %T => i32
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type => constants.%Make.type.2
|
||||
// CHECK:STDOUT: %Make => constants.%Make.2
|
||||
// CHECK:STDOUT: %.loc12_27.3 => constants.%.12
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(constants.%.1) {
|
||||
@@ -208,6 +251,11 @@ fn G() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(constants.%.1) {
|
||||
// CHECK:STDOUT: %T => constants.%.1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type => constants.%Make.type.3
|
||||
// CHECK:STDOUT: %Make => constants.%Make.3
|
||||
// CHECK:STDOUT: %.loc12_27.3 => constants.%.13
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Wrap(constants.%C) {
|
||||
@@ -220,5 +268,10 @@ fn G() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Make(constants.%C) {
|
||||
// CHECK:STDOUT: %T => constants.%C
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Make.type => constants.%Make.type.4
|
||||
// CHECK:STDOUT: %Make => constants.%Make.4
|
||||
// CHECK:STDOUT: %.loc12_27.3 => constants.%.16
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/generic/undefined.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/generic/undefined.carbon
|
||||
|
||||
// --- call_defined.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Defined[T:! type](x: T) -> T {
|
||||
return x;
|
||||
}
|
||||
|
||||
fn CallDefined() -> i32 {
|
||||
return Defined(0);
|
||||
}
|
||||
|
||||
// --- call_defined_late.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Defined[T:! type](x: T) -> T;
|
||||
|
||||
fn CallDefined() -> i32 {
|
||||
return Defined(0);
|
||||
}
|
||||
|
||||
fn Defined[T:! type](x: T) -> T {
|
||||
return x;
|
||||
}
|
||||
|
||||
// --- fail_call_undefined.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Undefined[T:! type](x: T) -> T;
|
||||
|
||||
fn CallUndefined() -> i32 {
|
||||
// CHECK:STDERR: fail_call_undefined.carbon:[[@LINE+6]]:10: error: use of undefined generic function
|
||||
// CHECK:STDERR: return Undefined(0);
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_call_undefined.carbon:[[@LINE-6]]:1: note: generic function declared here
|
||||
// CHECK:STDERR: fn Undefined[T:! type](x: T) -> T;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
return Undefined(0);
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- call_defined.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Defined.type: type = fn_type @Defined [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %Defined: %Defined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %CallDefined.type: type = fn_type @CallDefined [template]
|
||||
// CHECK:STDOUT: %CallDefined: %CallDefined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %Defined, @Defined(i32) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Int32 = %import_ref
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Defined = %Defined.decl
|
||||
// CHECK:STDOUT: .CallDefined = %CallDefined.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Defined.decl: %Defined.type = fn_decl @Defined [template = constants.%Defined] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: @Defined.%T.loc4_12.2 (%T) = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc4_12.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc4_25: type = name_ref T, %T.loc4_12.1 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %x.param: @Defined.%T.loc4_12.2 (%T) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @Defined.%T.loc4_12.2 (%T) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %T.ref.loc4_31: type = name_ref T, %T.loc4_12.1 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @Defined.%T.loc4_12.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallDefined.decl: %CallDefined.type = fn_decl @CallDefined [template = constants.%CallDefined] {} {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc8_21.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc8_21.2: type = converted %int.make_type_32, %.loc8_21.1 [template = i32]
|
||||
// CHECK:STDOUT: %return: ref i32 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Defined(%T.loc4_12.1: type) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_12.1: type](%x: @Defined.%T.loc4_12.2 (%T)) -> @Defined.%T.loc4_12.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: @Defined.%T.loc4_12.2 (%T) = name_ref x, %x
|
||||
// CHECK:STDOUT: return %x.ref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallDefined() -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Defined.ref: %Defined.type = name_ref Defined, file.%Defined.decl [template = constants.%Defined]
|
||||
// CHECK:STDOUT: %.loc9_18: i32 = int_literal 0 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc9_10: <specific function> = specific_function %Defined.ref, @Defined(i32) [template = constants.%.3]
|
||||
// CHECK:STDOUT: %Defined.call: init i32 = call %.loc9_10(%.loc9_18)
|
||||
// CHECK:STDOUT: %.loc9_20.1: i32 = value_of_initializer %Defined.call
|
||||
// CHECK:STDOUT: %.loc9_20.2: i32 = converted %Defined.call, %.loc9_20.1
|
||||
// CHECK:STDOUT: return %.loc9_20.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Defined(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Defined(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2 => i32
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- call_defined_late.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Defined.type: type = fn_type @Defined [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %Defined: %Defined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %CallDefined.type: type = fn_type @CallDefined [template]
|
||||
// CHECK:STDOUT: %CallDefined: %CallDefined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %Defined, @Defined(i32) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Int32 = %import_ref
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Defined = %Defined.decl.loc4
|
||||
// CHECK:STDOUT: .CallDefined = %CallDefined.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Defined.decl.loc4: %Defined.type = fn_decl @Defined [template = constants.%Defined] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: %T = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param.loc4: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc4_12.1: type = bind_symbolic_name T, 0, %T.param.loc4 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc4_25: type = name_ref T, %T.loc4_12.1 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %x.param.loc4: @Defined.%T.loc4_12.2 (%T) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x.loc4: @Defined.%T.loc4_12.2 (%T) = bind_name x, %x.param.loc4
|
||||
// CHECK:STDOUT: %T.ref.loc4_31: type = name_ref T, %T.loc4_12.1 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return.var.loc4: ref @Defined.%T.loc4_12.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallDefined.decl: %CallDefined.type = fn_decl @CallDefined [template = constants.%CallDefined] {} {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_21.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_21.2: type = converted %int.make_type_32, %.loc6_21.1 [template = i32]
|
||||
// CHECK:STDOUT: %return: ref i32 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Defined.decl.loc10: %Defined.type = fn_decl @Defined [template = constants.%Defined] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: %T = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param.loc10: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc10: type = bind_symbolic_name T, 0, %T.param.loc10 [symbolic = constants.%T]
|
||||
// CHECK:STDOUT: %T.ref.loc10_25: type = name_ref T, %T.loc10 [symbolic = constants.%T]
|
||||
// CHECK:STDOUT: %x.param.loc10: %T = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x.loc10: %T = bind_name x, %x.param.loc10
|
||||
// CHECK:STDOUT: %T.ref.loc10_31: type = name_ref T, %T.loc10 [symbolic = constants.%T]
|
||||
// CHECK:STDOUT: %return: ref %T = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Defined(%T.loc4_12.1: type) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_12.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc10: type](%x.loc10: %T) -> %T {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: @Defined.%T.loc4_12.2 (%T) = name_ref x, %x.loc10
|
||||
// CHECK:STDOUT: return %x.ref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallDefined() -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Defined.ref: %Defined.type = name_ref Defined, file.%Defined.decl.loc4 [template = constants.%Defined]
|
||||
// CHECK:STDOUT: %.loc7_18: i32 = int_literal 0 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc7_10: <specific function> = specific_function %Defined.ref, @Defined(i32) [template = constants.%.3]
|
||||
// CHECK:STDOUT: %Defined.call: init i32 = call %.loc7_10(%.loc7_18)
|
||||
// CHECK:STDOUT: %.loc7_20.1: i32 = value_of_initializer %Defined.call
|
||||
// CHECK:STDOUT: %.loc7_20.2: i32 = converted %Defined.call, %.loc7_20.1
|
||||
// CHECK:STDOUT: return %.loc7_20.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Defined(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Defined(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_12.2 => i32
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_call_undefined.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Undefined.type: type = fn_type @Undefined [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %Undefined: %Undefined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
|
||||
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %CallUndefined.type: type = fn_type @CallUndefined [template]
|
||||
// CHECK:STDOUT: %CallUndefined: %CallUndefined.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.2: i32 = int_literal 0 [template]
|
||||
// CHECK:STDOUT: %.3: <specific function> = specific_function %Undefined, @Undefined(i32) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Int32 = %import_ref
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/operators
|
||||
// CHECK:STDOUT: import Core//prelude/types
|
||||
// CHECK:STDOUT: import Core//prelude/operators/arithmetic
|
||||
// CHECK:STDOUT: import Core//prelude/operators/as
|
||||
// CHECK:STDOUT: import Core//prelude/operators/bitwise
|
||||
// CHECK:STDOUT: import Core//prelude/operators/comparison
|
||||
// CHECK:STDOUT: import Core//prelude/types/bool
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Undefined = %Undefined.decl
|
||||
// CHECK:STDOUT: .CallUndefined = %CallUndefined.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Undefined.decl: %Undefined.type = fn_decl @Undefined [template = constants.%Undefined] {
|
||||
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0
|
||||
// CHECK:STDOUT: %x.patt: @Undefined.%T.loc4_14.2 (%T) = binding_pattern x
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc4_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc4_27: type = name_ref T, %T.loc4_14.1 [symbolic = %T.loc4_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %x.param: @Undefined.%T.loc4_14.2 (%T) = param x, runtime_param0
|
||||
// CHECK:STDOUT: %x: @Undefined.%T.loc4_14.2 (%T) = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %T.ref.loc4_33: type = name_ref T, %T.loc4_14.1 [symbolic = %T.loc4_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @Undefined.%T.loc4_14.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %CallUndefined.decl: %CallUndefined.type = fn_decl @CallUndefined [template = constants.%CallUndefined] {} {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_23.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc6_23.2: type = converted %int.make_type_32, %.loc6_23.1 [template = i32]
|
||||
// CHECK:STDOUT: %return: ref i32 = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Undefined(%T.loc4_14.1: type) {
|
||||
// CHECK:STDOUT: %T.loc4_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_14.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.loc4_14.1: type](%x: @Undefined.%T.loc4_14.2 (%T)) -> @Undefined.%T.loc4_14.2 (%T);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @CallUndefined() -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Undefined.ref: %Undefined.type = name_ref Undefined, file.%Undefined.decl [template = constants.%Undefined]
|
||||
// CHECK:STDOUT: %.loc13_20: i32 = int_literal 0 [template = constants.%.2]
|
||||
// CHECK:STDOUT: %.loc13_10: <specific function> = specific_function %Undefined.ref, @Undefined(i32) [template = constants.%.3]
|
||||
// CHECK:STDOUT: %Undefined.call: init i32 = call %.loc13_10(%.loc13_20)
|
||||
// CHECK:STDOUT: %.loc13_22.1: i32 = value_of_initializer %Undefined.call
|
||||
// CHECK:STDOUT: %.loc13_22.2: i32 = converted %Undefined.call, %.loc13_22.1
|
||||
// CHECK:STDOUT: return %.loc13_22.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Undefined(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc4_14.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Undefined(i32) {
|
||||
// CHECK:STDOUT: %T.loc4_14.2 => i32
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
+25
-10
@@ -141,6 +141,7 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %F.type.3: type = fn_type @F.2, @impl(%.5) [template]
|
||||
// CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.6: <witness> = interface_witness (%F.3) [template]
|
||||
// CHECK:STDOUT: %.7: <specific function> = specific_function %F.3, @F.2(%.5) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -230,8 +231,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %x.ref: %.5 = name_ref x, %x
|
||||
// CHECK:STDOUT: %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
|
||||
// CHECK:STDOUT: %F.ref: %.2 = name_ref F, @HasF.%.loc5 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc13: %F.type.1 = interface_witness_access constants.%.6, element0 [template = constants.%F.3]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc13()
|
||||
// CHECK:STDOUT: %.loc13_4.1: %F.type.1 = interface_witness_access constants.%.6, element0 [template = constants.%F.3]
|
||||
// CHECK:STDOUT: %.loc13_4.2: <specific function> = specific_function %.loc13_4.1, @F.2(constants.%.5) [template = constants.%.7]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc13_4.2()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -263,7 +265,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %.loc8_34.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.5) {}
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.5) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- deduced_type_subst.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -404,7 +408,8 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %F.ref: %.2 = name_ref F, @HasF.%.loc5 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc13_11.1: %F.type.1 = interface_witness_access constants.%.6, element0 [template = constants.%F.3]
|
||||
// CHECK:STDOUT: %.loc13_11.2: <bound method> = bound_method %x.ref, %.loc13_11.1
|
||||
// CHECK:STDOUT: %F.call: init %.5 = call %.loc13_11.2(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_11.3: <specific function> = specific_function %.loc13_11.2, @F.2(constants.%.5)
|
||||
// CHECK:STDOUT: %F.call: init %.5 = call %.loc13_11.3(%x.ref)
|
||||
// CHECK:STDOUT: %.loc13_20.1: ref %.5 = temporary_storage
|
||||
// CHECK:STDOUT: %.loc13_20.2: ref %.5 = temporary %.loc13_20.1, %F.call
|
||||
// CHECK:STDOUT: %struct: %.5 = struct_value () [template = constants.%struct]
|
||||
@@ -448,6 +453,8 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.5) {
|
||||
// CHECK:STDOUT: %T => constants.%.5
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- deduced_type_argument.carbon
|
||||
@@ -476,6 +483,7 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %F.type.3: type = fn_type @F.2, @impl(%.4) [template]
|
||||
// CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: <witness> = interface_witness (%F.3) [template]
|
||||
// CHECK:STDOUT: %.9: <specific function> = specific_function %F.3, @F.2(%.4) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -590,8 +598,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %x.ref: %C.3 = name_ref x, %x
|
||||
// CHECK:STDOUT: %HasF.ref: type = name_ref HasF, file.%HasF.decl [template = constants.%HasF.type]
|
||||
// CHECK:STDOUT: %F.ref: %.2 = name_ref F, @HasF.%.loc5 [template = constants.%.3]
|
||||
// CHECK:STDOUT: %.loc15: %F.type.1 = interface_witness_access constants.%.8, element0 [template = constants.%F.3]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc15()
|
||||
// CHECK:STDOUT: %.loc15_4.1: %F.type.1 = interface_witness_access constants.%.8, element0 [template = constants.%F.3]
|
||||
// CHECK:STDOUT: %.loc15_4.2: <specific function> = specific_function %.loc15_4.1, @F.2(constants.%.4) [template = constants.%.9]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc15_4.2()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -640,7 +649,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %.loc10_37.2 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.4) {}
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.4) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- deduced_interface_argument.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -669,6 +680,7 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %F.type.4: type = fn_type @F.2, @impl(%.4) [template]
|
||||
// CHECK:STDOUT: %F.4: %F.type.4 = struct_value () [template]
|
||||
// CHECK:STDOUT: %.8: <witness> = interface_witness (%F.4) [template]
|
||||
// CHECK:STDOUT: %.9: <specific function> = specific_function %F.4, @F.2(%.4) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -783,8 +795,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %HasF.type: type = interface_type @HasF, @HasF(constants.%.4) [template = constants.%HasF.type.3]
|
||||
// CHECK:STDOUT: %.loc13_14: %.6 = specific_constant @HasF.%.loc5_9.1, @HasF(constants.%.4) [template = constants.%.7]
|
||||
// CHECK:STDOUT: %F.ref: %.6 = name_ref F, %.loc13_14 [template = constants.%.7]
|
||||
// CHECK:STDOUT: %.loc13_4: %F.type.3 = interface_witness_access constants.%.8, element0 [template = constants.%F.4]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc13_4()
|
||||
// CHECK:STDOUT: %.loc13_4.1: %F.type.3 = interface_witness_access constants.%.8, element0 [template = constants.%F.4]
|
||||
// CHECK:STDOUT: %.loc13_4.2: <specific function> = specific_function %.loc13_4.1, @F.2(constants.%.4) [template = constants.%.9]
|
||||
// CHECK:STDOUT: %F.call: init %.1 = call %.loc13_4.2()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -851,7 +864,9 @@ fn G(x: A) {
|
||||
// CHECK:STDOUT: %.loc8_38.2 => constants.%.8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.4) {}
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.4) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_incomplete_deduction.carbon
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -291,7 +291,8 @@ fn TestSpecific(a: A({})) -> {} {
|
||||
// CHECK:STDOUT: %F.ref: @TestGeneric.%.loc17_17.2 (%.18) = name_ref F, %.loc17_17.1 [symbolic = %.loc17_17.3 (constants.%.19)]
|
||||
// CHECK:STDOUT: %.loc17_11.1: @TestGeneric.%F.type.loc17_17 (%F.type.4) = interface_witness_access constants.%.20, element0 [symbolic = %F (constants.%F.5)]
|
||||
// CHECK:STDOUT: %.loc17_11.2: <bound method> = bound_method %a.ref, %.loc17_11.1
|
||||
// CHECK:STDOUT: %F.call: init @TestGeneric.%W.loc16_16.2 (%W) = call %.loc17_11.2(%a.ref)
|
||||
// CHECK:STDOUT: %.loc17_11.3: <specific function> = specific_function %.loc17_11.2, @F.2(constants.%W)
|
||||
// CHECK:STDOUT: %F.call: init @TestGeneric.%W.loc16_16.2 (%W) = call %.loc17_11.3(%a.ref)
|
||||
// CHECK:STDOUT: %.loc17_22.1: @TestGeneric.%W.loc16_16.2 (%W) = value_of_initializer %F.call
|
||||
// CHECK:STDOUT: %.loc17_22.2: @TestGeneric.%W.loc16_16.2 (%W) = converted %F.call, %.loc17_22.1
|
||||
// CHECK:STDOUT: return %.loc17_22.2
|
||||
@@ -309,7 +310,8 @@ fn TestSpecific(a: A({})) -> {} {
|
||||
// CHECK:STDOUT: %F.ref: %.27 = name_ref F, %.loc21_18 [template = constants.%.28]
|
||||
// CHECK:STDOUT: %.loc21_11.1: %F.type.6 = interface_witness_access constants.%.29, element0 [template = constants.%F.7]
|
||||
// CHECK:STDOUT: %.loc21_11.2: <bound method> = bound_method %a.ref, %.loc21_11.1
|
||||
// CHECK:STDOUT: %F.call: init %.21 = call %.loc21_11.2(%a.ref)
|
||||
// CHECK:STDOUT: %.loc21_11.3: <specific function> = specific_function %.loc21_11.2, @F.2(constants.%.21)
|
||||
// CHECK:STDOUT: %F.call: init %.21 = call %.loc21_11.3(%a.ref)
|
||||
// CHECK:STDOUT: %.loc21_21.1: ref %.21 = temporary_storage
|
||||
// CHECK:STDOUT: %.loc21_21.2: ref %.21 = temporary %.loc21_21.1, %F.call
|
||||
// CHECK:STDOUT: %struct: %.21 = struct_value () [template = constants.%struct]
|
||||
@@ -450,6 +452,9 @@ fn TestSpecific(a: A({})) -> {} {
|
||||
// CHECK:STDOUT: specific @F.2(constants.%W) {
|
||||
// CHECK:STDOUT: %V => constants.%W
|
||||
// CHECK:STDOUT: %A => constants.%A.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc12_16.3 => constants.%.14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I(@TestGeneric.%W.loc16_16.2) {
|
||||
@@ -498,5 +503,8 @@ fn TestSpecific(a: A({})) -> {} {
|
||||
// CHECK:STDOUT: specific @F.2(constants.%.21) {
|
||||
// CHECK:STDOUT: %V => constants.%.21
|
||||
// CHECK:STDOUT: %A => constants.%A.5
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc12_16.3 => constants.%.22
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+27
-11
@@ -33,15 +33,20 @@ fn H() {
|
||||
// CHECK:STDOUT: %I.type.2: type = interface_type @I, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Self: %I.type.2 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %U: type = bind_symbolic_name U, 2 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.2: type = assoc_entity_type %I.type.2, %F.type [symbolic]
|
||||
// CHECK:STDOUT: %F.type.1: type = fn_type @F, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %F: %F.type.1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.2: type = assoc_entity_type %I.type.2, %F.type.1 [symbolic]
|
||||
// CHECK:STDOUT: %.3: %.2 = assoc_entity element0, @I.%F.decl [symbolic]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %H.type: type = fn_type @H [template]
|
||||
// CHECK:STDOUT: %H: %H.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.4: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %.5: <specific function> = specific_function %G, @G(%.4) [template]
|
||||
// CHECK:STDOUT: %I.type.3: type = interface_type @I, @I(%.4) [template]
|
||||
// CHECK:STDOUT: %F.type.2: type = fn_type @F, @I(%.4) [template]
|
||||
// CHECK:STDOUT: %.6: type = assoc_entity_type %I.type.3, %F.type.2 [template]
|
||||
// CHECK:STDOUT: %.7: %.6 = assoc_entity element0, @I.%F.decl [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -71,14 +76,14 @@ fn H() {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %I.type: type = interface_type @I, @I(%T.loc11_13.2) [symbolic = %I.type (constants.%I.type.2)]
|
||||
// CHECK:STDOUT: %Self.2: %I.type.2 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type)]
|
||||
// CHECK:STDOUT: %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
|
||||
// CHECK:STDOUT: %.loc12_22.2: type = assoc_entity_type @I.%I.type (%I.type.2), @I.%F.type (%F.type) [symbolic = %.loc12_22.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc11_13.2) [symbolic = %F.type (constants.%F.type.1)]
|
||||
// CHECK:STDOUT: %F: @I.%F.type (%F.type.1) = struct_value () [symbolic = %F (constants.%F)]
|
||||
// CHECK:STDOUT: %.loc12_22.2: type = assoc_entity_type @I.%I.type (%I.type.2), @I.%F.type (%F.type.1) [symbolic = %.loc12_22.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc12_22.3: @I.%.loc12_22.2 (%.2) = assoc_entity element0, %F.decl [symbolic = %.loc12_22.3 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: %Self.1: @I.%I.type (%I.type.2) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)]
|
||||
// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = @I.%F (constants.%F)] {
|
||||
// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type.1) = fn_decl @F [symbolic = @I.%F (constants.%F)] {
|
||||
// CHECK:STDOUT: %U.patt: type = symbolic_binding_pattern U, 2
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %U.param: type = param U, runtime_param<invalid>
|
||||
@@ -106,8 +111,8 @@ fn H() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %I.type.loc19_4.2: type = interface_type @I, @I(%T.loc15_6.2) [symbolic = %I.type.loc19_4.2 (constants.%I.type.2)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc15_6.2) [symbolic = %F.type (constants.%F.type)]
|
||||
// CHECK:STDOUT: %.loc19_7.2: type = assoc_entity_type @G.%I.type.loc19_4.2 (%I.type.2), @G.%F.type (%F.type) [symbolic = %.loc19_7.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T.loc15_6.2) [symbolic = %F.type (constants.%F.type.1)]
|
||||
// CHECK:STDOUT: %.loc19_7.2: type = assoc_entity_type @G.%I.type.loc19_4.2 (%I.type.2), @G.%F.type (%F.type.1) [symbolic = %.loc19_7.2 (constants.%.2)]
|
||||
// CHECK:STDOUT: %.loc19_7.3: @G.%.loc19_7.2 (%.2) = assoc_entity element0, @I.%F.decl [symbolic = %.loc19_7.3 (constants.%.3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc15_6.1: type) {
|
||||
@@ -126,7 +131,8 @@ fn H() {
|
||||
// CHECK:STDOUT: %G.ref: %G.type = name_ref G, file.%G.decl [template = constants.%G]
|
||||
// CHECK:STDOUT: %.loc23_6: %.4 = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc23_4: type = converted %.loc23_6, constants.%.4 [template = constants.%.4]
|
||||
// CHECK:STDOUT: %G.call: init %.1 = call %G.ref()
|
||||
// CHECK:STDOUT: %.loc23_3: <specific function> = specific_function %G.ref, @G(constants.%.4) [template = constants.%.5]
|
||||
// CHECK:STDOUT: %G.call: init %.1 = call %.loc23_3()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -136,7 +142,7 @@ fn H() {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %I.type => constants.%I.type.2
|
||||
// CHECK:STDOUT: %Self.2 => constants.%Self
|
||||
// CHECK:STDOUT: %F.type => constants.%F.type
|
||||
// CHECK:STDOUT: %F.type => constants.%F.type.1
|
||||
// CHECK:STDOUT: %F => constants.%F
|
||||
// CHECK:STDOUT: %.loc12_22.2 => constants.%.2
|
||||
// CHECK:STDOUT: %.loc12_22.3 => constants.%.3
|
||||
@@ -160,5 +166,15 @@ fn H() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @G(constants.%.4) {
|
||||
// CHECK:STDOUT: %T.loc15_6.2 => constants.%.4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %I.type.loc19_4.2 => constants.%I.type.3
|
||||
// CHECK:STDOUT: %F.type => constants.%F.type.2
|
||||
// CHECK:STDOUT: %.loc19_7.2 => constants.%.6
|
||||
// CHECK:STDOUT: %.loc19_7.3 => constants.%.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I(constants.%.4) {
|
||||
// CHECK:STDOUT: %T.loc11_13.2 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -32,7 +32,7 @@ class C {
|
||||
|
||||
interface WithImplicitArgs[T:! type](N:! T);
|
||||
|
||||
fn Receive(T:! Simple(C));
|
||||
fn Receive(T:! Simple(C)) {}
|
||||
fn Pass(T:! Simple(C)) {
|
||||
Receive(T);
|
||||
}
|
||||
@@ -99,6 +99,7 @@ fn G(T:! Generic(B)) {
|
||||
// CHECK:STDOUT: %Receive: %Receive.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %Pass.type: type = fn_type @Pass [template]
|
||||
// CHECK:STDOUT: %Pass: %Pass.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.11: <specific function> = specific_function %Receive, @Receive(%T.2) [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -265,19 +266,26 @@ fn G(T:! Generic(B)) {
|
||||
// CHECK:STDOUT: generic fn @Receive(%T.loc24_12.1: %Simple.type.3) {
|
||||
// CHECK:STDOUT: %T.loc24_12.2: %Simple.type.3 = bind_symbolic_name T, 0 [symbolic = %T.loc24_12.2 (constants.%T.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc24_12.1: %Simple.type.3);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc24_12.1: %Simple.type.3) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Pass(%T.loc25_9.1: %Simple.type.3) {
|
||||
// CHECK:STDOUT: %T.loc25_9.2: %Simple.type.3 = bind_symbolic_name T, 0 [symbolic = %T.loc25_9.2 (constants.%T.2)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc26_3.2: <specific function> = specific_function constants.%Receive, @Receive(%T.loc25_9.2) [symbolic = %.loc26_3.2 (constants.%.11)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc25_9.1: %Simple.type.3) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Receive.ref: %Receive.type = name_ref Receive, file.%Receive.decl [template = constants.%Receive]
|
||||
// CHECK:STDOUT: %T.ref: %Simple.type.3 = name_ref T, %T.loc25_9.1 [symbolic = %T.loc25_9.2 (constants.%T.2)]
|
||||
// CHECK:STDOUT: %Receive.call: init %.1 = call %Receive.ref()
|
||||
// CHECK:STDOUT: %.loc26_3.1: <specific function> = specific_function %Receive.ref, @Receive(constants.%T.2) [symbolic = %.loc26_3.2 (constants.%.11)]
|
||||
// CHECK:STDOUT: %Receive.call: init %.1 = call %.loc26_3.1()
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -329,12 +337,18 @@ fn G(T:! Generic(B)) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Receive(constants.%T.2) {
|
||||
// CHECK:STDOUT: %T.loc24_12.2 => constants.%T.2
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Pass(constants.%T.2) {
|
||||
// CHECK:STDOUT: %T.loc25_9.2 => constants.%T.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Receive(@Pass.%T.loc25_9.2) {
|
||||
// CHECK:STDOUT: %T.loc24_12.2 => constants.%T.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_mismatched_args.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
|
||||
@@ -24,7 +24,7 @@ impl X as Core.ImplicitAs(i32) {
|
||||
// ... once we stop deducing `T` from the type of the second argument in this case.
|
||||
fn Sink_i32(n: i32);
|
||||
fn Sink_X(x: X);
|
||||
fn Source(T:! type) -> T;
|
||||
fn Source(T:! type) -> T { return Source(T); }
|
||||
|
||||
fn Test() {
|
||||
Sink_i32(Source(X));
|
||||
@@ -75,9 +75,12 @@ fn Test() {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Source.type: type = fn_type @Source [template]
|
||||
// CHECK:STDOUT: %Source: %Source.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.14: <specific function> = specific_function %Source, @Source(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Test.type: type = fn_type @Test [template]
|
||||
// CHECK:STDOUT: %Test: %Test.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %.14: %.5 = assoc_entity element0, imports.%import_ref.7 [symbolic]
|
||||
// CHECK:STDOUT: %.15: <specific function> = specific_function %Source, @Source(%X) [template]
|
||||
// CHECK:STDOUT: %.16: %.5 = assoc_entity element0, imports.%import_ref.7 [symbolic]
|
||||
// CHECK:STDOUT: %.17: <specific function> = specific_function %Source, @Source(i32) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -96,7 +99,7 @@ fn Test() {
|
||||
// CHECK:STDOUT: %import_ref.1: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32]
|
||||
// CHECK:STDOUT: %import_ref.2: %ImplicitAs.type.1 = import_ref Core//prelude/operators/as, inst+40, loaded [template = constants.%ImplicitAs]
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref Core//prelude/operators/as, inst+45, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4: @ImplicitAs.%.1 (%.5) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.14)]
|
||||
// CHECK:STDOUT: %import_ref.4: @ImplicitAs.%.1 (%.5) = import_ref Core//prelude/operators/as, inst+63, loaded [symbolic = @ImplicitAs.%.2 (constants.%.16)]
|
||||
// CHECK:STDOUT: %import_ref.5: @ImplicitAs.%Convert.type (%Convert.type.1) = import_ref Core//prelude/operators/as, inst+56, loaded [symbolic = @ImplicitAs.%Convert (constants.%Convert.1)]
|
||||
// CHECK:STDOUT: %import_ref.6 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
// CHECK:STDOUT: %import_ref.7 = import_ref Core//prelude/operators/as, inst+56, unloaded
|
||||
@@ -152,7 +155,7 @@ fn Test() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %T.param: type = param T, runtime_param<invalid>
|
||||
// CHECK:STDOUT: %T.loc27_11.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc27_11.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc27_11.1 [symbolic = %T.loc27_11.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %T.ref.loc27_24: type = name_ref T, %T.loc27_11.1 [symbolic = %T.loc27_11.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %return: ref @Source.%T.loc27_11.2 (%T) = var <return slot>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Test.decl: %Test.type = fn_decl @Test [template = constants.%Test] {} {}
|
||||
@@ -264,7 +267,19 @@ fn Test() {
|
||||
// CHECK:STDOUT: generic fn @Source(%T.loc27_11.1: type) {
|
||||
// CHECK:STDOUT: %T.loc27_11.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc27_11.2 (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc27_11.1: type) -> @Source.%T.loc27_11.2 (%T);
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc27_35.2: <specific function> = specific_function constants.%Source, @Source(%T.loc27_11.2) [symbolic = %.loc27_35.2 (constants.%.14)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%T.loc27_11.1: type) -> @Source.%T.loc27_11.2 (%T) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Source.ref: %Source.type = name_ref Source, file.%Source.decl [template = constants.%Source]
|
||||
// CHECK:STDOUT: %T.ref.loc27_42: type = name_ref T, %T.loc27_11.1 [symbolic = %T.loc27_11.2 (constants.%T)]
|
||||
// CHECK:STDOUT: %.loc27_35.1: <specific function> = specific_function %Source.ref, @Source(constants.%T) [symbolic = %.loc27_35.2 (constants.%.14)]
|
||||
// CHECK:STDOUT: %Source.call: init @Source.%T.loc27_11.2 (%T) = call %.loc27_35.1()
|
||||
// CHECK:STDOUT: %.loc27_44.1: @Source.%T.loc27_11.2 (%T) = value_of_initializer %Source.call
|
||||
// CHECK:STDOUT: %.loc27_44.2: @Source.%T.loc27_11.2 (%T) = converted %Source.call, %.loc27_44.1
|
||||
// CHECK:STDOUT: return %.loc27_44.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Test() {
|
||||
@@ -272,8 +287,9 @@ fn Test() {
|
||||
// CHECK:STDOUT: %Sink_i32.ref: %Sink_i32.type = name_ref Sink_i32, file.%Sink_i32.decl [template = constants.%Sink_i32]
|
||||
// CHECK:STDOUT: %Source.ref.loc30: %Source.type = name_ref Source, file.%Source.decl [template = constants.%Source]
|
||||
// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [template = constants.%X]
|
||||
// CHECK:STDOUT: %.loc30_12: <specific function> = specific_function %Source.ref.loc30, @Source(constants.%X) [template = constants.%.15]
|
||||
// CHECK:STDOUT: %.loc30_18.1: ref %X = temporary_storage
|
||||
// CHECK:STDOUT: %Source.call.loc30: init %X = call %Source.ref.loc30() to %.loc30_18.1
|
||||
// CHECK:STDOUT: %Source.call.loc30: init %X = call %.loc30_12() to %.loc30_18.1
|
||||
// CHECK:STDOUT: %ImplicitAs.type.loc30: type = interface_type @ImplicitAs, @ImplicitAs(i32) [template = constants.%ImplicitAs.type.4]
|
||||
// CHECK:STDOUT: %.loc30_11.1: %.11 = specific_constant imports.%import_ref.4, @ImplicitAs(i32) [template = constants.%.12]
|
||||
// CHECK:STDOUT: %Convert.ref.loc30: %.11 = name_ref Convert, %.loc30_11.1 [template = constants.%.12]
|
||||
@@ -292,7 +308,8 @@ fn Test() {
|
||||
// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32]
|
||||
// CHECK:STDOUT: %.loc31_16.1: type = value_of_initializer %int.make_type_32 [template = i32]
|
||||
// CHECK:STDOUT: %.loc31_16.2: type = converted %int.make_type_32, %.loc31_16.1 [template = i32]
|
||||
// CHECK:STDOUT: %Source.call.loc31: init i32 = call %Source.ref.loc31()
|
||||
// CHECK:STDOUT: %.loc31_10: <specific function> = specific_function %Source.ref.loc31, @Source(i32) [template = constants.%.17]
|
||||
// CHECK:STDOUT: %Source.call.loc31: init i32 = call %.loc31_10()
|
||||
// CHECK:STDOUT: %ImplicitAs.type.loc31: type = interface_type @ImplicitAs, @ImplicitAs(constants.%X) [template = constants.%ImplicitAs.type.3]
|
||||
// CHECK:STDOUT: %.loc31_9.1: %.7 = specific_constant imports.%import_ref.4, @ImplicitAs(constants.%X) [template = constants.%.8]
|
||||
// CHECK:STDOUT: %Convert.ref.loc31: %.7 = name_ref Convert, %.loc31_9.1 [template = constants.%.8]
|
||||
@@ -366,13 +383,26 @@ fn Test() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Source(constants.%T) {
|
||||
// CHECK:STDOUT: %T.loc27_11.2 => constants.%T
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc27_35.2 => constants.%.14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Source(@Source.%T.loc27_11.2) {
|
||||
// CHECK:STDOUT: %T.loc27_11.2 => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Source(constants.%X) {
|
||||
// CHECK:STDOUT: %T.loc27_11.2 => constants.%X
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc27_35.2 => constants.%.15
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Source(i32) {
|
||||
// CHECK:STDOUT: %T.loc27_11.2 => i32
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %.loc27_35.2 => constants.%.17
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -159,6 +159,8 @@ CARBON_DIAGNOSTIC_KIND(RepeatedImport)
|
||||
CARBON_DIAGNOSTIC_KIND(FirstImported)
|
||||
CARBON_DIAGNOSTIC_KIND(ExportFromImpl)
|
||||
CARBON_DIAGNOSTIC_KIND(MissingDefinitionInImpl)
|
||||
CARBON_DIAGNOSTIC_KIND(MissingGenericFunctionDefinition)
|
||||
CARBON_DIAGNOSTIC_KIND(MissingGenericFunctionDefinitionHere)
|
||||
|
||||
// Merge-related redeclaration checking.
|
||||
CARBON_DIAGNOSTIC_KIND(RedeclPrevDecl)
|
||||
|
||||
@@ -215,6 +215,11 @@ static auto EmitAsConstant(ConstantContext& context, SemIR::Namespace inst)
|
||||
return context.GetUnusedConstant(inst.type_id);
|
||||
}
|
||||
|
||||
static auto EmitAsConstant(ConstantContext& /*context*/,
|
||||
SemIR::SpecificFunction inst) -> llvm::Constant* {
|
||||
CARBON_FATAL("TODO: Add support: {0}", inst);
|
||||
}
|
||||
|
||||
static auto EmitAsConstant(ConstantContext& /*context*/,
|
||||
SemIR::StringLiteral inst) -> llvm::Constant* {
|
||||
CARBON_FATAL("TODO: Add support: {0}", inst);
|
||||
|
||||
@@ -412,6 +412,7 @@ static auto BuildTypeForInst(FileContext& context, SemIR::BuiltinInst inst)
|
||||
// storage
|
||||
// (`i8`) versus for `bool` values (`i1`).
|
||||
return llvm::Type::getInt1Ty(context.llvm_context());
|
||||
case SemIR::BuiltinInstKind::SpecificFunctionType:
|
||||
case SemIR::BuiltinInstKind::StringType:
|
||||
// TODO: Decide how we want to represent `StringType`.
|
||||
return llvm::PointerType::get(context.llvm_context(), 0);
|
||||
|
||||
@@ -67,6 +67,9 @@ CARBON_SEM_IR_BUILTIN_INST_KIND(StringType, "String")
|
||||
// The type of bound method values.
|
||||
CARBON_SEM_IR_BUILTIN_INST_KIND(BoundMethodType, "<bound method>")
|
||||
|
||||
// The type of specific functions.
|
||||
CARBON_SEM_IR_BUILTIN_INST_KIND(SpecificFunctionType, "<specific function>")
|
||||
|
||||
// The type of namespace and imported package names.
|
||||
CARBON_SEM_IR_BUILTIN_INST_KIND(NamespaceType, "<namespace>")
|
||||
|
||||
|
||||
@@ -270,6 +270,7 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
|
||||
case IntType::Kind:
|
||||
case Param::Kind:
|
||||
case PointerType::Kind:
|
||||
case SpecificFunction::Kind:
|
||||
case StringLiteral::Kind:
|
||||
case StructValue::Kind:
|
||||
case StructType::Kind:
|
||||
|
||||
@@ -12,10 +12,17 @@ namespace Carbon::SemIR {
|
||||
|
||||
auto GetCalleeFunction(const File& sem_ir, InstId callee_id) -> CalleeFunction {
|
||||
CalleeFunction result = {.function_id = FunctionId::Invalid,
|
||||
.specific_id = SpecificId::Invalid,
|
||||
.enclosing_specific_id = SpecificId::Invalid,
|
||||
.resolved_specific_id = SpecificId::Invalid,
|
||||
.self_id = InstId::Invalid,
|
||||
.is_error = false};
|
||||
|
||||
if (auto specific_function =
|
||||
sem_ir.insts().TryGetAs<SpecificFunction>(callee_id)) {
|
||||
result.resolved_specific_id = specific_function->specific_id;
|
||||
callee_id = specific_function->callee_id;
|
||||
}
|
||||
|
||||
if (auto bound_method = sem_ir.insts().TryGetAs<BoundMethod>(callee_id)) {
|
||||
result.self_id = bound_method->object_id;
|
||||
callee_id = bound_method->function_id;
|
||||
@@ -38,7 +45,7 @@ auto GetCalleeFunction(const File& sem_ir, InstId callee_id) -> CalleeFunction {
|
||||
}
|
||||
|
||||
result.function_id = fn_type->function_id;
|
||||
result.specific_id = fn_type->specific_id;
|
||||
result.enclosing_specific_id = fn_type->specific_id;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,9 @@ struct CalleeFunction {
|
||||
// The function. Invalid if not a function.
|
||||
SemIR::FunctionId function_id;
|
||||
// The specific that contains the function.
|
||||
SemIR::SpecificId specific_id;
|
||||
SemIR::SpecificId enclosing_specific_id;
|
||||
// The specific for the callee itself, in a resolved call.
|
||||
SemIR::SpecificId resolved_specific_id;
|
||||
// The bound `self` parameter. Invalid if not a method.
|
||||
SemIR::InstId self_id;
|
||||
// True if an error instruction was found.
|
||||
|
||||
@@ -64,7 +64,6 @@ CARBON_SEM_IR_INST_KIND(ImportDecl)
|
||||
CARBON_SEM_IR_INST_KIND(ImportRefUnloaded)
|
||||
CARBON_SEM_IR_INST_KIND(ImportRefLoaded)
|
||||
CARBON_SEM_IR_INST_KIND(InitializeFrom)
|
||||
CARBON_SEM_IR_INST_KIND(SpecificConstant)
|
||||
CARBON_SEM_IR_INST_KIND(InterfaceDecl)
|
||||
CARBON_SEM_IR_INST_KIND(InterfaceType)
|
||||
CARBON_SEM_IR_INST_KIND(InterfaceWitness)
|
||||
@@ -80,6 +79,8 @@ CARBON_SEM_IR_INST_KIND(RequirementEquivalent)
|
||||
CARBON_SEM_IR_INST_KIND(RequirementImpls)
|
||||
CARBON_SEM_IR_INST_KIND(ReturnExpr)
|
||||
CARBON_SEM_IR_INST_KIND(Return)
|
||||
CARBON_SEM_IR_INST_KIND(SpecificConstant)
|
||||
CARBON_SEM_IR_INST_KIND(SpecificFunction)
|
||||
CARBON_SEM_IR_INST_KIND(SpliceBlock)
|
||||
CARBON_SEM_IR_INST_KIND(StringLiteral)
|
||||
CARBON_SEM_IR_INST_KIND(StructAccess)
|
||||
|
||||
@@ -305,6 +305,7 @@ auto StringifyTypeExpr(const SemIR::File& outer_sem_ir, InstId outer_inst_id)
|
||||
case RequirementRewrite::Kind:
|
||||
case Return::Kind:
|
||||
case ReturnExpr::Kind:
|
||||
case SpecificFunction::Kind:
|
||||
case SpliceBlock::Kind:
|
||||
case StringLiteral::Kind:
|
||||
case StructAccess::Kind:
|
||||
|
||||
@@ -910,6 +910,27 @@ struct SpecificConstant {
|
||||
SpecificId specific_id;
|
||||
};
|
||||
|
||||
// A specific instance of a generic function. This represents the callee in a
|
||||
// call instruction that is calling a generic function, where the specific
|
||||
// arguments of the function have been deduced.
|
||||
//
|
||||
// TODO: This value corresponds to the `(FunctionType as Call(...)).Op` function
|
||||
// in the overloaded calls design. Eventually we should represent it more
|
||||
// directly as a member of the `Call` interface.
|
||||
struct SpecificFunction {
|
||||
static constexpr auto Kind = InstKind::SpecificFunction.Define<Parse::NodeId>(
|
||||
{.ir_name = "specific_function",
|
||||
.constant_kind = InstConstantKind::Always});
|
||||
|
||||
// Always the builtin SpecificFunctionType.
|
||||
TypeId type_id;
|
||||
// The expression denoting the callee.
|
||||
InstId callee_id;
|
||||
// The specific instance of the generic callee that will be called, including
|
||||
// all the compile-time arguments.
|
||||
SpecificId specific_id;
|
||||
};
|
||||
|
||||
// Splices a block into the location where this appears. This may be an
|
||||
// expression, producing a result with a given type. For example, when
|
||||
// constructing from aggregates we may figure out which conversions are required
|
||||
|
||||
Reference in New Issue
Block a user