Fix initialization of a variable via an ImplicitAs conversion. (#6327)

We used to generate initialization to a temporary instead, and leave the
variable uninitialized.
This commit is contained in:
Richard Smith
2025-11-05 21:05:34 +00:00
committed by GitHub
parent 8166f9a7cf
commit f2e98c2047
6 changed files with 162 additions and 118 deletions
+4 -3
View File
@@ -1451,6 +1451,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
if (expr_id == SemIR::ErrorInst::InstId) {
return expr_id;
}
bool performed_builtin_conversion = expr_id != orig_expr_id;
// Defer the action if it's dependent. We do this now rather than before
// attempting any conversion so that we can still perform builtin conversions
@@ -1552,10 +1553,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
case SemIR::ExprCategory::Initializing:
if (target.is_initializer()) {
if (orig_expr_id == expr_id) {
if (!performed_builtin_conversion) {
// Don't fill in the return slot if we created the expression through
// a conversion. In that case, we will have created it with the
// target already set.
// a builtin conversion. In that case, we will have created it with
// the target already set.
// TODO: Find a better way to track whether we need to do this.
MarkInitializerFor(sem_ir, expr_id, target);
}
+79
View File
@@ -0,0 +1,79 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/as/var_init.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/as/var_init.carbon
// --- var_init.carbon
library "[[@TEST_NAME]]";
class X {
impl () as Core.ImplicitAs(X) {
fn Convert[self: ()]() -> X { return {}; }
}
}
fn Convert(t: ()) {
//@dump-sem-ir-begin
var x: X = ();
//@dump-sem-ir-end
}
// CHECK:STDOUT: --- var_init.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %ImplicitAs.type.179: type = facet_type <@ImplicitAs, @ImplicitAs(%X)> [concrete]
// CHECK:STDOUT: %ImplicitAs.Convert.type.665: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%X) [concrete]
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness @X.%ImplicitAs.impl_witness_table [concrete]
// CHECK:STDOUT: %pattern_type.019: type = pattern_type %X [concrete]
// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.type: type = fn_type @empty_tuple.type.as.ImplicitAs.impl.Convert [concrete]
// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert: %empty_tuple.type.as.ImplicitAs.impl.Convert.type = struct_value () [concrete]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.179 = facet_value %empty_tuple.type, (%ImplicitAs.impl_witness) [concrete]
// CHECK:STDOUT: %.f5e: type = fn_type_with_self_type %ImplicitAs.Convert.type.665, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %X, () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.bd5: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.1c8: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.bd5 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Convert(%t.param: %empty_tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %x.patt: %pattern_type.019 = ref_binding_pattern x [concrete]
// CHECK:STDOUT: %x.var_patt: %pattern_type.019 = var_pattern %x.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x.var: ref %X = var %x.var_patt
// CHECK:STDOUT: %.loc12_15.1: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %impl.elem0: %.f5e = impl_witness_access constants.%ImplicitAs.impl_witness, element0 [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert]
// CHECK:STDOUT: %bound_method.loc12_3.1: <bound method> = bound_method %.loc12_15.1, %impl.elem0
// CHECK:STDOUT: %.loc12_3.1: ref %X = splice_block %x.var {}
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc12_15.2: %empty_tuple.type = converted %.loc12_15.1, %empty_tuple [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.call: init %X = call %bound_method.loc12_3.1(%.loc12_15.2) to %.loc12_3.1
// CHECK:STDOUT: %.loc12_3.2: init %X = converted %.loc12_15.1, %empty_tuple.type.as.ImplicitAs.impl.Convert.call
// CHECK:STDOUT: assign %x.var, %.loc12_3.2
// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %x: ref %X = ref_binding x, %x.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %x.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.1c8
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc12_3.2: <bound method> = bound_method %x.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.d17 = addr_of %x.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc12_3.2(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -1048,16 +1048,16 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc7_26.1: ref %C.b00 = converted %.loc7_24.1, %.loc7_24.4
// CHECK:STDOUT: %impl.elem0.loc7_35: %.e33 = impl_witness_access constants.%ImplicitAs.impl_witness.541, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.43b]
// CHECK:STDOUT: %bound_method.loc7_35: <bound method> = bound_method %.loc7_26.1, %impl.elem0.loc7_35
// CHECK:STDOUT: %.loc7_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.1: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc7_26.2: %C.b00 = acquire_value %.loc7_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35(%.loc7_26.2) to %.loc7_35.1
// CHECK:STDOUT: %.loc7_35.2: init %D = converted %.loc7_26.1, %C.as.ImplicitAs.impl.Convert.call.loc7
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35(%.loc7_26.2) to %.loc6_15.1
// CHECK:STDOUT: %.loc7_35: init %D = converted %.loc7_26.1, %C.as.ImplicitAs.impl.Convert.call.loc7
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc7_24.1: <bound method> = bound_method %.loc7_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.9ed
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.9ed, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.e56) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.67c]
// CHECK:STDOUT: %bound_method.loc7_24.1: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1
// CHECK:STDOUT: %addr.loc7_24.1: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.1: init %empty_tuple.type = call %bound_method.loc7_24.1(%addr.loc7_24.1)
// CHECK:STDOUT: return %.loc7_35.2 to %return
// CHECK:STDOUT: return %.loc7_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc7:
// CHECK:STDOUT: %false.loc8: bool = bool_literal false [concrete = constants.%false]
@@ -1082,10 +1082,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc8_26.1: ref %C.674 = converted %.loc8_24.1, %.loc8_24.4
// CHECK:STDOUT: %impl.elem0.loc8_35: %.5da = impl_witness_access constants.%ImplicitAs.impl_witness.371, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.e68]
// CHECK:STDOUT: %bound_method.loc8_35: <bound method> = bound_method %.loc8_26.1, %impl.elem0.loc8_35
// CHECK:STDOUT: %.loc8_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.2: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc8_26.2: %C.674 = acquire_value %.loc8_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35(%.loc8_26.2) to %.loc8_35.1
// CHECK:STDOUT: %.loc8_35.2: init %D = converted %.loc8_26.1, %C.as.ImplicitAs.impl.Convert.call.loc8
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35(%.loc8_26.2) to %.loc6_15.2
// CHECK:STDOUT: %.loc8_35: init %D = converted %.loc8_26.1, %C.as.ImplicitAs.impl.Convert.call.loc8
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc8_24.1: <bound method> = bound_method %.loc8_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d98
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d98, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.4dd) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.466]
// CHECK:STDOUT: %bound_method.loc8_24.1: <bound method> = bound_method %.loc8_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2
@@ -1096,7 +1096,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.2: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3
// CHECK:STDOUT: %addr.loc7_24.2: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.2: init %empty_tuple.type = call %bound_method.loc7_24.2(%addr.loc7_24.2)
// CHECK:STDOUT: return %.loc8_35.2 to %return
// CHECK:STDOUT: return %.loc8_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc8:
// CHECK:STDOUT: %false.loc9: bool = bool_literal false [concrete = constants.%false]
@@ -1121,10 +1121,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc9_26.1: ref %C.681 = converted %.loc9_24.1, %.loc9_24.4
// CHECK:STDOUT: %impl.elem0.loc9_35: %.b2b = impl_witness_access constants.%ImplicitAs.impl_witness.2a3, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.cb1]
// CHECK:STDOUT: %bound_method.loc9_35: <bound method> = bound_method %.loc9_26.1, %impl.elem0.loc9_35
// CHECK:STDOUT: %.loc9_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.3: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc9_26.2: %C.681 = acquire_value %.loc9_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35(%.loc9_26.2) to %.loc9_35.1
// CHECK:STDOUT: %.loc9_35.2: init %D = converted %.loc9_26.1, %C.as.ImplicitAs.impl.Convert.call.loc9
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35(%.loc9_26.2) to %.loc6_15.3
// CHECK:STDOUT: %.loc9_35: init %D = converted %.loc9_26.1, %C.as.ImplicitAs.impl.Convert.call.loc9
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc9_24.1: <bound method> = bound_method %.loc9_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.ce4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.ce4, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.7fe) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cfd]
// CHECK:STDOUT: %bound_method.loc9_24.1: <bound method> = bound_method %.loc9_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4
@@ -1140,7 +1140,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.3: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.6
// CHECK:STDOUT: %addr.loc7_24.3: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.3: init %empty_tuple.type = call %bound_method.loc7_24.3(%addr.loc7_24.3)
// CHECK:STDOUT: return %.loc9_35.2 to %return
// CHECK:STDOUT: return %.loc9_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc9:
// CHECK:STDOUT: %false.loc10: bool = bool_literal false [concrete = constants.%false]
@@ -1165,10 +1165,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc10_26.1: ref %C.7ac = converted %.loc10_24.1, %.loc10_24.4
// CHECK:STDOUT: %impl.elem0.loc10_35: %.11b = impl_witness_access constants.%ImplicitAs.impl_witness.29c, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.67e]
// CHECK:STDOUT: %bound_method.loc10_35: <bound method> = bound_method %.loc10_26.1, %impl.elem0.loc10_35
// CHECK:STDOUT: %.loc10_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.4: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc10_26.2: %C.7ac = acquire_value %.loc10_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35(%.loc10_26.2) to %.loc10_35.1
// CHECK:STDOUT: %.loc10_35.2: init %D = converted %.loc10_26.1, %C.as.ImplicitAs.impl.Convert.call.loc10
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35(%.loc10_26.2) to %.loc6_15.4
// CHECK:STDOUT: %.loc10_35: init %D = converted %.loc10_26.1, %C.as.ImplicitAs.impl.Convert.call.loc10
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc10_24.1: <bound method> = bound_method %.loc10_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.931
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.7: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.931, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.99b) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.20a]
// CHECK:STDOUT: %bound_method.loc10_24.1: <bound method> = bound_method %.loc10_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.7
@@ -1189,7 +1189,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.4: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.10
// CHECK:STDOUT: %addr.loc7_24.4: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.4: init %empty_tuple.type = call %bound_method.loc7_24.4(%addr.loc7_24.4)
// CHECK:STDOUT: return %.loc10_35.2 to %return
// CHECK:STDOUT: return %.loc10_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc10:
// CHECK:STDOUT: %false.loc11: bool = bool_literal false [concrete = constants.%false]
@@ -1214,10 +1214,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc11_26.1: ref %C.89d = converted %.loc11_24.1, %.loc11_24.4
// CHECK:STDOUT: %impl.elem0.loc11_35: %.0dc = impl_witness_access constants.%ImplicitAs.impl_witness.565, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.58d]
// CHECK:STDOUT: %bound_method.loc11_35: <bound method> = bound_method %.loc11_26.1, %impl.elem0.loc11_35
// CHECK:STDOUT: %.loc11_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.5: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc11_26.2: %C.89d = acquire_value %.loc11_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35(%.loc11_26.2) to %.loc11_35.1
// CHECK:STDOUT: %.loc11_35.2: init %D = converted %.loc11_26.1, %C.as.ImplicitAs.impl.Convert.call.loc11
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35(%.loc11_26.2) to %.loc6_15.5
// CHECK:STDOUT: %.loc11_35: init %D = converted %.loc11_26.1, %C.as.ImplicitAs.impl.Convert.call.loc11
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11_24.1: <bound method> = bound_method %.loc11_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d47
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.11: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d47, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.b4c) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.fe8]
// CHECK:STDOUT: %bound_method.loc11_24.1: <bound method> = bound_method %.loc11_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.11
@@ -1243,7 +1243,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.5: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.15
// CHECK:STDOUT: %addr.loc7_24.5: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.5: init %empty_tuple.type = call %bound_method.loc7_24.5(%addr.loc7_24.5)
// CHECK:STDOUT: return %.loc11_35.2 to %return
// CHECK:STDOUT: return %.loc11_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc11:
// CHECK:STDOUT: %false.loc12: bool = bool_literal false [concrete = constants.%false]
@@ -1268,10 +1268,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc12_26.1: ref %C.f0a = converted %.loc12_24.1, %.loc12_24.4
// CHECK:STDOUT: %impl.elem0.loc12_35: %.332 = impl_witness_access constants.%ImplicitAs.impl_witness.c1a, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.a45]
// CHECK:STDOUT: %bound_method.loc12_35: <bound method> = bound_method %.loc12_26.1, %impl.elem0.loc12_35
// CHECK:STDOUT: %.loc12_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.6: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc12_26.2: %C.f0a = acquire_value %.loc12_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35(%.loc12_26.2) to %.loc12_35.1
// CHECK:STDOUT: %.loc12_35.2: init %D = converted %.loc12_26.1, %C.as.ImplicitAs.impl.Convert.call.loc12
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35(%.loc12_26.2) to %.loc6_15.6
// CHECK:STDOUT: %.loc12_35: init %D = converted %.loc12_26.1, %C.as.ImplicitAs.impl.Convert.call.loc12
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc12_24.1: <bound method> = bound_method %.loc12_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.217
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.16: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.217, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.430) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.bcb]
// CHECK:STDOUT: %bound_method.loc12_24.1: <bound method> = bound_method %.loc12_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.16
@@ -1302,7 +1302,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.6: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.21
// CHECK:STDOUT: %addr.loc7_24.6: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.6: init %empty_tuple.type = call %bound_method.loc7_24.6(%addr.loc7_24.6)
// CHECK:STDOUT: return %.loc12_35.2 to %return
// CHECK:STDOUT: return %.loc12_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc12:
// CHECK:STDOUT: %false.loc13: bool = bool_literal false [concrete = constants.%false]
@@ -1327,10 +1327,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc13_26.1: ref %C.c60 = converted %.loc13_24.1, %.loc13_24.4
// CHECK:STDOUT: %impl.elem0.loc13_35: %.1bb = impl_witness_access constants.%ImplicitAs.impl_witness.ebf, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.ad0]
// CHECK:STDOUT: %bound_method.loc13_35: <bound method> = bound_method %.loc13_26.1, %impl.elem0.loc13_35
// CHECK:STDOUT: %.loc13_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.7: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc13_26.2: %C.c60 = acquire_value %.loc13_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35(%.loc13_26.2) to %.loc13_35.1
// CHECK:STDOUT: %.loc13_35.2: init %D = converted %.loc13_26.1, %C.as.ImplicitAs.impl.Convert.call.loc13
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35(%.loc13_26.2) to %.loc6_15.7
// CHECK:STDOUT: %.loc13_35: init %D = converted %.loc13_26.1, %C.as.ImplicitAs.impl.Convert.call.loc13
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc13_24.1: <bound method> = bound_method %.loc13_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.bf7
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.22: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.bf7, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.14a) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5e9]
// CHECK:STDOUT: %bound_method.loc13_24.1: <bound method> = bound_method %.loc13_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.22
@@ -1366,7 +1366,7 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.7: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.28
// CHECK:STDOUT: %addr.loc7_24.7: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.7: init %empty_tuple.type = call %bound_method.loc7_24.7(%addr.loc7_24.7)
// CHECK:STDOUT: return %.loc13_35.2 to %return
// CHECK:STDOUT: return %.loc13_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc13:
// CHECK:STDOUT: %false.loc14: bool = bool_literal false [concrete = constants.%false]
@@ -1391,10 +1391,10 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %.loc14_26.1: ref %C.304 = converted %.loc14_24.1, %.loc14_24.4
// CHECK:STDOUT: %impl.elem0.loc14_35: %.bc1 = impl_witness_access constants.%ImplicitAs.impl_witness.b93, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.9be]
// CHECK:STDOUT: %bound_method.loc14_35: <bound method> = bound_method %.loc14_26.1, %impl.elem0.loc14_35
// CHECK:STDOUT: %.loc14_35.1: ref %D = temporary_storage
// CHECK:STDOUT: %.loc6_15.8: ref %D = splice_block %return {}
// CHECK:STDOUT: %.loc14_26.2: %C.304 = acquire_value %.loc14_26.1
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35(%.loc14_26.2) to %.loc14_35.1
// CHECK:STDOUT: %.loc14_35.2: init %D = converted %.loc14_26.1, %C.as.ImplicitAs.impl.Convert.call.loc14
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35(%.loc14_26.2) to %.loc6_15.8
// CHECK:STDOUT: %.loc14_35: init %D = converted %.loc14_26.1, %C.as.ImplicitAs.impl.Convert.call.loc14
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc14_24.1: <bound method> = bound_method %.loc14_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.29: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.488) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.eb6]
// CHECK:STDOUT: %bound_method.loc14_24.1: <bound method> = bound_method %.loc14_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.29
@@ -1435,13 +1435,13 @@ fn F0(n: i32) -> P.D {
// CHECK:STDOUT: %bound_method.loc7_24.8: <bound method> = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.36
// CHECK:STDOUT: %addr.loc7_24.8: %ptr.697 = addr_of %.loc7_24.4
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.8: init %empty_tuple.type = call %bound_method.loc7_24.8(%addr.loc7_24.8)
// CHECK:STDOUT: return %.loc14_35.2 to %return
// CHECK:STDOUT: return %.loc14_35 to %return
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc14:
// CHECK:STDOUT: %P.ref.loc15: <namespace> = name_ref P, imports.%P [concrete = imports.%P]
// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, imports.%P.Make [concrete = constants.%Make]
// CHECK:STDOUT: %.loc6_15: ref %D = splice_block %return {}
// CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc6_15
// CHECK:STDOUT: %.loc6_15.9: ref %D = splice_block %return {}
// CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc6_15.9
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc14_24.2: <bound method> = bound_method %.loc14_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.37: <specific function> = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.488) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.eb6]
// CHECK:STDOUT: %bound_method.loc14_24.2: <bound method> = bound_method %.loc14_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.37
+8 -16
View File
@@ -104,13 +104,11 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19
// CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20
// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !20
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20
// CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.2.temp), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: ret void, !dbg !19
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -118,7 +116,7 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { alwaysinline nounwind }
@@ -157,14 +155,12 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: %.loc7_20.1.temp = alloca { i32 }, align 8, !dbg !7
// CHECK:STDOUT: %.loc7_20.2.temp = alloca { i32 }, align 8, !dbg !7
// CHECK:STDOUT: %.loc7_19.1.temp = alloca { i32 }, align 8, !dbg !8
// CHECK:STDOUT: %.loc7_21.1.temp = alloca { i32 }, align 8, !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_20.1.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_20.2.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_19.1.temp), !dbg !8
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc7_19.1.temp, ptr %a), !dbg !8
// CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc7_20.2.temp, ptr %.loc7_19.1.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_21.1.temp), !dbg !9
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc7_21.1.temp, ptr %.loc7_20.2.temp), !dbg !9
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc7_20.2.temp), !dbg !9
// CHECK:STDOUT: ret void, !dbg !9
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -180,7 +176,7 @@ fn Test(a: A) -> C {
// 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, { 3, 2, 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) }
@@ -216,13 +212,11 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc9_19.1.temp = alloca { i32 }, align 8, !dbg !11
// CHECK:STDOUT: %.2.temp = alloca { i32 }, align 8
// CHECK:STDOUT: %.loc9_19.2.temp = alloca { i32 }, align 8, !dbg !11
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_19.1.temp), !dbg !11
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.2.temp)
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.2.temp, ptr %a), !dbg !12
// CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc9_19.1.temp, ptr %.2.temp), !dbg !11
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_19.2.temp), !dbg !11
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc9_19.2.temp, ptr %.loc9_19.1.temp), !dbg !11
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc9_19.1.temp), !dbg !11
// CHECK:STDOUT: ret void, !dbg !11
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -234,7 +228,7 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { alwaysinline nounwind }
@@ -265,14 +259,12 @@ fn Test(a: A) -> C {
// CHECK:STDOUT: %.loc8_19.1.temp = alloca { i32 }, align 8, !dbg !7
// CHECK:STDOUT: %.loc8_19.2.temp = alloca { i32 }, align 8, !dbg !7
// CHECK:STDOUT: %.loc8_18.1.temp = alloca { i32 }, align 8, !dbg !8
// CHECK:STDOUT: %.loc8_20.1.temp = alloca { i32 }, align 8, !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_19.1.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_19.2.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_18.1.temp), !dbg !8
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc8_18.1.temp, ptr %a), !dbg !8
// CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc8_19.2.temp, ptr %.loc8_18.1.temp), !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_20.1.temp), !dbg !9
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc8_20.1.temp, ptr %.loc8_19.2.temp), !dbg !9
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc8_19.2.temp), !dbg !9
// CHECK:STDOUT: ret void, !dbg !9
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -288,7 +280,7 @@ fn Test(a: A) -> C {
// 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, { 3, 2, 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) }
+6 -14
View File
@@ -108,13 +108,11 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19
// CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20
// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !20
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20
// CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.2.temp), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !19
// CHECK:STDOUT: ret void, !dbg !19
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -124,14 +122,12 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: %.loc24_20.1.temp = alloca { i32 }, align 8, !dbg !22
// CHECK:STDOUT: %.loc24_20.2.temp = alloca { i32 }, align 8, !dbg !22
// CHECK:STDOUT: %.loc24_19.1.temp = alloca { i32 }, align 8, !dbg !23
// CHECK:STDOUT: %.loc24_21.1.temp = alloca { i32 }, align 8, !dbg !24
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_20.1.temp), !dbg !22
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_20.2.temp), !dbg !22
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_19.1.temp), !dbg !23
// CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc24_19.1.temp, ptr %a), !dbg !23
// CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc24_20.2.temp, ptr %.loc24_19.1.temp), !dbg !22
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_21.1.temp), !dbg !24
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc24_21.1.temp, ptr %.loc24_20.2.temp), !dbg !24
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc24_20.2.temp), !dbg !24
// CHECK:STDOUT: ret void, !dbg !24
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -139,7 +135,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 6, 5, 4, 3, 2, 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 4, 3, 2, 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { alwaysinline nounwind }
@@ -193,7 +189,6 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: %.loc22_23.3.temp = alloca {}, align 8, !dbg !9
// CHECK:STDOUT: %.loc22_23.7.temp = alloca {}, align 8, !dbg !9
// CHECK:STDOUT: %.loc22_22.1.temp = alloca {}, align 8, !dbg !10
// CHECK:STDOUT: %.loc22_24.1.temp = alloca {}, align 8, !dbg !11
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_23.1.temp), !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_23.3.temp), !dbg !9
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !9
@@ -201,8 +196,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_22.1.temp), !dbg !10
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_22.1.temp, ptr %b), !dbg !10
// CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc22_23.7.temp, ptr %c, ptr %.loc22_22.1.temp), !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_24.1.temp), !dbg !11
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_24.1.temp, ptr %.loc22_23.7.temp), !dbg !11
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc22_23.7.temp), !dbg !11
// CHECK:STDOUT: ret void, !dbg !11
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -239,20 +233,18 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
// CHECK:STDOUT: %.loc18_31.2.temp = alloca {}, align 8, !dbg !21
// CHECK:STDOUT: %.loc18_31.6.temp = alloca {}, align 8, !dbg !21
// CHECK:STDOUT: %.loc12_21.1.temp = alloca {}, align 8, !dbg !22
// CHECK:STDOUT: %.loc18_31.7.temp = alloca {}, align 8, !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.2.temp), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.6.temp), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc12_21.1.temp), !dbg !22
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc12_21.1.temp, ptr %x), !dbg !22
// CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc18_31.6.temp, ptr %self, ptr %.loc12_21.1.temp), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.7.temp), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.7.temp, ptr %.loc18_31.6.temp), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc18_31.6.temp), !dbg !21
// CHECK:STDOUT: ret void, !dbg !21
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 8, 7, 6, 5, 4 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 6, 5, 4, 3 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+31 -51
View File
@@ -21,8 +21,6 @@ fn Convert(o: Core.Optional(i32*)) -> Core.Optional(i32) {
}
fn AddOrRemoveConst(a: i32, b: const i32) {
// TODO: The code generated for these conversions is wrong: we initialize a
// temporary rather than the local variable.
var oa: Core.Optional(i32) = a;
var coa: const Core.Optional(i32) = a;
var oca: Core.Optional(const i32) = a;
@@ -39,16 +37,14 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CConvert.Main(ptr sret({ i32, i1 }) %return, ptr %o) #0 !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc18_20.1.temp = alloca { i32, i1 }, align 8, !dbg !7
// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.217efae529e578bc(ptr %o), !dbg !8
// CHECK:STDOUT: br i1 %Optional.HasValue.call, label %if.then, label %if.else, !dbg !9
// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.217efae529e578bc(ptr %o), !dbg !7
// CHECK:STDOUT: br i1 %Optional.HasValue.call, label %if.then, label %if.else, !dbg !8
// CHECK:STDOUT:
// CHECK:STDOUT: if.then: ; preds = %entry
// CHECK:STDOUT: %Optional.Get.call = call ptr @_CGet.Optional.Core.217efae529e578bc(ptr %o), !dbg !10
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_20.1.temp), !dbg !7
// CHECK:STDOUT: %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !11
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %.loc18_20.1.temp, i32 %.loc18_12.2), !dbg !7
// CHECK:STDOUT: ret void, !dbg !7
// CHECK:STDOUT: %Optional.Get.call = call ptr @_CGet.Optional.Core.217efae529e578bc(ptr %o), !dbg !9
// CHECK:STDOUT: %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !10
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %return, i32 %.loc18_12.2), !dbg !11
// CHECK:STDOUT: ret void, !dbg !11
// CHECK:STDOUT:
// CHECK:STDOUT: if.else: ; preds = %entry
// CHECK:STDOUT: call void @_CNone.Optional.Core.f16306f3d30b9711(ptr %return), !dbg !12
@@ -59,45 +55,29 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: define void @_CAddOrRemoveConst.Main(i32 %a, i32 %b) #0 !dbg !14 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %oa.var = alloca { i32, i1 }, align 8, !dbg !15
// CHECK:STDOUT: %.loc26_3.1.temp = alloca { i32, i1 }, align 8, !dbg !15
// CHECK:STDOUT: %coa.var = alloca { i32, i1 }, align 8, !dbg !16
// CHECK:STDOUT: %.loc27_3.1.temp = alloca { i32, i1 }, align 8, !dbg !16
// CHECK:STDOUT: %oca.var = alloca { i32, i1 }, align 8, !dbg !17
// CHECK:STDOUT: %.loc28_3.1.temp = alloca { i32, i1 }, align 8, !dbg !17
// CHECK:STDOUT: %coca.var = alloca { i32, i1 }, align 8, !dbg !18
// CHECK:STDOUT: %.loc29_3.1.temp = alloca { i32, i1 }, align 8, !dbg !18
// CHECK:STDOUT: %ob.var = alloca { i32, i1 }, align 8, !dbg !19
// CHECK:STDOUT: %.loc30_3.1.temp = alloca { i32, i1 }, align 8, !dbg !19
// CHECK:STDOUT: %cob.var = alloca { i32, i1 }, align 8, !dbg !20
// CHECK:STDOUT: %.loc31_3.1.temp = alloca { i32, i1 }, align 8, !dbg !20
// CHECK:STDOUT: %ocb.var = alloca { i32, i1 }, align 8, !dbg !21
// CHECK:STDOUT: %.loc32_3.1.temp = alloca { i32, i1 }, align 8, !dbg !21
// CHECK:STDOUT: %cocb.var = alloca { i32, i1 }, align 8, !dbg !22
// CHECK:STDOUT: %.loc33_3.1.temp = alloca { i32, i1 }, align 8, !dbg !22
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %oa.var), !dbg !15
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc26_3.1.temp), !dbg !15
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %.loc26_3.1.temp, i32 %a), !dbg !15
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %oa.var, i32 %a), !dbg !15
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coa.var), !dbg !16
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc27_3.1.temp), !dbg !16
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr %.loc27_3.1.temp, i32 %a), !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 @llvm.lifetime.start.p0(ptr %.loc28_3.1.temp), !dbg !17
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %.loc28_3.1.temp, i32 %a), !dbg !17
// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %oca.var, i32 %a), !dbg !17
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coca.var), !dbg !18
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc29_3.1.temp), !dbg !18
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %.loc29_3.1.temp, i32 %a), !dbg !18
// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %coca.var, i32 %a), !dbg !18
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %ob.var), !dbg !19
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc30_3.1.temp), !dbg !19
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.7bf331f068e9c2df"(ptr %.loc30_3.1.temp, i32 %b), !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 @llvm.lifetime.start.p0(ptr %.loc31_3.1.temp), !dbg !20
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.af35f070baa4994b"(ptr %.loc31_3.1.temp, i32 %b), !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 @llvm.lifetime.start.p0(ptr %.loc32_3.1.temp), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr %.loc32_3.1.temp, i32 %b), !dbg !21
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr %ocb.var, i32 %b), !dbg !21
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %cocb.var), !dbg !22
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc33_3.1.temp), !dbg !22
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr %.loc33_3.1.temp, i32 %b), !dbg !22
// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr %cocb.var, i32 %b), !dbg !22
// CHECK:STDOUT: ret void, !dbg !23
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -114,9 +94,6 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// 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.dbc2dba5c3cff15b"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !31 {
// CHECK:STDOUT: call void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711"(ptr %return, i32 %self), !dbg !32
@@ -129,6 +106,9 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: ret void, !dbg !36
// 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.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !37 {
// CHECK:STDOUT: %temp = alloca { i32, i1 }, align 8, !dbg !39
@@ -255,8 +235,8 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 }
// CHECK:STDOUT: uselistorder ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b", { 0, 1, 3, 2 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -271,22 +251,22 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.Main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 18, column: 5, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 17, column: 7, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 17, column: 6, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 13, scope: !4)
// CHECK:STDOUT: !11 = !DILocation(line: 18, column: 12, scope: !4)
// CHECK:STDOUT: !7 = !DILocation(line: 17, column: 7, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 17, column: 6, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 13, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 12, scope: !4)
// CHECK:STDOUT: !11 = !DILocation(line: 18, column: 5, scope: !4)
// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 10, scope: !4)
// CHECK:STDOUT: !13 = !DILocation(line: 20, column: 3, scope: !4)
// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "AddOrRemoveConst", linkageName: "_CAddOrRemoveConst.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !15 = !DILocation(line: 26, column: 3, scope: !14)
// CHECK:STDOUT: !16 = !DILocation(line: 27, column: 3, scope: !14)
// CHECK:STDOUT: !17 = !DILocation(line: 28, column: 3, scope: !14)
// CHECK:STDOUT: !18 = !DILocation(line: 29, column: 3, scope: !14)
// CHECK:STDOUT: !19 = !DILocation(line: 30, column: 3, scope: !14)
// CHECK:STDOUT: !20 = !DILocation(line: 31, column: 3, scope: !14)
// CHECK:STDOUT: !21 = !DILocation(line: 32, column: 3, scope: !14)
// CHECK:STDOUT: !22 = !DILocation(line: 33, column: 3, scope: !14)
// CHECK:STDOUT: !15 = !DILocation(line: 24, column: 3, scope: !14)
// CHECK:STDOUT: !16 = !DILocation(line: 25, column: 3, scope: !14)
// CHECK:STDOUT: !17 = !DILocation(line: 26, column: 3, scope: !14)
// CHECK:STDOUT: !18 = !DILocation(line: 27, column: 3, scope: !14)
// CHECK:STDOUT: !19 = !DILocation(line: 28, column: 3, scope: !14)
// CHECK:STDOUT: !20 = !DILocation(line: 29, column: 3, scope: !14)
// CHECK:STDOUT: !21 = !DILocation(line: 30, column: 3, scope: !14)
// CHECK:STDOUT: !22 = !DILocation(line: 31, column: 3, scope: !14)
// CHECK:STDOUT: !23 = !DILocation(line: 23, column: 1, scope: !14)
// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "HasValue", linkageName: "_CHasValue.Optional.Core.217efae529e578bc", scope: null, file: !25, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !25 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")