Use the value representation of T as that of MaybeUnformed(T) where possible (#6334)

If the value representation of `T` is a copy representation, but it
copies all of the bits of `T`'s object representation, then it's OK to
use that as the value representation of `MaybeUnformed(T)` too.

This fixes the behavior of interop with nullable pointers, which are
represented as an adapter of `MaybeUnformed(T*)`, and need to be passed
to and returned from functions on the Carbon / C++ boundary as `T*`s.
This commit is contained in:
Richard Smith
2025-11-07 16:25:27 +00:00
committed by GitHub
parent d6c19442b2
commit 8f19f7a7c0
14 changed files with 417 additions and 322 deletions
+14 -6
View File
@@ -32,6 +32,7 @@
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/inst.h"
#include "toolchain/sem_ir/type.h"
#include "toolchain/sem_ir/type_info.h"
#include "toolchain/sem_ir/typed_insts.h"
// TODO: This contains a lot of recursion. Consider removing it in order to
@@ -1006,16 +1007,23 @@ static auto PerformBuiltinConversion(
.diagnose = target.diagnose});
}
// `MaybeUnformed(T)` has a pointer value representation, and `T` might
// not, so convert as needed when removing `MaybeUnformed`.
// `MaybeUnformed(T)` might have a pointer value representation when `T`
// does not, so convert as needed when removing `MaybeUnformed`.
bool need_value_binding = false;
if ((removed_quals & SemIR::TypeQualifiers::MaybeUnformed) !=
SemIR::TypeQualifiers::None &&
category == SemIR::ExprCategory::Value) {
value_id = AddInst<SemIR::ValueAsRef>(
context, loc_id,
{.type_id = value_type_id, .value_id = value_id});
need_value_binding = true;
auto value_rep =
SemIR::ValueRepr::ForType(context.sem_ir(), value_type_id);
auto unformed_value_rep =
SemIR::ValueRepr::ForType(context.sem_ir(), target.type_id);
if (value_rep.kind != unformed_value_rep.kind) {
CARBON_CHECK(unformed_value_rep.kind == SemIR::ValueRepr::Pointer);
value_id = AddInst<SemIR::ValueAsRef>(
context, loc_id,
{.type_id = value_type_id, .value_id = value_id});
need_value_binding = true;
}
}
value_id = AddInst<SemIR::AsCompatible>(
+4
View File
@@ -291,6 +291,10 @@ auto HandleParseNode(Context& context, Parse::ChoiceDefinitionId node_id)
for (auto [i, deferred_binding] :
llvm::enumerate(context.choice_deferred_bindings())) {
// TODO: This requires the class to be complete, but we've not yet called
// `FinishGenericDefinition`, so we can't use it as a complete type yet. But
// this also potentially adds things to the generic definition, so we can't
// call `FinsihGenericDefinition` before this call, either.
MakeLetBinding(context,
ChoiceInfo{.self_type_id = class_info.self_type_id,
.name_scope_id = class_info.scope_id,
+3 -5
View File
@@ -313,12 +313,10 @@ fn Use() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %value.ref: %MaybeUnformed.275 = name_ref value, file.%value
// CHECK:STDOUT: %X.ref.loc13_30: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %.loc13_27.1: ref %MaybeUnformed.275 = value_as_ref %value.ref
// CHECK:STDOUT: %.loc13_27.2: ref %X = as_compatible %.loc13_27.1
// CHECK:STDOUT: %.loc13_27.3: %X = acquire_value %.loc13_27.2
// CHECK:STDOUT: %.loc13_27.4: %X = converted %value.ref, %.loc13_27.3
// CHECK:STDOUT: %.loc13_27.1: %X = as_compatible %value.ref
// CHECK:STDOUT: %.loc13_27.2: %X = converted %value.ref, %.loc13_27.1
// CHECK:STDOUT: %X.ref.loc13_10: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %v: %X = value_binding v, %.loc13_27.4
// CHECK:STDOUT: %v: %X = value_binding v, %.loc13_27.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.1c6 = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
+13 -17
View File
@@ -95,8 +95,8 @@ fn NotPointer() -> MakeUnformed({}) = "pointer.make_null";
// CHECK:STDOUT: %.loc11_24.2: type = value_of_initializer %MakeUnformed.call.loc11 [concrete = constants.%.b2d]
// CHECK:STDOUT: %.loc11_24.3: type = converted %MakeUnformed.call.loc11, %.loc11_24.2 [concrete = constants.%.b2d]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc11_48.1: ref %.b2d = temporary @__global_init.%.loc11, @__global_init.%MakeNullEmptyStruct.call
// CHECK:STDOUT: %.loc11_48.2: %.b2d = acquire_value %.loc11_48.1
// CHECK:STDOUT: %.loc11_48.1: %.b2d = value_of_initializer @__global_init.%MakeNullEmptyStruct.call
// CHECK:STDOUT: %.loc11_48.2: %.b2d = converted @__global_init.%MakeNullEmptyStruct.call, %.loc11_48.1
// CHECK:STDOUT: %s: %.b2d = value_binding s, %.loc11_48.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.ad6 = value_binding_pattern c [concrete]
@@ -109,19 +109,17 @@ fn NotPointer() -> MakeUnformed({}) = "pointer.make_null";
// CHECK:STDOUT: %.loc12_23.2: type = value_of_initializer %MakeUnformed.call.loc12 [concrete = constants.%.273]
// CHECK:STDOUT: %.loc12_23.3: type = converted %MakeUnformed.call.loc12, %.loc12_23.2 [concrete = constants.%.273]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc12_37.1: ref %.273 = temporary @__global_init.%.loc12, @__global_init.%MakeNullC.call
// CHECK:STDOUT: %.loc12_37.2: %.273 = acquire_value %.loc12_37.1
// CHECK:STDOUT: %.loc12_37.1: %.273 = value_of_initializer @__global_init.%MakeNullC.call
// CHECK:STDOUT: %.loc12_37.2: %.273 = converted @__global_init.%MakeNullC.call, %.loc12_37.1
// CHECK:STDOUT: %c: %.273 = value_binding c, %.loc12_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %MakeNullEmptyStruct.ref: %MakeNullEmptyStruct.type = name_ref MakeNullEmptyStruct, file.%MakeNullEmptyStruct.decl [concrete = constants.%MakeNullEmptyStruct]
// CHECK:STDOUT: %.loc11: ref %.b2d = temporary_storage
// CHECK:STDOUT: %MakeNullEmptyStruct.call: init %.b2d = call %MakeNullEmptyStruct.ref() to %.loc11
// CHECK:STDOUT: %MakeNullEmptyStruct.call: init %.b2d = call %MakeNullEmptyStruct.ref()
// CHECK:STDOUT: %MakeNullC.ref: %MakeNullC.type = name_ref MakeNullC, file.%MakeNullC.decl [concrete = constants.%MakeNullC]
// CHECK:STDOUT: %.loc12: ref %.273 = temporary_storage
// CHECK:STDOUT: %MakeNullC.call: init %.273 = call %MakeNullC.ref() to %.loc12
// CHECK:STDOUT: %MakeNullC.call: init %.273 = call %MakeNullC.ref()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -157,8 +155,8 @@ fn NotPointer() -> MakeUnformed({}) = "pointer.make_null";
// CHECK:STDOUT: %.loc10_24.2: type = value_of_initializer %MakeUnformed.call.loc10 [concrete = constants.%.b2d]
// CHECK:STDOUT: %.loc10_24.3: type = converted %MakeUnformed.call.loc10, %.loc10_24.2 [concrete = constants.%.b2d]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc10_39.1: ref %.b2d = temporary @__global_init.%.loc10_39.2, @__global_init.%MakeNull.call.loc10
// CHECK:STDOUT: %.loc10_39.2: %.b2d = acquire_value %.loc10_39.1
// CHECK:STDOUT: %.loc10_39.1: %.b2d = value_of_initializer @__global_init.%MakeNull.call.loc10
// CHECK:STDOUT: %.loc10_39.2: %.b2d = converted @__global_init.%MakeNull.call.loc10, %.loc10_39.1
// CHECK:STDOUT: %s: %.b2d = value_binding s, %.loc10_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.ad6 = value_binding_pattern c [concrete]
@@ -171,8 +169,8 @@ fn NotPointer() -> MakeUnformed({}) = "pointer.make_null";
// CHECK:STDOUT: %.loc11_23.2: type = value_of_initializer %MakeUnformed.call.loc11 [concrete = constants.%.273]
// CHECK:STDOUT: %.loc11_23.3: type = converted %MakeUnformed.call.loc11, %.loc11_23.2 [concrete = constants.%.273]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc11_37.1: ref %.273 = temporary @__global_init.%.loc11, @__global_init.%MakeNull.call.loc11
// CHECK:STDOUT: %.loc11_37.2: %.273 = acquire_value %.loc11_37.1
// CHECK:STDOUT: %.loc11_37.1: %.273 = value_of_initializer @__global_init.%MakeNull.call.loc11
// CHECK:STDOUT: %.loc11_37.2: %.273 = converted @__global_init.%MakeNull.call.loc11, %.loc11_37.1
// CHECK:STDOUT: %c: %.273 = value_binding c, %.loc11_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -180,15 +178,13 @@ fn NotPointer() -> MakeUnformed({}) = "pointer.make_null";
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %MakeNull.ref.loc10: %MakeNull.type = name_ref MakeNull, file.%MakeNull.decl [concrete = constants.%MakeNull]
// CHECK:STDOUT: %.loc10_38: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc10_39.1: type = converted %.loc10_38, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
// CHECK:STDOUT: %.loc10_39: type = converted %.loc10_38, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
// CHECK:STDOUT: %MakeNull.specific_fn.loc10: <specific function> = specific_function %MakeNull.ref.loc10, @MakeNull(constants.%empty_struct_type) [concrete = constants.%MakeNull.specific_fn.7cb]
// CHECK:STDOUT: %.loc10_39.2: ref %.b2d = temporary_storage
// CHECK:STDOUT: %MakeNull.call.loc10: init %.b2d = call %MakeNull.specific_fn.loc10() to %.loc10_39.2
// CHECK:STDOUT: %MakeNull.call.loc10: init %.b2d = call %MakeNull.specific_fn.loc10()
// CHECK:STDOUT: %MakeNull.ref.loc11: %MakeNull.type = name_ref MakeNull, file.%MakeNull.decl [concrete = constants.%MakeNull]
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %MakeNull.specific_fn.loc11: <specific function> = specific_function %MakeNull.ref.loc11, @MakeNull(constants.%C) [concrete = constants.%MakeNull.specific_fn.22e]
// CHECK:STDOUT: %.loc11: ref %.273 = temporary_storage
// CHECK:STDOUT: %MakeNull.call.loc11: init %.273 = call %MakeNull.specific_fn.loc11() to %.loc11
// CHECK:STDOUT: %MakeNull.call.loc11: init %.273 = call %MakeNull.specific_fn.loc11()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
+23 -23
View File
@@ -96,6 +96,12 @@ fn Read() {
// CHECK:STDOUT: %Optional.None.dc7: %Optional.None.type.193 = struct_value () [symbolic]
// CHECK:STDOUT: %Optional.Some.type.32b: type = fn_type @Optional.Some, @Optional(%T.3fe) [symbolic]
// CHECK:STDOUT: %Optional.Some.249: %Optional.Some.type.32b = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyT: %type_where = symbolic_binding DestroyT, 0 [symbolic]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%DestroyT) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.fd5: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c = struct_value () [symbolic]
// CHECK:STDOUT: %Iterate.impl_witness: <witness> = impl_witness @IntRange.%Iterate.impl_witness_table, @IntRange.as.Iterate.impl(%N) [symbolic]
// CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor.type: type = fn_type @IntRange.as.Iterate.impl.NewCursor, @IntRange.as.Iterate.impl(%N) [symbolic]
// CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor: %IntRange.as.Iterate.impl.NewCursor.type = struct_value () [symbolic]
@@ -151,19 +157,13 @@ fn Read() {
// CHECK:STDOUT: %impl.elem0.923: %.080 = impl_witness_access %Inc.lookup_impl_witness, element0 [symbolic]
// CHECK:STDOUT: %specific_impl_fn.173: <specific function> = specific_impl_function %impl.elem0.923, @Inc.Op(%Inc.facet) [symbolic]
// CHECK:STDOUT: %Optional.Some.specific_fn: <specific function> = specific_function %Optional.Some.37c, @Optional.Some(%OptionalStorage.facet.ea4) [symbolic]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %DestroyT: %type_where = symbolic_binding DestroyT, 0 [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%DestroyT) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.fd5: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c = struct_value () [symbolic]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Int.b50e37.1, () [symbolic]
// CHECK:STDOUT: %Destroy.impl_witness.437: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.353: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic]
// CHECK:STDOUT: %facet_value.4a9: %type_where = facet_value %Int.b50e37.1, () [symbolic]
// CHECK:STDOUT: %Destroy.impl_witness.b47: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.4a9) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.353: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.4a9) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.3be: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.353 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Int.b50e37.1, (%Destroy.impl_witness.437) [symbolic]
// CHECK:STDOUT: %.200: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.3be, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [symbolic]
// CHECK:STDOUT: %Destroy.facet.11d: %Destroy.type = facet_value %Int.b50e37.1, (%Destroy.impl_witness.b47) [symbolic]
// CHECK:STDOUT: %.a64: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.11d [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.e87: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.3be, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.4a9) [symbolic]
// CHECK:STDOUT: %Optional.None.specific_fn: <specific function> = specific_function %Optional.None.b0b, @Optional.None(%OptionalStorage.facet.ea4) [symbolic]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
@@ -230,6 +230,8 @@ fn Read() {
// CHECK:STDOUT: %Copy.impl_witness_table.b6a = impl_witness_table (%Core.import_ref.d12), @Int.as.Copy.impl [concrete]
// CHECK:STDOUT: %Core.import_ref.f2f: @Optional.%Optional.None.type (%Optional.None.type.193) = import_ref Core//prelude/iterate, inst{{[0-9A-F]+}} [indirect], loaded [symbolic = @Optional.%Optional.None (constants.%Optional.None.dc7)]
// CHECK:STDOUT: %Core.import_ref.961: @Optional.%Optional.Some.type (%Optional.Some.type.32b) = import_ref Core//prelude/iterate, inst{{[0-9A-F]+}} [indirect], loaded [symbolic = @Optional.%Optional.Some (constants.%Optional.Some.249)]
// CHECK:STDOUT: %Core.import_ref.416: @DestroyT.binding.as_type.as.Destroy.impl.%DestroyT.binding.as_type.as.Destroy.impl.Op.type (%DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c) = import_ref Core//prelude/types/optional, inst{{[0-9A-F]+}} [indirect], loaded [symbolic = @DestroyT.binding.as_type.as.Destroy.impl.%DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.fd5)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.416), @DestroyT.binding.as_type.as.Destroy.impl [concrete]
// CHECK:STDOUT: %Core.Optional: %Optional.type = import_ref Core//prelude/types/optional, Optional, loaded [concrete = constants.%Optional.generic]
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/copy, Copy, loaded [concrete = constants.%Copy.type]
// CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic]
@@ -243,8 +245,6 @@ fn Read() {
// CHECK:STDOUT: %OrderedWith.impl_witness_table.401 = impl_witness_table (%Core.import_ref.b35, %Core.import_ref.2a1, %Core.import_ref.3bc, %Core.import_ref.8fd), @Int.as.OrderedWith.impl.849 [concrete]
// CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type]
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
// CHECK:STDOUT: %Core.import_ref.5c4: @DestroyT.binding.as_type.as.Destroy.impl.%DestroyT.binding.as_type.as.Destroy.impl.Op.type (%DestroyT.binding.as_type.as.Destroy.impl.Op.type.15c) = import_ref Core//prelude/destroy, loc{{\d+_\d+}}, loaded [symbolic = @DestroyT.binding.as_type.as.Destroy.impl.%DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.fd5)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.5c4), @DestroyT.binding.as_type.as.Destroy.impl [concrete]
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/types/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
@@ -587,13 +587,13 @@ fn Read() {
// CHECK:STDOUT: %Optional.Some.type: type = fn_type @Optional.Some, @Optional(%OptionalStorage.facet.loc11_75.1) [symbolic = %Optional.Some.type (constants.%Optional.Some.type.74c)]
// CHECK:STDOUT: %Optional.Some: @IntRange.as.Iterate.impl.Next.%Optional.Some.type (%Optional.Some.type.74c) = struct_value () [symbolic = %Optional.Some (constants.%Optional.Some.37c)]
// CHECK:STDOUT: %Optional.Some.specific_fn.loc15_42.2: <specific function> = specific_function %Optional.Some, @Optional.Some(%OptionalStorage.facet.loc11_75.1) [symbolic = %Optional.Some.specific_fn.loc15_42.2 (constants.%Optional.Some.specific_fn)]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Int.loc11_43.1, () [symbolic = %facet_value (constants.%facet_value)]
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.437)]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Int.loc11_43.1, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)]
// CHECK:STDOUT: %.loc12_7: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc12_7 (constants.%.200)]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Int.loc11_43.1, () [symbolic = %facet_value (constants.%facet_value.4a9)]
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.b47)]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Int.loc11_43.1, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.11d)]
// CHECK:STDOUT: %.loc12_7: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc12_7 (constants.%.a64)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.type (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.type.353)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op: @IntRange.as.Iterate.impl.Next.%DestroyT.binding.as_type.as.Destroy.impl.Op.type (%DestroyT.binding.as_type.as.Destroy.impl.Op.type.353) = struct_value () [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.3be)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.e87)]
// CHECK:STDOUT: %Optional.None.type: type = fn_type @Optional.None, @Optional(%OptionalStorage.facet.loc11_75.1) [symbolic = %Optional.None.type (constants.%Optional.None.type.a39)]
// CHECK:STDOUT: %Optional.None: @IntRange.as.Iterate.impl.Next.%Optional.None.type (%Optional.None.type.a39) = struct_value () [symbolic = %Optional.None (constants.%Optional.None.b0b)]
// CHECK:STDOUT: %Optional.None.specific_fn.loc17_42.2: <specific function> = specific_function %Optional.None, @Optional.None(%OptionalStorage.facet.loc11_75.1) [symbolic = %Optional.None.specific_fn.loc17_42.2 (constants.%Optional.None.specific_fn)]
@@ -668,9 +668,9 @@ fn Read() {
// CHECK:STDOUT: %.loc11_47.1: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.23f) = splice_block %return {}
// CHECK:STDOUT: %.loc15_48: @IntRange.as.Iterate.impl.Next.%Int.loc11_43.1 (%Int.b50e37.1) = acquire_value %value.ref.loc15
// CHECK:STDOUT: %Optional.Some.call: init @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.23f) = call %Optional.Some.specific_fn.loc15_42.1(%.loc15_48) to %.loc11_47.1
// CHECK:STDOUT: %impl.elem0.loc12_7.1: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.200) = impl_witness_access constants.%Destroy.impl_witness.437, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.3be)]
// CHECK:STDOUT: %impl.elem0.loc12_7.1: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.a64) = impl_witness_access constants.%Destroy.impl_witness.b47, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.3be)]
// CHECK:STDOUT: %bound_method.loc12_7.1: <bound method> = bound_method %value.var, %impl.elem0.loc12_7.1
// CHECK:STDOUT: %specific_fn.loc12_7.1: <specific function> = specific_function %impl.elem0.loc12_7.1, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn)]
// CHECK:STDOUT: %specific_fn.loc12_7.1: <specific function> = specific_function %impl.elem0.loc12_7.1, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.4a9) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.e87)]
// CHECK:STDOUT: %bound_method.loc12_7.2: <bound method> = bound_method %value.var, %specific_fn.loc12_7.1
// CHECK:STDOUT: %addr.loc12_7.1: @IntRange.as.Iterate.impl.Next.%ptr.loc11_44.1 (%ptr.1cf) = addr_of %value.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc12_7.1: init %empty_tuple.type = call %bound_method.loc12_7.2(%addr.loc12_7.1)
@@ -691,9 +691,9 @@ fn Read() {
// CHECK:STDOUT: %Optional.None.specific_fn.loc17_42.1: <specific function> = specific_function %None.ref, @Optional.None(constants.%OptionalStorage.facet.ea4) [symbolic = %Optional.None.specific_fn.loc17_42.2 (constants.%Optional.None.specific_fn)]
// CHECK:STDOUT: %.loc11_47.2: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.23f) = splice_block %return {}
// CHECK:STDOUT: %Optional.None.call: init @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.23f) = call %Optional.None.specific_fn.loc17_42.1() to %.loc11_47.2
// CHECK:STDOUT: %impl.elem0.loc12_7.2: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.200) = impl_witness_access constants.%Destroy.impl_witness.437, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.3be)]
// CHECK:STDOUT: %impl.elem0.loc12_7.2: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.a64) = impl_witness_access constants.%Destroy.impl_witness.b47, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.3be)]
// CHECK:STDOUT: %bound_method.loc12_7.3: <bound method> = bound_method %value.var, %impl.elem0.loc12_7.2
// CHECK:STDOUT: %specific_fn.loc12_7.2: <specific function> = specific_function %impl.elem0.loc12_7.2, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn)]
// CHECK:STDOUT: %specific_fn.loc12_7.2: <specific function> = specific_function %impl.elem0.loc12_7.2, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.4a9) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.e87)]
// CHECK:STDOUT: %bound_method.loc12_7.4: <bound method> = bound_method %value.var, %specific_fn.loc12_7.2
// CHECK:STDOUT: %addr.loc12_7.2: @IntRange.as.Iterate.impl.Next.%ptr.loc11_44.1 (%ptr.1cf) = addr_of %value.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc12_7.2: init %empty_tuple.type = call %bound_method.loc12_7.4(%addr.loc12_7.2)
@@ -114,6 +114,7 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.2cf: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(%i32) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.0a3: %OptionalStorage.type = facet_value %ptr.235, (%OptionalStorage.impl_witness.2cf) [concrete]
// CHECK:STDOUT: %Optional.18c: type = class_type @Optional, @Optional(%OptionalStorage.facet.0a3) [concrete]
@@ -136,7 +137,6 @@ fn F() {
// CHECK:STDOUT: %ImplicitAs.facet.59b: %ImplicitAs.type.4f4 = facet_value %ptr.235, (%ImplicitAs.impl_witness.f51) [concrete]
// CHECK:STDOUT: %.4d2: type = fn_type_with_self_type %ImplicitAs.Convert.type.7ef, %ImplicitAs.facet.59b [concrete]
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %U.binding.as_type.as.ImplicitAs.impl.Convert.b59, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(%OptionalStorage.facet.0a3, %OptionalAs.facet) [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value.888: %type_where = facet_value %Optional.18c, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.b81: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.888) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.55c: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.b81 = struct_value () [concrete]
@@ -211,10 +211,10 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc11_18.1: <bound method> = bound_method %addr.loc11_18.1, %impl.elem0.loc11_18
// CHECK:STDOUT: %specific_fn.loc11_18: <specific function> = specific_function %impl.elem0.loc11_18, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(constants.%OptionalStorage.facet.0a3, constants.%OptionalAs.facet) [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc11_18.2: <bound method> = bound_method %addr.loc11_18.1, %specific_fn.loc11_18
// CHECK:STDOUT: %.loc11_18.1: ref %Optional.18c = temporary_storage
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.18c = call %bound_method.loc11_18.2(%addr.loc11_18.1) to %.loc11_18.1
// CHECK:STDOUT: %.loc11_18.2: init %Optional.18c = converted %addr.loc11_18.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_18.3: ref %Optional.18c = temporary %.loc11_18.1, %.loc11_18.2
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.18c = call %bound_method.loc11_18.2(%addr.loc11_18.1)
// CHECK:STDOUT: %.loc11_18.1: init %Optional.18c = converted %addr.loc11_18.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_18.2: ref %Optional.18c = temporary_storage
// CHECK:STDOUT: %.loc11_18.3: ref %Optional.18c = temporary %.loc11_18.2, %.loc11_18.1
// CHECK:STDOUT: %.loc11_18.4: %Optional.18c = acquire_value %.loc11_18.3
// CHECK:STDOUT: %TakesArray.call: init %empty_tuple.type = call imports.%TakesArray.decl(%.loc11_18.4)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11: <bound method> = bound_method %.loc11_18.3, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.55c
+31 -39
View File
@@ -923,6 +923,7 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.fef: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(%S) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.066: %OptionalStorage.type = facet_value %ptr.5c7, (%OptionalStorage.impl_witness.fef) [concrete]
// CHECK:STDOUT: %Optional.454: type = class_type @Optional, @Optional(%OptionalStorage.facet.066) [concrete]
@@ -951,7 +952,6 @@ fn F() {
// CHECK:STDOUT: %ImplicitAs.facet.5b5: %ImplicitAs.type.099 = facet_value %const.b9a, (%ImplicitAs.impl_witness.322) [concrete]
// CHECK:STDOUT: %.65a: type = fn_type_with_self_type %ImplicitAs.Convert.type.d3b, %ImplicitAs.facet.5b5 [concrete]
// CHECK:STDOUT: %const.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %const.as.ImplicitAs.impl.Convert.3a1, @const.as.ImplicitAs.impl.Convert(%Optional.454, %ImplicitAs.facet.2c8) [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value.542: %type_where = facet_value %Optional.454, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.542) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.de7: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8 = struct_value () [concrete]
@@ -1019,11 +1019,11 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc11_11.1: <bound method> = bound_method %p.ref, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @const.as.ImplicitAs.impl.Convert(constants.%Optional.454, constants.%ImplicitAs.facet.2c8) [concrete = constants.%const.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc11_11.2: <bound method> = bound_method %p.ref, %specific_fn
// CHECK:STDOUT: %.loc11_11.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc11_11.2: %const.b9a = acquire_value %p.ref
// CHECK:STDOUT: %const.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_11.2(%.loc11_11.2) to %.loc11_11.1
// CHECK:STDOUT: %.loc11_11.3: init %Optional.454 = converted %p.ref, %const.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_11.4: ref %Optional.454 = temporary %.loc11_11.1, %.loc11_11.3
// CHECK:STDOUT: %.loc11_11.1: %const.b9a = acquire_value %p.ref
// CHECK:STDOUT: %const.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_11.2(%.loc11_11.1)
// CHECK:STDOUT: %.loc11_11.2: init %Optional.454 = converted %p.ref, %const.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_11.3: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc11_11.4: ref %Optional.454 = temporary %.loc11_11.3, %.loc11_11.2
// CHECK:STDOUT: %.loc11_11.5: %Optional.454 = acquire_value %.loc11_11.4
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc11_11.5)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11: <bound method> = bound_method %.loc11_11.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
@@ -1057,6 +1057,7 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.fef: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(%S) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.066: %OptionalStorage.type = facet_value %ptr.5c7, (%OptionalStorage.impl_witness.fef) [concrete]
// CHECK:STDOUT: %Optional.454: type = class_type @Optional, @Optional(%OptionalStorage.facet.066) [concrete]
@@ -1079,7 +1080,6 @@ fn F() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.099 = facet_value %ptr.5c7, (%ImplicitAs.impl_witness.aa3) [concrete]
// CHECK:STDOUT: %.4d4: type = fn_type_with_self_type %ImplicitAs.Convert.type.d3b, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %U.binding.as_type.as.ImplicitAs.impl.Convert.80c, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(%OptionalStorage.facet.066, %OptionalAs.facet) [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value.542: %type_where = facet_value %Optional.454, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.542) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.de7: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8 = struct_value () [concrete]
@@ -1144,11 +1144,11 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc11_11.1: <bound method> = bound_method %p.ref, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(constants.%OptionalStorage.facet.066, constants.%OptionalAs.facet) [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc11_11.2: <bound method> = bound_method %p.ref, %specific_fn
// CHECK:STDOUT: %.loc11_11.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc11_11.2: %ptr.5c7 = acquire_value %p.ref
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_11.2(%.loc11_11.2) to %.loc11_11.1
// CHECK:STDOUT: %.loc11_11.3: init %Optional.454 = converted %p.ref, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_11.4: ref %Optional.454 = temporary %.loc11_11.1, %.loc11_11.3
// CHECK:STDOUT: %.loc11_11.1: %ptr.5c7 = acquire_value %p.ref
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_11.2(%.loc11_11.1)
// CHECK:STDOUT: %.loc11_11.2: init %Optional.454 = converted %p.ref, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_11.3: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc11_11.4: ref %Optional.454 = temporary %.loc11_11.3, %.loc11_11.2
// CHECK:STDOUT: %.loc11_11.5: %Optional.454 = acquire_value %.loc11_11.4
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc11_11.5)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11: <bound method> = bound_method %.loc11_11.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
@@ -1316,6 +1316,7 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.fef: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(%S) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.066: %OptionalStorage.type = facet_value %ptr.5c7, (%OptionalStorage.impl_witness.fef) [concrete]
// CHECK:STDOUT: %Optional.454: type = class_type @Optional, @Optional(%OptionalStorage.facet.066) [concrete]
@@ -1338,7 +1339,6 @@ fn F() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.099 = facet_value %ptr.5c7, (%ImplicitAs.impl_witness.aa3) [concrete]
// CHECK:STDOUT: %.4d4: type = fn_type_with_self_type %ImplicitAs.Convert.type.d3b, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %U.binding.as_type.as.ImplicitAs.impl.Convert.80c, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(%OptionalStorage.facet.066, %OptionalAs.facet) [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value.542: %type_where = facet_value %Optional.454, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.542) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.de7: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8 = struct_value () [concrete]
@@ -1403,10 +1403,10 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc9_11.1: <bound method> = bound_method %addr.loc9_11.1, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(constants.%OptionalStorage.facet.066, constants.%OptionalAs.facet) [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc9_11.2: <bound method> = bound_method %addr.loc9_11.1, %specific_fn
// CHECK:STDOUT: %.loc9_11.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc9_11.2(%addr.loc9_11.1) to %.loc9_11.1
// CHECK:STDOUT: %.loc9_11.2: init %Optional.454 = converted %addr.loc9_11.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc9_11.3: ref %Optional.454 = temporary %.loc9_11.1, %.loc9_11.2
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc9_11.2(%addr.loc9_11.1)
// CHECK:STDOUT: %.loc9_11.1: init %Optional.454 = converted %addr.loc9_11.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc9_11.2: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc9_11.3: ref %Optional.454 = temporary %.loc9_11.2, %.loc9_11.1
// CHECK:STDOUT: %.loc9_11.4: %Optional.454 = acquire_value %.loc9_11.3
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc9_11.4)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc9: <bound method> = bound_method %.loc9_11.3, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
@@ -1486,8 +1486,7 @@ fn F() {
// CHECK:STDOUT: %.loc12_32: %Optional.None.type.410 = specific_constant imports.%Core.import_ref.f1d, @Optional(constants.%OptionalStorage.facet) [concrete = constants.%Optional.None.d01]
// CHECK:STDOUT: %None.ref: %Optional.None.type.410 = name_ref None, %.loc12_32 [concrete = constants.%Optional.None.d01]
// CHECK:STDOUT: %Optional.None.specific_fn: <specific function> = specific_function %None.ref, @Optional.None(constants.%OptionalStorage.facet) [concrete = constants.%Optional.None.specific_fn]
// CHECK:STDOUT: %.loc12_38: ref %Optional.91c = temporary_storage
// CHECK:STDOUT: %Optional.None.call: init %Optional.91c = call %Optional.None.specific_fn() to %.loc12_38
// CHECK:STDOUT: %Optional.None.call: init %Optional.91c = call %Optional.None.specific_fn()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -1586,6 +1585,8 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.fef: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(%S) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.066: %OptionalStorage.type = facet_value %ptr.5c7, (%OptionalStorage.impl_witness.fef) [concrete]
// CHECK:STDOUT: %Optional.454: type = class_type @Optional, @Optional(%OptionalStorage.facet.066) [concrete]
@@ -1603,7 +1604,6 @@ fn F() {
// CHECK:STDOUT: %OptionalAs.type.af7: type = facet_type <@OptionalAs, @OptionalAs(%OptionalStorage.facet.066)> [concrete]
// CHECK:STDOUT: %T.binding.as_type.as.OptionalAs.impl.Convert.type.8c6: type = fn_type @T.binding.as_type.as.OptionalAs.impl.Convert, @T.binding.as_type.as.OptionalAs.impl(%T.3fe) [symbolic]
// CHECK:STDOUT: %T.binding.as_type.as.OptionalAs.impl.Convert.180: %T.binding.as_type.as.OptionalAs.impl.Convert.type.8c6 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %OptionalAs.impl_witness.12c: <witness> = impl_witness imports.%OptionalAs.impl_witness_table.8ee, @T.binding.as_type.as.OptionalAs.impl(%OptionalStorage.facet.066) [concrete]
// CHECK:STDOUT: %OptionalAs.facet: %OptionalAs.type.af7 = facet_value %ptr.5c7, (%OptionalAs.impl_witness.12c) [concrete]
// CHECK:STDOUT: %ImplicitAs.impl_witness.aa3: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.da6, @U.binding.as_type.as.ImplicitAs.impl.ea7(%OptionalStorage.facet.066, %OptionalAs.facet) [concrete]
@@ -1616,7 +1616,6 @@ fn F() {
// CHECK:STDOUT: %Indirect.cpp_overload_set.value: %Indirect.cpp_overload_set.type = cpp_overload_set_value @Indirect.cpp_overload_set [concrete]
// CHECK:STDOUT: %Indirect__carbon_thunk.type: type = fn_type @Indirect__carbon_thunk [concrete]
// CHECK:STDOUT: %Indirect__carbon_thunk: %Indirect__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value.542: %type_where = facet_value %Optional.454, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.542) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.de7: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6e8 = struct_value () [concrete]
@@ -1700,18 +1699,16 @@ fn F() {
// CHECK:STDOUT: %Direct.ref: %Direct.cpp_overload_set.type = name_ref Direct, imports.%Direct.cpp_overload_set.value [concrete = constants.%Direct.cpp_overload_set.value]
// CHECK:STDOUT: %s.ref: ref %S = name_ref s, %s
// CHECK:STDOUT: %addr.loc11_14.1: %ptr.5c7 = addr_of %s.ref
// CHECK:STDOUT: %.loc11_16.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %impl.elem0: %.4d4 = impl_witness_access constants.%ImplicitAs.impl_witness.aa3, element0 [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.80c]
// CHECK:STDOUT: %bound_method.loc11_14.1: <bound method> = bound_method %addr.loc11_14.1, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(constants.%OptionalStorage.facet.066, constants.%OptionalAs.facet) [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc11_14.2: <bound method> = bound_method %addr.loc11_14.1, %specific_fn
// CHECK:STDOUT: %.loc11_14.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_14.2(%addr.loc11_14.1) to %.loc11_14.1
// CHECK:STDOUT: %.loc11_14.2: init %Optional.454 = converted %addr.loc11_14.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_14.3: ref %Optional.454 = temporary %.loc11_14.1, %.loc11_14.2
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.454 = call %bound_method.loc11_14.2(%addr.loc11_14.1)
// CHECK:STDOUT: %.loc11_14.1: init %Optional.454 = converted %addr.loc11_14.1, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc11_14.2: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc11_14.3: ref %Optional.454 = temporary %.loc11_14.2, %.loc11_14.1
// CHECK:STDOUT: %.loc11_14.4: %Optional.454 = acquire_value %.loc11_14.3
// CHECK:STDOUT: %Direct.call: init %Optional.454 = call imports.%Direct.decl(%.loc11_14.4) to %.loc11_16.1
// CHECK:STDOUT: %.loc11_16.2: ref %Optional.454 = temporary %.loc11_16.1, %Direct.call
// CHECK:STDOUT: %Direct.call: init %Optional.454 = call imports.%Direct.decl(%.loc11_14.4)
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.683 = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
@@ -1724,11 +1721,10 @@ fn F() {
// CHECK:STDOUT: %.loc13_48.3: init %S = class_init (), %.loc13_48.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc13_48.4: ref %S = temporary %.loc13_48.2, %.loc13_48.3
// CHECK:STDOUT: %.loc13_50.1: ref %S = converted %.loc13_48.1, %.loc13_48.4
// CHECK:STDOUT: %.loc13_58.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc13_50.2: %S = acquire_value %.loc13_50.1
// CHECK:STDOUT: %.loc13_50.3: ref %S = value_as_ref %.loc13_50.2
// CHECK:STDOUT: %addr.loc13_58.1: %ptr.5c7 = addr_of %.loc13_50.3
// CHECK:STDOUT: %Indirect__carbon_thunk.call: init %Optional.454 = call imports.%Indirect__carbon_thunk.decl(%addr.loc13_58.1) to %.loc13_58.1
// CHECK:STDOUT: %Indirect__carbon_thunk.call: init %Optional.454 = call imports.%Indirect__carbon_thunk.decl(%addr.loc13_58.1)
// CHECK:STDOUT: %.loc13_30.1: type = splice_block %Optional [concrete = constants.%Optional.454] {
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %Optional.ref: %Optional.type = name_ref Optional, imports.%Core.Optional [concrete = constants.%Optional.generic]
@@ -1739,6 +1735,7 @@ fn F() {
// CHECK:STDOUT: %.loc13_30.2: %OptionalStorage.type = converted %ptr, %OptionalStorage.facet [concrete = constants.%OptionalStorage.facet.066]
// CHECK:STDOUT: %Optional: type = class_type @Optional, @Optional(constants.%OptionalStorage.facet.066) [concrete = constants.%Optional.454]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_58.1: ref %Optional.454 = temporary_storage
// CHECK:STDOUT: %.loc13_58.2: ref %Optional.454 = temporary %.loc13_58.1, %Indirect__carbon_thunk.call
// CHECK:STDOUT: %.loc13_58.3: %Optional.454 = acquire_value %.loc13_58.2
// CHECK:STDOUT: %a: %Optional.454 = value_binding a, %.loc13_58.3
@@ -1752,19 +1749,14 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc13_48: <bound method> = bound_method %.loc13_48.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2
// CHECK:STDOUT: %addr.loc13_48: %ptr.5c7 = addr_of %.loc13_48.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc13_48: init %empty_tuple.type = call %bound_method.loc13_48(%addr.loc13_48)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11_16: <bound method> = bound_method %.loc11_16.2, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11: <bound method> = bound_method %.loc11_14.3, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc11_16: <bound method> = bound_method %.loc11_16.2, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3
// CHECK:STDOUT: %addr.loc11_16: %ptr.3c6 = addr_of %.loc11_16.2
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc11_16: init %empty_tuple.type = call %bound_method.loc11_16(%addr.loc11_16)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11_14: <bound method> = bound_method %.loc11_14.3, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.de7
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc11_14.3: <bound method> = bound_method %.loc11_14.3, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4
// CHECK:STDOUT: %bound_method.loc11_14.3: <bound method> = bound_method %.loc11_14.3, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3
// CHECK:STDOUT: %addr.loc11_14.2: %ptr.3c6 = addr_of %.loc11_14.3
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc11_14: init %empty_tuple.type = call %bound_method.loc11_14.3(%addr.loc11_14.2)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc11: init %empty_tuple.type = call %bound_method.loc11_14.3(%addr.loc11_14.2)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc10: <bound method> = bound_method %s.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.572
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc10: <bound method> = bound_method %s.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5
// CHECK:STDOUT: %bound_method.loc10: <bound method> = bound_method %s.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4
// CHECK:STDOUT: %addr.loc10: %ptr.5c7 = addr_of %s.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10)
// CHECK:STDOUT: <elided>
@@ -221,6 +221,7 @@ fn F() {
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.type.911: type = fn_type @ptr.as.OptionalStorage.impl.Some, @ptr.as.OptionalStorage.impl(%T.d9f) [symbolic]
// CHECK:STDOUT: %ptr.as.OptionalStorage.impl.Some.2a0: %ptr.as.OptionalStorage.impl.Some.type.911 = struct_value () [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.a64: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.236, @ptr.as.OptionalStorage.impl(Cpp.void) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet.e2a: %OptionalStorage.type = facet_value %ptr.03c, (%OptionalStorage.impl_witness.a64) [concrete]
// CHECK:STDOUT: %Optional.75d: type = class_type @Optional, @Optional(%OptionalStorage.facet.e2a) [concrete]
@@ -243,9 +244,8 @@ fn F() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.707 = facet_value %ptr.03c, (%ImplicitAs.impl_witness.354) [concrete]
// CHECK:STDOUT: %.120: type = fn_type_with_self_type %ImplicitAs.Convert.type.465, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %U.binding.as_type.as.ImplicitAs.impl.Convert.aa4, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(%OptionalStorage.facet.e2a, %OptionalAs.facet) [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Optional.75d, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.773: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
// CHECK:STDOUT: %facet_value.9af: %type_where = facet_value %Optional.75d, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.773: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.9af) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.9de: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.773 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.a68: type = ptr_type %Optional.75d [concrete]
// CHECK:STDOUT: }
@@ -289,10 +289,10 @@ fn F() {
// CHECK:STDOUT: %bound_method.loc10_11.1: <bound method> = bound_method %input.ref, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @U.binding.as_type.as.ImplicitAs.impl.Convert.2(constants.%OptionalStorage.facet.e2a, constants.%OptionalAs.facet) [concrete = constants.%U.binding.as_type.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc10_11.2: <bound method> = bound_method %input.ref, %specific_fn
// CHECK:STDOUT: %.loc10_11.1: ref %Optional.75d = temporary_storage
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.75d = call %bound_method.loc10_11.2(%input.ref) to %.loc10_11.1
// CHECK:STDOUT: %.loc10_11.2: init %Optional.75d = converted %input.ref, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc10_11.3: ref %Optional.75d = temporary %.loc10_11.1, %.loc10_11.2
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call: init %Optional.75d = call %bound_method.loc10_11.2(%input.ref)
// CHECK:STDOUT: %.loc10_11.1: init %Optional.75d = converted %input.ref, %U.binding.as_type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: %.loc10_11.2: ref %Optional.75d = temporary_storage
// CHECK:STDOUT: %.loc10_11.3: ref %Optional.75d = temporary %.loc10_11.2, %.loc10_11.1
// CHECK:STDOUT: %.loc10_11.4: %Optional.75d = acquire_value %.loc10_11.3
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc10_11.4)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc10_11.3, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.9de
@@ -365,8 +365,7 @@ fn F() {
// CHECK:STDOUT: %.loc14_35: %Optional.None.type.623 = specific_constant imports.%Core.import_ref.f1d, @Optional(constants.%OptionalStorage.facet) [concrete = constants.%Optional.None.97f]
// CHECK:STDOUT: %None.ref: %Optional.None.type.623 = name_ref None, %.loc14_35 [concrete = constants.%Optional.None.97f]
// CHECK:STDOUT: %Optional.None.specific_fn: <specific function> = specific_function %None.ref, @Optional.None(constants.%OptionalStorage.facet) [concrete = constants.%Optional.None.specific_fn]
// CHECK:STDOUT: %.loc14_41: ref %Optional.db3 = temporary_storage
// CHECK:STDOUT: %Optional.None.call: init %Optional.db3 = call %Optional.None.specific_fn() to %.loc14_41
// CHECK:STDOUT: %Optional.None.call: init %Optional.db3 = call %Optional.None.specific_fn()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -381,6 +380,8 @@ fn F() {
// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %ptr.4f0: type = ptr_type %T.d9f [symbolic]
// CHECK:STDOUT: %MaybeUnformed.cff: type = class_type @MaybeUnformed, @MaybeUnformed(%ptr.4f0) [symbolic]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %OptionalStorage.impl_witness.e1a: <witness> = impl_witness imports.%OptionalStorage.impl_witness_table.2f8, @ptr.as.OptionalStorage.impl(Cpp.void) [concrete]
// CHECK:STDOUT: %OptionalStorage.facet: %OptionalStorage.type = facet_value %ptr.03c, (%OptionalStorage.impl_witness.e1a) [concrete]
// CHECK:STDOUT: %Optional.af8: type = class_type @Optional, @Optional(%OptionalStorage.facet) [concrete]
@@ -389,10 +390,8 @@ fn F() {
// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Optional.af8, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d7f: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
// CHECK:STDOUT: %facet_value.2d8: %type_where = facet_value %Optional.af8, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d7f: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.2d8) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.7ff: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d7f = struct_value () [concrete]
// CHECK:STDOUT: %ptr.ee2: type = ptr_type %Optional.af8 [concrete]
// CHECK:STDOUT: }
@@ -435,8 +434,7 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.ref.loc10_42: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value]
// CHECK:STDOUT: %.loc10_50.1: ref %Optional.af8 = temporary_storage
// CHECK:STDOUT: %foo.call: init %Optional.af8 = call imports.%foo.decl() to %.loc10_50.1
// CHECK:STDOUT: %foo.call: init %Optional.af8 = call imports.%foo.decl()
// CHECK:STDOUT: %.loc10_38.1: type = splice_block %Optional [concrete = constants.%Optional.af8] {
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %Optional.ref: %Optional.type = name_ref Optional, imports.%Core.Optional [concrete = constants.%Optional.generic]
@@ -447,6 +445,7 @@ fn F() {
// CHECK:STDOUT: %.loc10_38.2: %OptionalStorage.type = converted %ptr, %OptionalStorage.facet [concrete = constants.%OptionalStorage.facet]
// CHECK:STDOUT: %Optional: type = class_type @Optional, @Optional(constants.%OptionalStorage.facet) [concrete = constants.%Optional.af8]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc10_50.1: ref %Optional.af8 = temporary_storage
// CHECK:STDOUT: %.loc10_50.2: ref %Optional.af8 = temporary %.loc10_50.1, %foo.call
// CHECK:STDOUT: %.loc10_50.3: %Optional.af8 = acquire_value %.loc10_50.2
// CHECK:STDOUT: %output: %Optional.af8 = value_binding output, %.loc10_50.3
+24 -4
View File
@@ -9,10 +9,13 @@
#include "toolchain/check/cpp/import.h"
#include "toolchain/check/generic.h"
#include "toolchain/check/inst.h"
#include "toolchain/check/literal.h"
#include "toolchain/check/type.h"
#include "toolchain/diagnostics/format_providers.h"
#include "toolchain/sem_ir/constant.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/specific_named_constraint.h"
#include "toolchain/sem_ir/type_info.h"
#include "toolchain/sem_ir/typed_insts.h"
namespace Carbon::Check {
@@ -625,11 +628,28 @@ auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
}
auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
SemIR::MaybeUnformedType /*inst*/) const
SemIR::MaybeUnformedType inst) const
-> SemIR::CompleteTypeInfo {
// `MaybeUnformed(T)` always has a pointer value representation, regardless of
// `T`'s value representation.
return {.value_repr = MakePointerValueRepr(type_id)};
// `MaybeUnformed(T)` has the same value representation as `T` if that value
// representation preserves all the bytes of the value, including any padding
// bits. Otherwise we need to use a different representation.
auto inner_type_id = context_->types().GetTypeIdForTypeInstId(inst.inner_id);
auto nested = GetNestedInfo(inner_type_id);
if (nested.value_repr.kind == SemIR::ValueRepr::Custom) {
nested.value_repr = MakePointerValueRepr(type_id);
} else if (nested.value_repr.kind == SemIR::ValueRepr::Copy) {
auto type_inst = context_->types().GetAsInst(nested.value_repr.type_id);
// TODO: Should ValueRepr::IsCopyOfObjectRepr return false for `bool`?
if (!nested.value_repr.IsCopyOfObjectRepr(context_->sem_ir(),
inner_type_id) ||
type_inst.Is<SemIR::BoolType>()) {
nested.value_repr = MakePointerValueRepr(type_id);
}
// TODO: Handle any other types that we treat as having discarded padding
// bits. For now there are no such types, as all class types and all structs
// and tuples with more than one element are passed indirectly.
}
return nested;
}
auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
+5 -11
View File
@@ -470,22 +470,16 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id,
}
case SemIR::BuiltinFunctionKind::PointerMakeNull: {
// MaybeUnformed(T*) has an in-place initializing representation, so an
// out parameter will be passed.
context.builder().CreateStore(
llvm::ConstantPointerNull::get(
llvm::PointerType::get(context.llvm_context(),
/*AddressSpace=*/0)),
context.GetValue(arg_ids[0]));
context.SetLocal(inst_id,
llvm::PoisonValue::get(context.GetTypeOfInst(inst_id)));
llvm::ConstantPointerNull::get(
llvm::PointerType::get(context.llvm_context(),
/*AddressSpace=*/0)));
return;
}
case SemIR::BuiltinFunctionKind::PointerIsNull: {
auto* ptr = context.builder().CreateLoad(
context.GetTypeOfInst(arg_ids[0]), context.GetValue(arg_ids[0]));
context.SetLocal(inst_id, context.builder().CreateIsNull(ptr));
context.SetLocal(inst_id, context.builder().CreateIsNull(
context.GetValue(arg_ids[0])));
return;
}
+118 -39
View File
@@ -12,72 +12,136 @@
fn MaybeUnformedBuiltin(t: type) -> type = "maybe_unformed.make_type";
fn TakeBuiltin(x: MaybeUnformedBuiltin(i32)) {}
fn MakeBuiltin() -> MaybeUnformedBuiltin(i32);
fn TakeI32(x: MaybeUnformedBuiltin(i32)) {}
fn MakeI32() -> MaybeUnformedBuiltin(i32);
fn PassBuiltin() {
// This is passed by pointer even though `i32` would generally be passed in
// registers.
TakeBuiltin(MakeBuiltin());
fn TakeBool(x: MaybeUnformedBuiltin(bool)) {}
fn MakeBool() -> MaybeUnformedBuiltin(bool);
fn PassI32() {
// This is passed by value, as that preserves all the bits.
TakeI32(MakeI32());
}
// Also test that an adapter wrapped around the builtin behaves the same.
fn PassBool() {
// This is passed by pointer to preserve all the bits.
TakeBool(MakeBool());
}
fn ConvertBoolToUnformedBool(var b: bool) {
TakeBool(b);
}
// Also test that an adapter wrapped around the builtin is passed appropriately,
// using the same calling convention as the adapted type.
class MaybeUnformedAdapter(T:! type) {
adapt MaybeUnformedBuiltin(T);
}
fn TakeAdapter(x: MaybeUnformedAdapter(i32)) {}
fn MakeAdapter() -> MaybeUnformedAdapter(i32);
fn TakeAdapterI32(x: MaybeUnformedAdapter(i32)) {}
fn MakeAdapterI32() -> MaybeUnformedAdapter(i32);
fn PassAdapter() {
TakeAdapter(MakeAdapter());
fn PassAdapterI32() {
// TODO: The `value_of_initializer` optimization doesn't get used here, so we
// unnecessarily round-trip this value through memory.
TakeAdapterI32(MakeAdapterI32());
}
fn TakeAdapterBool(x: MaybeUnformedAdapter(bool)) {}
fn MakeAdapterBool() -> MaybeUnformedAdapter(bool);
fn PassAdapterBool() {
TakeAdapterBool(MakeAdapterBool());
}
// CHECK:STDOUT: ; ModuleID = 'maybe_unformed.carbon'
// CHECK:STDOUT: source_filename = "maybe_unformed.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CTakeBuiltin.Main(ptr %x) #0 !dbg !4 {
// CHECK:STDOUT: define void @_CTakeI32.Main(i32 %x) #0 !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !7
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CMakeBuiltin.Main(ptr sret(i32))
// CHECK:STDOUT: declare i32 @_CMakeI32.Main()
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassBuiltin.Main() #0 !dbg !8 {
// CHECK:STDOUT: define void @_CTakeBool.Main(ptr %x) #0 !dbg !8 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc21_27.1.temp = alloca i32, align 4, !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc21_27.1.temp), !dbg !9
// CHECK:STDOUT: call void @_CMakeBuiltin.Main(ptr %.loc21_27.1.temp), !dbg !9
// CHECK:STDOUT: call void @_CTakeBuiltin.Main(ptr %.loc21_27.1.temp), !dbg !10
// CHECK:STDOUT: ret void, !dbg !11
// CHECK:STDOUT: ret void, !dbg !9
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CMakeBool.Main(ptr sret(i1))
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CTakeAdapter.Main(ptr %x) #0 !dbg !12 {
// CHECK:STDOUT: define void @_CPassI32.Main() #0 !dbg !10 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %MakeI32.call = call i32 @_CMakeI32.Main(), !dbg !11
// CHECK:STDOUT: call void @_CTakeI32.Main(i32 %MakeI32.call), !dbg !12
// CHECK:STDOUT: ret void, !dbg !13
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CMakeAdapter.Main(ptr sret(i32))
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassBool.Main() #0 !dbg !14 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc28_21.1.temp = alloca i1, align 1, !dbg !15
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc28_21.1.temp), !dbg !15
// CHECK:STDOUT: call void @_CMakeBool.Main(ptr %.loc28_21.1.temp), !dbg !15
// CHECK:STDOUT: call void @_CTakeBool.Main(ptr %.loc28_21.1.temp), !dbg !16
// CHECK:STDOUT: ret void, !dbg !17
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassAdapter.Main() #0 !dbg !14 {
// CHECK:STDOUT: define void @_CConvertBoolToUnformedBool.Main(ptr %b) #0 !dbg !18 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc34_27.1.temp = alloca i32, align 4, !dbg !15
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc34_27.1.temp), !dbg !15
// CHECK:STDOUT: call void @_CMakeAdapter.Main(ptr %.loc34_27.1.temp), !dbg !15
// CHECK:STDOUT: call void @_CTakeAdapter.Main(ptr %.loc34_27.1.temp), !dbg !16
// CHECK:STDOUT: ret void, !dbg !17
// CHECK:STDOUT: call void @_CTakeBool.Main(ptr %b), !dbg !19
// CHECK:STDOUT: ret void, !dbg !20
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CTakeAdapterI32.Main(i32 %x) #0 !dbg !21 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !22
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare i32 @_CMakeAdapterI32.Main()
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassAdapterI32.Main() #0 !dbg !23 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc48_33.1.temp = alloca i32, align 4, !dbg !24
// CHECK:STDOUT: %MakeAdapterI32.call = call i32 @_CMakeAdapterI32.Main(), !dbg !24
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc48_33.1.temp), !dbg !24
// CHECK:STDOUT: store i32 %MakeAdapterI32.call, ptr %.loc48_33.1.temp, align 4, !dbg !24
// CHECK:STDOUT: %.loc48_33.3 = load i32, ptr %.loc48_33.1.temp, align 4, !dbg !24
// CHECK:STDOUT: call void @_CTakeAdapterI32.Main(i32 %.loc48_33.3), !dbg !25
// CHECK:STDOUT: ret void, !dbg !26
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CTakeAdapterBool.Main(ptr %x) #0 !dbg !27 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !28
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_CMakeAdapterBool.Main(ptr sret(i1))
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassAdapterBool.Main() #0 !dbg !29 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc55_35.1.temp = alloca i1, align 1, !dbg !30
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc55_35.1.temp), !dbg !30
// CHECK:STDOUT: call void @_CMakeAdapterBool.Main(ptr %.loc55_35.1.temp), !dbg !30
// CHECK:STDOUT: call void @_CTakeAdapterBool.Main(ptr %.loc55_35.1.temp), !dbg !31
// CHECK:STDOUT: ret void, !dbg !32
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -89,17 +153,32 @@ fn PassAdapter() {
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "maybe_unformed.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "TakeBuiltin", linkageName: "_CTakeBuiltin.Main", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "TakeI32", linkageName: "_CTakeI32.Main", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 15, column: 1, scope: !4)
// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "PassBuiltin", linkageName: "_CPassBuiltin.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !9 = !DILocation(line: 21, column: 15, scope: !8)
// CHECK:STDOUT: !10 = !DILocation(line: 21, column: 3, scope: !8)
// CHECK:STDOUT: !11 = !DILocation(line: 18, column: 1, scope: !8)
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "TakeAdapter", linkageName: "_CTakeAdapter.Main", scope: null, file: !3, line: 30, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !13 = !DILocation(line: 30, column: 1, scope: !12)
// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "PassAdapter", linkageName: "_CPassAdapter.Main", scope: null, file: !3, line: 33, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !15 = !DILocation(line: 34, column: 15, scope: !14)
// CHECK:STDOUT: !16 = !DILocation(line: 34, column: 3, scope: !14)
// CHECK:STDOUT: !17 = !DILocation(line: 33, column: 1, scope: !14)
// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "TakeBool", linkageName: "_CTakeBool.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 1, scope: !8)
// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "PassI32", linkageName: "_CPassI32.Main", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !11 = !DILocation(line: 23, column: 11, scope: !10)
// CHECK:STDOUT: !12 = !DILocation(line: 23, column: 3, scope: !10)
// CHECK:STDOUT: !13 = !DILocation(line: 21, column: 1, scope: !10)
// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "PassBool", linkageName: "_CPassBool.Main", scope: null, file: !3, line: 26, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !15 = !DILocation(line: 28, column: 12, scope: !14)
// CHECK:STDOUT: !16 = !DILocation(line: 28, column: 3, scope: !14)
// CHECK:STDOUT: !17 = !DILocation(line: 26, column: 1, scope: !14)
// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "ConvertBoolToUnformedBool", linkageName: "_CConvertBoolToUnformedBool.Main", scope: null, file: !3, line: 31, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !19 = !DILocation(line: 32, column: 3, scope: !18)
// CHECK:STDOUT: !20 = !DILocation(line: 31, column: 1, scope: !18)
// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "TakeAdapterI32", linkageName: "_CTakeAdapterI32.Main", scope: null, file: !3, line: 42, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !22 = !DILocation(line: 42, column: 1, scope: !21)
// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "PassAdapterI32", linkageName: "_CPassAdapterI32.Main", scope: null, file: !3, line: 45, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !24 = !DILocation(line: 48, column: 18, scope: !23)
// CHECK:STDOUT: !25 = !DILocation(line: 48, column: 3, scope: !23)
// CHECK:STDOUT: !26 = !DILocation(line: 45, column: 1, scope: !23)
// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "TakeAdapterBool", linkageName: "_CTakeAdapterBool.Main", scope: null, file: !3, line: 51, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !28 = !DILocation(line: 51, column: 1, scope: !27)
// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "PassAdapterBool", linkageName: "_CPassAdapterBool.Main", scope: null, file: !3, line: 54, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !30 = !DILocation(line: 55, column: 19, scope: !29)
// CHECK:STDOUT: !31 = !DILocation(line: 55, column: 3, scope: !29)
// CHECK:STDOUT: !32 = !DILocation(line: 54, column: 1, scope: !29)
+9 -12
View File
@@ -28,18 +28,16 @@ fn Check(p: MakeUnformed(C*)) -> bool {
// CHECK:STDOUT: source_filename = "pointer.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CNull.Main(ptr sret(ptr) %return) #0 !dbg !4 {
// CHECK:STDOUT: define ptr @_CNull.Main() #0 !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: store ptr null, ptr %return, align 8, !dbg !7
// CHECK:STDOUT: ret void, !dbg !8
// CHECK:STDOUT: ret ptr null, !dbg !7
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i1 @_CCheck.Main(ptr %p) #0 !dbg !9 {
// CHECK:STDOUT: define i1 @_CCheck.Main(ptr %p) #0 !dbg !8 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %IsNull.call = load ptr, ptr %p, align 8, !dbg !10
// CHECK:STDOUT: %IsNull.call1 = icmp eq ptr %IsNull.call, null, !dbg !10
// CHECK:STDOUT: ret i1 %IsNull.call1, !dbg !11
// CHECK:STDOUT: %IsNull.call = icmp eq ptr %p, null, !dbg !9
// CHECK:STDOUT: ret i1 %IsNull.call, !dbg !10
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
@@ -54,8 +52,7 @@ fn Check(p: MakeUnformed(C*)) -> bool {
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Null", linkageName: "_CNull.Main", scope: null, file: !3, line: 19, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 20, column: 10, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 20, column: 3, scope: !4)
// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "Check", linkageName: "_CCheck.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !10 = !DILocation(line: 24, column: 10, scope: !9)
// CHECK:STDOUT: !11 = !DILocation(line: 24, column: 3, scope: !9)
// CHECK:STDOUT: !7 = !DILocation(line: 20, column: 3, scope: !4)
// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "Check", linkageName: "_CCheck.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !9 = !DILocation(line: 24, column: 10, scope: !8)
// CHECK:STDOUT: !10 = !DILocation(line: 24, column: 3, scope: !8)
+58 -47
View File
@@ -68,6 +68,8 @@ fn PassPtr(p: Core.Optional(Cpp.C*)) {
}
fn PassNonnullPtr(p: Cpp.C*) {
// TODO: The `value_of_initializer` optimization doesn't get used here, so we
// unnecessarily round-trip this value through memory.
Cpp.TakePtr(p);
}
@@ -188,23 +190,25 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassNonnullPtr.Main(ptr %p) #0 !dbg !11 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc20_15.1.temp = alloca ptr, align 8, !dbg !12
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_15.1.temp), !dbg !12
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr %.loc20_15.1.temp, ptr %p), !dbg !12
// CHECK:STDOUT: call void @_Z7TakePtrP1C(ptr %.loc20_15.1.temp), !dbg !13
// CHECK:STDOUT: %.loc22_15.2.temp = alloca ptr, align 8, !dbg !12
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr %p), !dbg !12
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_15.2.temp), !dbg !12
// CHECK:STDOUT: store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc22_15.2.temp, align 8, !dbg !12
// CHECK:STDOUT: %.loc22_15.4 = load ptr, ptr %.loc22_15.2.temp, align 8, !dbg !12
// CHECK:STDOUT: call void @_Z7TakePtrP1C(ptr %.loc22_15.4), !dbg !13
// CHECK:STDOUT: ret void, !dbg !14
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_Z7TakePtrP1C(ptr)
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CReturnPtr.Main(ptr sret(ptr) %return) #0 !dbg !15 {
// CHECK:STDOUT: define ptr @_CReturnPtr.Main() #0 !dbg !15 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: call void @_Z9ReturnPtrv(ptr %return), !dbg !16
// CHECK:STDOUT: ret void, !dbg !17
// CHECK:STDOUT: %ReturnPtr.call = call ptr @_Z9ReturnPtrv(), !dbg !16
// CHECK:STDOUT: ret ptr %ReturnPtr.call, !dbg !17
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @_Z9ReturnPtrv(ptr sret(ptr))
// CHECK:STDOUT: declare ptr @_Z9ReturnPtrv()
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassPtrWithThunk.Main(ptr %p) #0 !dbg !18 {
@@ -215,45 +219,50 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CPassNonnullPtrWithThunk.Main(ptr %p) #0 !dbg !20 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc33_24.1.temp = alloca ptr, align 8, !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc33_24.1.temp), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr %.loc33_24.1.temp, ptr %p), !dbg !21
// CHECK:STDOUT: call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %.loc33_24.1.temp), !dbg !22
// CHECK:STDOUT: %.loc35_24.2.temp = alloca ptr, align 8, !dbg !21
// CHECK:STDOUT: %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr %p), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc35_24.2.temp), !dbg !21
// CHECK:STDOUT: store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc35_24.2.temp, align 8, !dbg !21
// CHECK:STDOUT: %.loc35_24.4 = load ptr, ptr %.loc35_24.2.temp, align 8, !dbg !21
// CHECK:STDOUT: call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %.loc35_24.4), !dbg !22
// CHECK:STDOUT: ret void, !dbg !23
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CReturnPtrWithThunk.Main(ptr sret(ptr) %return) #0 !dbg !24 {
// CHECK:STDOUT: define ptr @_CReturnPtrWithThunk.Main() #0 !dbg !24 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: call void @_Z18ReturnPtrWithThunki.carbon_thunk0(ptr %return), !dbg !25
// CHECK:STDOUT: ret void, !dbg !26
// CHECK:STDOUT: %ReturnPtrWithThunk__carbon_thunk.call = call ptr @_Z18ReturnPtrWithThunki.carbon_thunk0(), !dbg !25
// CHECK:STDOUT: ret ptr %ReturnPtrWithThunk__carbon_thunk.call, !dbg !26
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr %self) #0 !dbg !27 {
// CHECK:STDOUT: %1 = call ptr @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.b5eba8f3f1d9af5a"(ptr %self), !dbg !29
// CHECK:STDOUT: ret ptr %1, !dbg !30
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422"(ptr sret(ptr) %return, ptr %self) #0 !dbg !27 {
// CHECK:STDOUT: call void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.b5eba8f3f1d9af5a"(ptr %return, ptr %self), !dbg !29
// CHECK:STDOUT: ret void, !dbg !30
// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.b5eba8f3f1d9af5a"(ptr %self) #0 !dbg !31 {
// CHECK:STDOUT: %1 = call ptr @_CSome.Optional.Core.b5eba8f3f1d9af5a(ptr %self), !dbg !32
// CHECK:STDOUT: ret ptr %1, !dbg !33
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.b5eba8f3f1d9af5a"(ptr sret(ptr) %return, ptr %self) #0 !dbg !31 {
// CHECK:STDOUT: call void @_CSome.Optional.Core.b5eba8f3f1d9af5a(ptr %return, ptr %self), !dbg !32
// CHECK:STDOUT: ret void, !dbg !33
// CHECK:STDOUT: define linkonce_odr ptr @_CSome.Optional.Core.b5eba8f3f1d9af5a(ptr %value) #0 !dbg !34 {
// CHECK:STDOUT: %1 = call ptr @"_CSome.4f0b5cc38af595d2:OptionalStorage.Core.f53db17714b9f655"(ptr %value), !dbg !35
// CHECK:STDOUT: ret ptr %1, !dbg !36
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSome.Optional.Core.b5eba8f3f1d9af5a(ptr sret(ptr) %return, ptr %value) #0 !dbg !34 {
// CHECK:STDOUT: call void @"_CSome.4f0b5cc38af595d2:OptionalStorage.Core.f53db17714b9f655"(ptr %return, ptr %value), !dbg !35
// CHECK:STDOUT: ret void, !dbg !36
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CSome.4f0b5cc38af595d2:OptionalStorage.Core.f53db17714b9f655"(ptr sret(ptr) %return, ptr %self) #0 !dbg !37 {
// CHECK:STDOUT: store ptr %self, ptr %return, align 8, !dbg !38
// CHECK:STDOUT: ret void, !dbg !39
// CHECK:STDOUT: define linkonce_odr ptr @"_CSome.4f0b5cc38af595d2:OptionalStorage.Core.f53db17714b9f655"(ptr %self) #0 !dbg !37 {
// CHECK:STDOUT: %1 = alloca ptr, align 8, !dbg !38
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %1), !dbg !38
// CHECK:STDOUT: store ptr %self, ptr %1, align 8, !dbg !39
// CHECK:STDOUT: %2 = load ptr, ptr %1, align 8, !dbg !40
// CHECK:STDOUT: ret ptr %2, !dbg !41
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress
@@ -278,8 +287,8 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
// CHECK:STDOUT: declare ptr @_Z18ReturnPtrWithThunki(i32) #3
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
// CHECK:STDOUT: uselistorder ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422", { 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 2, 1 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -301,21 +310,21 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
// CHECK:STDOUT: !9 = !{}
// CHECK:STDOUT: !10 = !DILocation(line: 14, column: 1, scope: !7)
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "PassNonnullPtr", linkageName: "_CPassNonnullPtr.Main", scope: null, file: !6, line: 19, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 15, scope: !11)
// CHECK:STDOUT: !13 = !DILocation(line: 20, column: 3, scope: !11)
// CHECK:STDOUT: !12 = !DILocation(line: 22, column: 15, scope: !11)
// CHECK:STDOUT: !13 = !DILocation(line: 22, column: 3, scope: !11)
// CHECK:STDOUT: !14 = !DILocation(line: 19, column: 1, scope: !11)
// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !6, line: 23, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !16 = !DILocation(line: 24, column: 10, scope: !15)
// CHECK:STDOUT: !17 = !DILocation(line: 24, column: 3, scope: !15)
// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !6, line: 27, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !19 = !DILocation(line: 27, column: 1, scope: !18)
// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "PassNonnullPtrWithThunk", linkageName: "_CPassNonnullPtrWithThunk.Main", scope: null, file: !6, line: 32, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !21 = !DILocation(line: 33, column: 24, scope: !20)
// CHECK:STDOUT: !22 = !DILocation(line: 33, column: 3, scope: !20)
// CHECK:STDOUT: !23 = !DILocation(line: 32, column: 1, scope: !20)
// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !6, line: 36, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !25 = !DILocation(line: 37, column: 10, scope: !24)
// CHECK:STDOUT: !26 = !DILocation(line: 37, column: 3, scope: !24)
// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !6, line: 25, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !16 = !DILocation(line: 26, column: 10, scope: !15)
// CHECK:STDOUT: !17 = !DILocation(line: 26, column: 3, scope: !15)
// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !6, line: 29, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !19 = !DILocation(line: 29, column: 1, scope: !18)
// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "PassNonnullPtrWithThunk", linkageName: "_CPassNonnullPtrWithThunk.Main", scope: null, file: !6, line: 34, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !21 = !DILocation(line: 35, column: 24, scope: !20)
// CHECK:STDOUT: !22 = !DILocation(line: 35, column: 3, scope: !20)
// CHECK:STDOUT: !23 = !DILocation(line: 34, column: 1, scope: !20)
// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !6, line: 38, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !25 = !DILocation(line: 39, column: 10, scope: !24)
// CHECK:STDOUT: !26 = !DILocation(line: 39, column: 3, scope: !24)
// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.f82b7327366b1770:ImplicitAs.Core.78b0d6e062ff6422", scope: null, file: !28, line: 82, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !28 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
// CHECK:STDOUT: !29 = !DILocation(line: 83, column: 12, scope: !27)
@@ -327,5 +336,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
// CHECK:STDOUT: !35 = !DILocation(line: 30, column: 12, scope: !34)
// CHECK:STDOUT: !36 = !DILocation(line: 30, column: 5, scope: !34)
// CHECK:STDOUT: !37 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.4f0b5cc38af595d2:OptionalStorage.Core.f53db17714b9f655", scope: null, file: !28, line: 125, type: !8, spFlags: DISPFlagDefinition, unit: !5)
// CHECK:STDOUT: !38 = !DILocation(line: 127, column: 5, scope: !37)
// CHECK:STDOUT: !39 = !DILocation(line: 128, column: 5, scope: !37)
// CHECK:STDOUT: !38 = !DILocation(line: 126, column: 14, scope: !37)
// CHECK:STDOUT: !39 = !DILocation(line: 127, column: 5, scope: !37)
// CHECK:STDOUT: !40 = !DILocation(line: 126, column: 18, scope: !37)
// CHECK:STDOUT: !41 = !DILocation(line: 128, column: 5, scope: !37)
+96 -99
View File
@@ -67,25 +67,24 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coa.var), !dbg !16
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr %coa.var, i32 %a), !dbg !16
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %oca.var), !dbg !17
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %oca.var, i32 %a), !dbg !17
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.17894abe4ff6869d"(ptr %oca.var, i32 %a), !dbg !17
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coca.var), !dbg !18
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %coca.var, i32 %a), !dbg !18
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.9702cf0ed9564406"(ptr %coca.var, i32 %a), !dbg !18
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %ob.var), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.7bf331f068e9c2df"(ptr %ob.var, i32 %b), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %cob.var), !dbg !20
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.af35f070baa4994b"(ptr %cob.var, i32 %b), !dbg !20
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %ocb.var), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr %ocb.var, i32 %b), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.9702cf0ed9564406"(ptr %ocb.var, i32 %b), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %cocb.var), !dbg !22
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr %cocb.var, i32 %b), !dbg !22
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.44c1f37bfbfb88a3"(ptr %cocb.var, i32 %b), !dbg !22
// CHECK:STDOUT: ret void, !dbg !23
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i1 @_CHasValue.Optional.Core.217efae529e578bc(ptr %self) #0 !dbg !24 {
// CHECK:STDOUT: %1 = load ptr, ptr %self, align 8, !dbg !26
// CHECK:STDOUT: %2 = icmp eq ptr %1, null, !dbg !26
// CHECK:STDOUT: ret i1 %2, !dbg !27
// CHECK:STDOUT: %1 = icmp eq ptr %self, null, !dbg !26
// CHECK:STDOUT: ret i1 %1, !dbg !27
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
@@ -118,16 +117,16 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !41 {
// CHECK:STDOUT: call void @"_CConvert.9d11af2db03b082d:OptionalAs.Core.f6268c15480add99"(ptr %return, i32 %self), !dbg !42
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.17894abe4ff6869d"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !41 {
// CHECK:STDOUT: call void @"_CConvert.9d11af2db03b082d:OptionalAs.Core.19e2d83267c24030"(ptr %return, i32 %self), !dbg !42
// CHECK:STDOUT: ret void, !dbg !43
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !44 {
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.9702cf0ed9564406"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !44 {
// CHECK:STDOUT: %temp = alloca { i32, i1 }, align 8, !dbg !45
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %temp), !dbg !45
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %temp, i32 %self), !dbg !45
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.17894abe4ff6869d"(ptr %temp, i32 %self), !dbg !45
// CHECK:STDOUT: ret void, !dbg !46
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -144,94 +143,93 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !53 {
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %return, i32 %self), !dbg !54
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.9702cf0ed9564406"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !53 {
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.17894abe4ff6869d"(ptr %return, i32 %self), !dbg !54
// CHECK:STDOUT: ret void, !dbg !55
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !56 {
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %return, i32 %self), !dbg !57
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.44c1f37bfbfb88a3"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !56 {
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.9702cf0ed9564406"(ptr %return, i32 %self), !dbg !57
// CHECK:STDOUT: ret void, !dbg !58
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr ptr @"_CGet.4f0b5cc38af595d2:OptionalStorage.Core.b88d1103f417c6d4"(ptr %value) #0 !dbg !59 {
// CHECK:STDOUT: %1 = load ptr, ptr %value, align 8, !dbg !60
// CHECK:STDOUT: ret ptr %1, !dbg !61
// CHECK:STDOUT: ret ptr %value, !dbg !60
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !62 {
// CHECK:STDOUT: call void @_CSome.Optional.Core.f16306f3d30b9711(ptr %return, i32 %self), !dbg !63
// CHECK:STDOUT: ret void, !dbg !64
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !61 {
// CHECK:STDOUT: call void @_CSome.Optional.Core.f16306f3d30b9711(ptr %return, i32 %self), !dbg !62
// CHECK:STDOUT: ret void, !dbg !63
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CNone.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr sret({ i32, i1 }) %return) #0 !dbg !65 {
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !66
// CHECK:STDOUT: store i8 0, ptr %has_value, align 1, !dbg !66
// CHECK:STDOUT: ret void, !dbg !67
// CHECK:STDOUT: define linkonce_odr void @"_CNone.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr sret({ i32, i1 }) %return) #0 !dbg !64 {
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !65
// CHECK:STDOUT: store i8 0, ptr %has_value, align 1, !dbg !65
// CHECK:STDOUT: ret void, !dbg !66
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.9d11af2db03b082d:OptionalAs.Core.f6268c15480add99"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !68 {
// CHECK:STDOUT: %temp = alloca i32, align 4, !dbg !69
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %temp), !dbg !69
// CHECK:STDOUT: %1 = call i32 @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff"(i32 %self), !dbg !69
// CHECK:STDOUT: store i32 %1, ptr %temp, align 4, !dbg !69
// CHECK:STDOUT: %2 = load i32, ptr %temp, align 4, !dbg !69
// CHECK:STDOUT: call void @_CSome.Optional.Core.9427236976e7a9ec(ptr %return, i32 %2), !dbg !70
// CHECK:STDOUT: ret void, !dbg !71
// CHECK:STDOUT: define linkonce_odr void @"_CConvert.9d11af2db03b082d:OptionalAs.Core.19e2d83267c24030"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !67 {
// CHECK:STDOUT: %temp = alloca i32, align 4, !dbg !68
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %temp), !dbg !68
// CHECK:STDOUT: %1 = call i32 @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff"(i32 %self), !dbg !68
// CHECK:STDOUT: store i32 %1, ptr %temp, align 4, !dbg !68
// CHECK:STDOUT: %2 = load i32, ptr %temp, align 4, !dbg !68
// CHECK:STDOUT: call void @_CSome.Optional.Core.9427236976e7a9ec(ptr %return, i32 %2), !dbg !69
// CHECK:STDOUT: ret void, !dbg !70
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSome.Optional.Core.f16306f3d30b9711(ptr sret({ i32, i1 }) %return, i32 %value) #0 !dbg !72 {
// CHECK:STDOUT: call void @"_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr %return, i32 %value), !dbg !73
// CHECK:STDOUT: ret void, !dbg !74
// CHECK:STDOUT: define linkonce_odr void @_CSome.Optional.Core.f16306f3d30b9711(ptr sret({ i32, i1 }) %return, i32 %value) #0 !dbg !71 {
// CHECK:STDOUT: call void @"_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr %return, i32 %value), !dbg !72
// CHECK:STDOUT: ret void, !dbg !73
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff"(i32 %self) #0 !dbg !75 {
// CHECK:STDOUT: %temp = alloca i32, align 4, !dbg !76
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %temp), !dbg !76
// CHECK:STDOUT: %1 = call i32 @"_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899"(i32 %self), !dbg !76
// CHECK:STDOUT: ret i32 %1, !dbg !77
// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff"(i32 %self) #0 !dbg !74 {
// CHECK:STDOUT: %temp = alloca i32, align 4, !dbg !75
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %temp), !dbg !75
// CHECK:STDOUT: %1 = call i32 @"_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899"(i32 %self), !dbg !75
// CHECK:STDOUT: ret i32 %1, !dbg !76
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSome.Optional.Core.9427236976e7a9ec(ptr sret({ i32, i1 }) %return, i32 %value) #0 !dbg !78 {
// CHECK:STDOUT: call void @"_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053"(ptr %return, i32 %value), !dbg !79
// CHECK:STDOUT: ret void, !dbg !80
// CHECK:STDOUT: define linkonce_odr void @_CSome.Optional.Core.9427236976e7a9ec(ptr sret({ i32, i1 }) %return, i32 %value) #0 !dbg !77 {
// CHECK:STDOUT: call void @"_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053"(ptr %return, i32 %value), !dbg !78
// CHECK:STDOUT: ret void, !dbg !79
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !81 {
// CHECK:STDOUT: %value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 0, !dbg !82
// CHECK:STDOUT: store i32 %self, ptr %value, align 4, !dbg !82
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !83
// CHECK:STDOUT: store i8 1, ptr %has_value, align 1, !dbg !83
// CHECK:STDOUT: ret void, !dbg !84
// CHECK:STDOUT: define linkonce_odr void @"_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !80 {
// CHECK:STDOUT: %value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 0, !dbg !81
// CHECK:STDOUT: store i32 %self, ptr %value, align 4, !dbg !81
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !82
// CHECK:STDOUT: store i8 1, ptr %has_value, align 1, !dbg !82
// CHECK:STDOUT: ret void, !dbg !83
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899"(i32 %self) #0 !dbg !85 {
// CHECK:STDOUT: ret i32 %self, !dbg !86
// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899"(i32 %self) #0 !dbg !84 {
// CHECK:STDOUT: ret i32 %self, !dbg !85
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @"_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !87 {
// CHECK:STDOUT: %value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 0, !dbg !88
// CHECK:STDOUT: %1 = call i32 @"_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899"(i32 %self), !dbg !89
// CHECK:STDOUT: store i32 %1, ptr %value, align 4, !dbg !88
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !90
// CHECK:STDOUT: store i8 1, ptr %has_value, align 1, !dbg !90
// CHECK:STDOUT: ret void, !dbg !91
// CHECK:STDOUT: define linkonce_odr void @"_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !86 {
// CHECK:STDOUT: %value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 0, !dbg !87
// CHECK:STDOUT: %1 = call i32 @"_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899"(i32 %self), !dbg !88
// CHECK:STDOUT: store i32 %1, ptr %value, align 4, !dbg !87
// CHECK:STDOUT: %has_value = getelementptr inbounds nuw { i32, i1 }, ptr %return, i32 0, i32 1, !dbg !89
// CHECK:STDOUT: store i8 1, ptr %has_value, align 1, !dbg !89
// CHECK:STDOUT: ret void, !dbg !90
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899"(i32 %self) #0 !dbg !92 {
// CHECK:STDOUT: ret i32 %self, !dbg !94
// CHECK:STDOUT: define linkonce_odr i32 @"_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899"(i32 %self) #0 !dbg !91 {
// CHECK:STDOUT: ret i32 %self, !dbg !93
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
@@ -285,10 +283,10 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: !38 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
// CHECK:STDOUT: !39 = !DILocation(line: 28, column: 45, scope: !37)
// CHECK:STDOUT: !40 = !DILocation(line: 28, column: 38, scope: !37)
// CHECK:STDOUT: !41 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999", scope: null, file: !25, line: 82, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !41 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.f82b7327366b1770:ImplicitAs.Core.17894abe4ff6869d", scope: null, file: !25, line: 82, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !42 = !DILocation(line: 83, column: 12, scope: !41)
// CHECK:STDOUT: !43 = !DILocation(line: 83, column: 5, scope: !41)
// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27", scope: null, file: !38, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.ab0f2d07242360d7:ImplicitAs.Core.9702cf0ed9564406", scope: null, file: !38, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !45 = !DILocation(line: 28, column: 45, scope: !44)
// CHECK:STDOUT: !46 = !DILocation(line: 28, column: 38, scope: !44)
// CHECK:STDOUT: !47 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.7bf331f068e9c2df", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
@@ -297,45 +295,44 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: !50 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.af35f070baa4994b", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !51 = !DILocation(line: 32, column: 45, scope: !50)
// CHECK:STDOUT: !52 = !DILocation(line: 32, column: 38, scope: !50)
// CHECK:STDOUT: !53 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !53 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.9702cf0ed9564406", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !54 = !DILocation(line: 32, column: 45, scope: !53)
// CHECK:STDOUT: !55 = !DILocation(line: 32, column: 38, scope: !53)
// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.4a889a7251a91071:ImplicitAs.Core.44c1f37bfbfb88a3", scope: null, file: !38, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !57 = !DILocation(line: 32, column: 45, scope: !56)
// CHECK:STDOUT: !58 = !DILocation(line: 32, column: 38, scope: !56)
// CHECK:STDOUT: !59 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.4f0b5cc38af595d2:OptionalStorage.Core.b88d1103f417c6d4", scope: null, file: !25, line: 131, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !60 = !DILocation(line: 132, column: 12, scope: !59)
// CHECK:STDOUT: !61 = !DILocation(line: 132, column: 5, scope: !59)
// CHECK:STDOUT: !62 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711", scope: null, file: !25, line: 68, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !63 = !DILocation(line: 69, column: 12, scope: !62)
// CHECK:STDOUT: !64 = !DILocation(line: 69, column: 5, scope: !62)
// CHECK:STDOUT: !65 = distinct !DISubprogram(name: "None", linkageName: "_CNone.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899", scope: null, file: !25, line: 99, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !66 = !DILocation(line: 101, column: 5, scope: !65)
// CHECK:STDOUT: !67 = !DILocation(line: 102, column: 5, scope: !65)
// CHECK:STDOUT: !68 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.9d11af2db03b082d:OptionalAs.Core.f6268c15480add99", scope: null, file: !25, line: 75, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !69 = !DILocation(line: 76, column: 29, scope: !68)
// CHECK:STDOUT: !70 = !DILocation(line: 76, column: 12, scope: !68)
// CHECK:STDOUT: !71 = !DILocation(line: 76, column: 5, scope: !68)
// CHECK:STDOUT: !72 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.f16306f3d30b9711", scope: null, file: !25, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !73 = !DILocation(line: 30, column: 12, scope: !72)
// CHECK:STDOUT: !74 = !DILocation(line: 30, column: 5, scope: !72)
// CHECK:STDOUT: !75 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff", scope: null, file: !38, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !76 = !DILocation(line: 28, column: 45, scope: !75)
// CHECK:STDOUT: !77 = !DILocation(line: 28, column: 38, scope: !75)
// CHECK:STDOUT: !78 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.9427236976e7a9ec", scope: null, file: !25, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !79 = !DILocation(line: 30, column: 12, scope: !78)
// CHECK:STDOUT: !80 = !DILocation(line: 30, column: 5, scope: !78)
// CHECK:STDOUT: !81 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899", scope: null, file: !25, line: 104, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !82 = !DILocation(line: 108, column: 5, scope: !81)
// CHECK:STDOUT: !83 = !DILocation(line: 109, column: 5, scope: !81)
// CHECK:STDOUT: !84 = !DILocation(line: 110, column: 5, scope: !81)
// CHECK:STDOUT: !85 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899", scope: null, file: !38, line: 24, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !86 = !DILocation(line: 24, column: 38, scope: !85)
// CHECK:STDOUT: !87 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053", scope: null, file: !25, line: 104, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !88 = !DILocation(line: 108, column: 5, scope: !87)
// CHECK:STDOUT: !89 = !DILocation(line: 108, column: 28, scope: !87)
// CHECK:STDOUT: !90 = !DILocation(line: 109, column: 5, scope: !87)
// CHECK:STDOUT: !91 = !DILocation(line: 110, column: 5, scope: !87)
// CHECK:STDOUT: !92 = distinct !DISubprogram(name: "Op", linkageName: "_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899", scope: null, file: !93, line: 19, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !93 = !DIFile(filename: "{{.*}}/prelude/copy.carbon", directory: "")
// CHECK:STDOUT: !94 = !DILocation(line: 19, column: 33, scope: !92)
// CHECK:STDOUT: !60 = !DILocation(line: 132, column: 5, scope: !59)
// CHECK:STDOUT: !61 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711", scope: null, file: !25, line: 68, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !62 = !DILocation(line: 69, column: 12, scope: !61)
// CHECK:STDOUT: !63 = !DILocation(line: 69, column: 5, scope: !61)
// CHECK:STDOUT: !64 = distinct !DISubprogram(name: "None", linkageName: "_CNone.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899", scope: null, file: !25, line: 99, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !65 = !DILocation(line: 101, column: 5, scope: !64)
// CHECK:STDOUT: !66 = !DILocation(line: 102, column: 5, scope: !64)
// CHECK:STDOUT: !67 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.9d11af2db03b082d:OptionalAs.Core.19e2d83267c24030", scope: null, file: !25, line: 75, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !68 = !DILocation(line: 76, column: 29, scope: !67)
// CHECK:STDOUT: !69 = !DILocation(line: 76, column: 12, scope: !67)
// CHECK:STDOUT: !70 = !DILocation(line: 76, column: 5, scope: !67)
// CHECK:STDOUT: !71 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.f16306f3d30b9711", scope: null, file: !25, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !72 = !DILocation(line: 30, column: 12, scope: !71)
// CHECK:STDOUT: !73 = !DILocation(line: 30, column: 5, scope: !71)
// CHECK:STDOUT: !74 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.ab0f2d07242360d7:ImplicitAs.Core.f9a27c9a1900a4ff", scope: null, file: !38, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !75 = !DILocation(line: 28, column: 45, scope: !74)
// CHECK:STDOUT: !76 = !DILocation(line: 28, column: 38, scope: !74)
// CHECK:STDOUT: !77 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.9427236976e7a9ec", scope: null, file: !25, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !78 = !DILocation(line: 30, column: 12, scope: !77)
// CHECK:STDOUT: !79 = !DILocation(line: 30, column: 5, scope: !77)
// CHECK:STDOUT: !80 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.225258f1a45e9386:OptionalStorage.Core.5450dc8e8b8e0899", scope: null, file: !25, line: 104, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !81 = !DILocation(line: 108, column: 5, scope: !80)
// CHECK:STDOUT: !82 = !DILocation(line: 109, column: 5, scope: !80)
// CHECK:STDOUT: !83 = !DILocation(line: 110, column: 5, scope: !80)
// CHECK:STDOUT: !84 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.225258f1a45e9386:ImplicitAs.Core.5450dc8e8b8e0899", scope: null, file: !38, line: 24, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !85 = !DILocation(line: 24, column: 38, scope: !84)
// CHECK:STDOUT: !86 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.225258f1a45e9386:OptionalStorage.Core.ae62e7630b150053", scope: null, file: !25, line: 104, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !87 = !DILocation(line: 108, column: 5, scope: !86)
// CHECK:STDOUT: !88 = !DILocation(line: 108, column: 28, scope: !86)
// CHECK:STDOUT: !89 = !DILocation(line: 109, column: 5, scope: !86)
// CHECK:STDOUT: !90 = !DILocation(line: 110, column: 5, scope: !86)
// CHECK:STDOUT: !91 = distinct !DISubprogram(name: "Op", linkageName: "_COp.14f25726eade61db:Copy.Core.5450dc8e8b8e0899", scope: null, file: !92, line: 19, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !92 = !DIFile(filename: "{{.*}}/prelude/copy.carbon", directory: "")
// CHECK:STDOUT: !93 = !DILocation(line: 19, column: 33, scope: !91)