Skip to content

Commit d60900c

Browse files
authored
Remove special case for returning value expressions by copy (#6052)
When returning a value from a function whose return type has a by-copy initializing representation, perform initialization like we do when the return type has an in-place initializing representation. This makes our SemIR representation more uniform, as the return expression will now always be an initializing expression rather than a value expression, but more importantly it means that attempts to return a non-copyable type by value now fail, even if the type has a by-copy initializing representation. This catches a bunch of places where we were returning a value of an unconstrained template parameter `T:! type`, which we were incorrectly allowing because we didn't notice it was not copyable. Unfortunately this then requires quite a few test updates. Like #6034, this exposes a lowering issue where lowering crashes when attempting to lower a specific copy operation for certain types; a couple more tests are temporarily disabled here. An upcoming PR dependent on this one will fix the issue and re-enable those tests.
1 parent 896ef4d commit d60900c

File tree

231 files changed

+8685
-9063
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+8685
-9063
lines changed

core/prelude/copy.carbon

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ private fn CharLiteral() -> type = "char_literal.make_type";
1515
private fn FloatLiteral() -> type = "float_literal.make_type";
1616
private fn IntLiteral() -> type = "int_literal.make_type";
1717

18+
impl forall [T:! Copy] const T as Copy {
19+
fn Op[self: Self]() -> Self { return (self as T).(Copy.Op)() as const T; }
20+
}
21+
1822
impl Bool() as Copy {
1923
fn Op[self: Self]() -> Self = "primitive_copy";
2024
}
@@ -55,3 +59,9 @@ impl forall [T:! Copy, U:! Copy] (T, U) as Copy {
5559
return (self.0.Op(), self.1.Op());
5660
}
5761
}
62+
63+
impl forall [T:! Copy, U:! Copy, V:! Copy] (T, U, V) as Copy {
64+
fn Op[self: Self]() -> Self {
65+
return (self.0.Op(), self.1.Op(), self.2.Op());
66+
}
67+
}

core/prelude/operators/as.carbon

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package Core library "prelude/operators/as";
66

7+
import library "prelude/copy";
8+
79
interface UnsafeAs(Dest:! type) {
810
fn Convert[self: Self]() -> Dest;
911
}
@@ -18,7 +20,6 @@ interface ImplicitAs(Dest:! type) {
1820
fn Convert[self: Self]() -> Dest;
1921
}
2022

21-
// TODO: This should only apply to copyable types.
22-
impl forall [T:! type] T as ImplicitAs(T) {
23-
fn Convert[self: Self]() -> Self { return self; }
23+
impl forall [T:! Copy] T as ImplicitAs(T) {
24+
fn Convert[self: Self]() -> Self { return self.(Copy.Op)(); }
2425
}

core/prelude/types/string.carbon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package Core library "prelude/types/string";
66

7+
import library "prelude/copy";
78
import library "prelude/destroy";
89
import library "prelude/types/char";
910
import library "prelude/types/uint";

toolchain/check/return.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,10 @@ auto BuildReturnWithExpr(Context& context, SemIR::LocId loc_id,
157157
// We already diagnosed that the return type is invalid. Don't try to
158158
// convert to it.
159159
expr_id = SemIR::ErrorInst::InstId;
160-
} else if (return_info.has_return_slot()) {
160+
} else {
161161
return_slot_id = GetCurrentReturnSlot(context);
162162
CARBON_CHECK(return_slot_id.has_value());
163163
expr_id = Initialize(context, loc_id, return_slot_id, expr_id);
164-
} else {
165-
expr_id =
166-
ConvertToValueOfType(context, loc_id, expr_id, return_info.type_id);
167164
}
168165

169166
AddReturnCleanupBlockWithExpr(

toolchain/check/testdata/alias/export_name.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ var d: D* = &c;
341341
// CHECK:STDOUT: %Main.import_ref.8db: <witness> = import_ref Main//export_orig, inst24 [indirect], loaded [concrete = constants.%complete_type.357]
342342
// CHECK:STDOUT: %Main.import_ref.6a9 = import_ref Main//export_orig, inst25 [indirect], unloaded
343343
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type]
344-
// CHECK:STDOUT: %Core.import_ref.de9: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.f23) = import_ref Core//prelude/parts/copy, loc32_31, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.abf)]
344+
// CHECK:STDOUT: %Core.import_ref.de9: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.f23) = import_ref Core//prelude/parts/copy, loc36_31, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.abf)]
345345
// CHECK:STDOUT: %Copy.impl_witness_table.a71 = impl_witness_table (%Core.import_ref.de9), @ptr.as.Copy.impl [concrete]
346346
// CHECK:STDOUT: }
347347
// CHECK:STDOUT:

toolchain/check/testdata/array/import.carbon

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,31 @@ fn F() -> array(i32, 1) {
6262
// CHECK:STDOUT: constants {
6363
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
6464
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
65+
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic]
6566
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
6667
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
6768
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
6869
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete]
6970
// CHECK:STDOUT: %array_type: type = array_type %int_42, %i32 [concrete]
7071
// CHECK:STDOUT: %ptr.830: type = ptr_type %array_type [concrete]
72+
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
73+
// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete]
74+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.857: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
75+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.6aa: %Int.as.Copy.impl.Op.type.857 = struct_value () [symbolic]
76+
// CHECK:STDOUT: %Copy.impl_witness.f0b: <witness> = impl_witness imports.%Copy.impl_witness_table.f59, @Int.as.Copy.impl(%int_32) [concrete]
77+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.af5: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
78+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.87e: %Int.as.Copy.impl.Op.type.af5 = struct_value () [concrete]
79+
// CHECK:STDOUT: %Copy.facet.26d: %Copy.type = facet_value %i32, (%Copy.impl_witness.f0b) [concrete]
80+
// CHECK:STDOUT: %.3c4: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet.26d [concrete]
81+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.87e, @Int.as.Copy.impl.Op(%int_32) [concrete]
7182
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.886: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete]
7283
// CHECK:STDOUT: %T.as.Destroy.impl.Op.923: %T.as.Destroy.impl.Op.type.886 = struct_value () [concrete]
7384
// CHECK:STDOUT: }
7485
// CHECK:STDOUT:
7586
// CHECK:STDOUT: imports {
7687
// CHECK:STDOUT: %Main.F: %F.type = import_ref Main//library, F, loaded [concrete = constants.%F]
88+
// CHECK:STDOUT: %Core.import_ref.b3c: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.857) = import_ref Core//prelude/parts/int, loc17_31, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.6aa)]
89+
// CHECK:STDOUT: %Copy.impl_witness_table.f59 = impl_witness_table (%Core.import_ref.b3c), @Int.as.Copy.impl [concrete]
7790
// CHECK:STDOUT: }
7891
// CHECK:STDOUT:
7992
// CHECK:STDOUT: fn @G(%n.param: %i32) -> %i32 {
@@ -87,12 +100,17 @@ fn F() -> array(i32, 1) {
87100
// CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
88101
// CHECK:STDOUT: %.loc6_15.1: ref %i32 = array_index %.loc6_12.2, %n.ref
89102
// CHECK:STDOUT: %.loc6_15.2: %i32 = bind_value %.loc6_15.1
103+
// CHECK:STDOUT: %impl.elem0: %.3c4 = impl_witness_access constants.%Copy.impl_witness.f0b, element0 [concrete = constants.%Int.as.Copy.impl.Op.87e]
104+
// CHECK:STDOUT: %bound_method.loc6_15.1: <bound method> = bound_method %.loc6_15.2, %impl.elem0
105+
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
106+
// CHECK:STDOUT: %bound_method.loc6_15.2: <bound method> = bound_method %.loc6_15.2, %specific_fn
107+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_15.2(%.loc6_15.2)
90108
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc6_12.2, constants.%T.as.Destroy.impl.Op.923
91109
// CHECK:STDOUT: <elided>
92-
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc6_12.2, %T.as.Destroy.impl.Op.specific_fn
110+
// CHECK:STDOUT: %bound_method.loc6_12: <bound method> = bound_method %.loc6_12.2, %T.as.Destroy.impl.Op.specific_fn
93111
// CHECK:STDOUT: %addr: %ptr.830 = addr_of %.loc6_12.2
94-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
95-
// CHECK:STDOUT: return %.loc6_15.2
112+
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc6_12(%addr)
113+
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return
96114
// CHECK:STDOUT: }
97115
// CHECK:STDOUT:
98116
// CHECK:STDOUT: --- fail_todo_import_symbolic_decl.carbon

toolchain/check/testdata/array/index_not_literal.carbon

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,26 @@ fn F(a: array({}, 3)) -> {} {
5151
// CHECK:STDOUT: constants {
5252
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
5353
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
54+
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic]
5455
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
5556
// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete]
5657
// CHECK:STDOUT: %array_type: type = array_type %int_3.1ba, %i32 [concrete]
5758
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
5859
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
5960
// CHECK:STDOUT: %ptr.f01: type = ptr_type %array_type [concrete]
61+
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
62+
// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete]
63+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.857: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
64+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.6aa: %Int.as.Copy.impl.Op.type.857 = struct_value () [symbolic]
65+
// CHECK:STDOUT: %Copy.impl_witness.f0b: <witness> = impl_witness imports.%Copy.impl_witness_table.f59, @Int.as.Copy.impl(%int_32) [concrete]
66+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.af5: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
67+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.87e: %Int.as.Copy.impl.Op.type.af5 = struct_value () [concrete]
68+
// CHECK:STDOUT: %Copy.facet.26d: %Copy.type = facet_value %i32, (%Copy.impl_witness.f0b) [concrete]
69+
// CHECK:STDOUT: %.3c4: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet.26d [concrete]
70+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.87e, @Int.as.Copy.impl.Op(%int_32) [concrete]
6071
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
6172
// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete]
62-
// CHECK:STDOUT: %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete]
73+
// CHECK:STDOUT: %tuple.type.37f: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete]
6374
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
6475
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
6576
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
@@ -87,6 +98,8 @@ fn F(a: array({}, 3)) -> {} {
8798
// CHECK:STDOUT: }
8899
// CHECK:STDOUT:
89100
// CHECK:STDOUT: imports {
101+
// CHECK:STDOUT: %Core.import_ref.b3c: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.857) = import_ref Core//prelude/parts/int, loc17_31, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.6aa)]
102+
// CHECK:STDOUT: %Copy.impl_witness_table.f59 = impl_witness_table (%Core.import_ref.b3c), @Int.as.Copy.impl [concrete]
90103
// CHECK:STDOUT: %Core.import_ref.428: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.49e) = import_ref Core//prelude/parts/int, loc23_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f01)]
91104
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.b6b = impl_witness_table (%Core.import_ref.428), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
92105
// CHECK:STDOUT: }
@@ -100,7 +113,12 @@ fn F(a: array({}, 3)) -> {} {
100113
// CHECK:STDOUT: %.loc4_15.1: ref %array_type = value_as_ref %arr.ref
101114
// CHECK:STDOUT: %.loc4_15.2: ref %i32 = array_index %.loc4_15.1, %i.ref
102115
// CHECK:STDOUT: %.loc4_15.3: %i32 = bind_value %.loc4_15.2
103-
// CHECK:STDOUT: return %.loc4_15.3
116+
// CHECK:STDOUT: %impl.elem0: %.3c4 = impl_witness_access constants.%Copy.impl_witness.f0b, element0 [concrete = constants.%Int.as.Copy.impl.Op.87e]
117+
// CHECK:STDOUT: %bound_method.loc4_15.1: <bound method> = bound_method %.loc4_15.3, %impl.elem0
118+
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
119+
// CHECK:STDOUT: %bound_method.loc4_15.2: <bound method> = bound_method %.loc4_15.3, %specific_fn
120+
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc4_15.2(%.loc4_15.3)
121+
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return
104122
// CHECK:STDOUT: }
105123
// CHECK:STDOUT:
106124
// CHECK:STDOUT: fn @G() -> %i32 {
@@ -109,7 +127,7 @@ fn F(a: array({}, 3)) -> {} {
109127
// CHECK:STDOUT: %int_1.loc10_13: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
110128
// CHECK:STDOUT: %int_2.loc10_16: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
111129
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
112-
// CHECK:STDOUT: %.loc10_20.1: %tuple.type = tuple_literal (%int_1.loc10_13, %int_2.loc10_16, %int_3)
130+
// CHECK:STDOUT: %.loc10_20.1: %tuple.type.37f = tuple_literal (%int_1.loc10_13, %int_2.loc10_16, %int_3)
113131
// CHECK:STDOUT: %int_1.loc10_23: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
114132
// CHECK:STDOUT: %impl.elem0.loc10_20.1: %.7ea = impl_witness_access constants.%ImplicitAs.impl_witness.acc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.592]
115133
// CHECK:STDOUT: %bound_method.loc10_20.1: <bound method> = bound_method %int_1.loc10_13, %impl.elem0.loc10_20.1 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.a02]
@@ -151,14 +169,12 @@ fn F(a: array({}, 3)) -> {} {
151169
// CHECK:STDOUT: %.loc10_23.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_23 [concrete = constants.%int_1.5d2]
152170
// CHECK:STDOUT: %.loc10_23.2: %i32 = converted %int_1.loc10_23, %.loc10_23.1 [concrete = constants.%int_1.5d2]
153171
// CHECK:STDOUT: %F.call: init %i32 = call %F.ref(%.loc10_20.15, %.loc10_23.2)
154-
// CHECK:STDOUT: %.loc10_25.1: %i32 = value_of_initializer %F.call
155-
// CHECK:STDOUT: %.loc10_25.2: %i32 = converted %F.call, %.loc10_25.1
156172
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc10_20.14, constants.%T.as.Destroy.impl.Op.a44
157173
// CHECK:STDOUT: <elided>
158174
// CHECK:STDOUT: %bound_method.loc10_20.7: <bound method> = bound_method %.loc10_20.14, %T.as.Destroy.impl.Op.specific_fn
159175
// CHECK:STDOUT: %addr: %ptr.f01 = addr_of %.loc10_20.14
160176
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc10_20.7(%addr)
161-
// CHECK:STDOUT: return %.loc10_25.2
177+
// CHECK:STDOUT: return %F.call to %return
162178
// CHECK:STDOUT: }
163179
// CHECK:STDOUT:
164180
// CHECK:STDOUT: --- index_non_literal.carbon
@@ -215,6 +231,8 @@ fn F(a: array({}, 3)) -> {} {
215231
// CHECK:STDOUT: %.loc6_30.2: ref %empty_struct_type = array_index %.loc6_30.1, %.loc6_24.3
216232
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete = constants.%empty_struct]
217233
// CHECK:STDOUT: %.loc6_30.3: %empty_struct_type = converted %.loc6_30.2, %empty_struct [concrete = constants.%empty_struct]
218-
// CHECK:STDOUT: return %.loc6_30.3
234+
// CHECK:STDOUT: %.loc6_30.4: init %empty_struct_type = struct_init () to %return [concrete = constants.%empty_struct]
235+
// CHECK:STDOUT: %.loc6_31: init %empty_struct_type = converted %.loc6_30.3, %.loc6_30.4 [concrete = constants.%empty_struct]
236+
// CHECK:STDOUT: return %.loc6_31 to %return
219237
// CHECK:STDOUT: }
220238
// CHECK:STDOUT:

toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,14 @@ library "[[@TEST_NAME]]";
156156
// CHECK:STDOUT: %B.call: init %empty_tuple.type = call %B.ref()
157157
// CHECK:STDOUT: assign %c.ref.loc19, %B.call
158158
// CHECK:STDOUT: %c.ref.loc20: ref %empty_tuple.type = name_ref c, %c
159-
// CHECK:STDOUT: %tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
160-
// CHECK:STDOUT: %.loc20: %empty_tuple.type = converted %c.ref.loc20, %tuple [concrete = constants.%empty_tuple]
159+
// CHECK:STDOUT: %.loc20_10: init %empty_tuple.type = tuple_init () to %return [concrete = constants.%empty_tuple]
160+
// CHECK:STDOUT: %.loc20_11: init %empty_tuple.type = converted %c.ref.loc20, %.loc20_10 [concrete = constants.%empty_tuple]
161161
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %c.var, constants.%T.as.Destroy.impl.Op.bae
162162
// CHECK:STDOUT: <elided>
163163
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn
164164
// CHECK:STDOUT: %addr: %ptr.843 = addr_of %c.var
165165
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
166-
// CHECK:STDOUT: return %.loc20
166+
// CHECK:STDOUT: return %.loc20_11 to %return
167167
// CHECK:STDOUT: }
168168
// CHECK:STDOUT:
169169
// CHECK:STDOUT: --- class.carbon

toolchain/check/testdata/basics/raw_identifier.carbon

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn C(r#if: ()) -> () {
3030
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
3131
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
3232
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
33+
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
3334
// CHECK:STDOUT: %B.type: type = fn_type @B [concrete]
3435
// CHECK:STDOUT: %B: %B.type = struct_value () [concrete]
3536
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
@@ -98,18 +99,24 @@ fn C(r#if: ()) -> () {
9899
// CHECK:STDOUT: fn @A(%n.param: %empty_tuple.type) -> %empty_tuple.type {
99100
// CHECK:STDOUT: !entry:
100101
// CHECK:STDOUT: %n.ref: %empty_tuple.type = name_ref n, %n
101-
// CHECK:STDOUT: return %n.ref
102+
// CHECK:STDOUT: %.loc15_10: init %empty_tuple.type = tuple_init () to %return [concrete = constants.%empty_tuple]
103+
// CHECK:STDOUT: %.loc15_13: init %empty_tuple.type = converted %n.ref, %.loc15_10 [concrete = constants.%empty_tuple]
104+
// CHECK:STDOUT: return %.loc15_13 to %return
102105
// CHECK:STDOUT: }
103106
// CHECK:STDOUT:
104107
// CHECK:STDOUT: fn @B(%n.param: %empty_tuple.type) -> %empty_tuple.type {
105108
// CHECK:STDOUT: !entry:
106109
// CHECK:STDOUT: %n.ref: %empty_tuple.type = name_ref n, %n
107-
// CHECK:STDOUT: return %n.ref
110+
// CHECK:STDOUT: %.loc19_10: init %empty_tuple.type = tuple_init () to %return [concrete = constants.%empty_tuple]
111+
// CHECK:STDOUT: %.loc19_11: init %empty_tuple.type = converted %n.ref, %.loc19_10 [concrete = constants.%empty_tuple]
112+
// CHECK:STDOUT: return %.loc19_11 to %return
108113
// CHECK:STDOUT: }
109114
// CHECK:STDOUT:
110115
// CHECK:STDOUT: fn @C(%if.param: %empty_tuple.type) -> %empty_tuple.type {
111116
// CHECK:STDOUT: !entry:
112117
// CHECK:STDOUT: %if.ref: %empty_tuple.type = name_ref r#if, %if
113-
// CHECK:STDOUT: return %if.ref
118+
// CHECK:STDOUT: %.loc23_10: init %empty_tuple.type = tuple_init () to %return [concrete = constants.%empty_tuple]
119+
// CHECK:STDOUT: %.loc23_14: init %empty_tuple.type = converted %if.ref, %.loc23_10 [concrete = constants.%empty_tuple]
120+
// CHECK:STDOUT: return %.loc23_14 to %return
114121
// CHECK:STDOUT: }
115122
// CHECK:STDOUT:

0 commit comments

Comments
 (0)