Skip to content

Commit 9704dc6

Browse files
authored
Change the Destroy blanket impls to be more specific (#6098)
The main direction of this change is the edits to `destroy.carbon` (matching in both prelude and min_prelude). Previously there was a no-op blanket impl for `Destroy`, which hid all missing implementations of `Destroy`. This does a few things: - Sets up builtin aggregate destruction for struct and tuple types as before, but also adds C++ class types and array types to the same handling. (all as a TODO for actual implementation) - Also maybe-unformed destruction, for now at least. (there's a chance I may try a different approach on this, but the impl lookup wasn't working as I'd hope in order to write it in code) - Adds handlers for simple things that are easy to do in code: `type`, `bool`, pointers. (because these are no-op destruction) - Redirect `const T` destruction to `T` destruction. This leaves as future issues: - `partial T` destruction. (this can't be done similar to `const` because it only works for non-`final` class types; I think `class` definitions should just generate what's needed) - Destruction of other prelude-provided types. (will probably come up as we implement class destruction, that the adapted builtin type doesn't implement `Destroy` -- but may end up special-casing that in a way that moots it) This moves the `&` operator from `facet_types.carbon` to `convert.carbon` because more things need to handle type and now that we're getting separate copy and destroy interfaces. It should be low-cost (an interface and builtin) so hopefully this is the right balance for complexity and re-use. A few tests are also edited in order to focus them more on what they intend to test, and avoid a `Destroy` dependency.
1 parent 868c4b7 commit 9704dc6

File tree

143 files changed

+3268
-2410
lines changed

Some content is hidden

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

143 files changed

+3268
-2410
lines changed

.codespell_ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Exceptions. See /LICENSE for license information.
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

5+
AggregateT
56
ArchType
67
atleast
78
circularly

core/prelude/destroy.carbon

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,35 @@
44

55
package Core library "prelude/destroy";
66

7+
import library "prelude/types/bool";
8+
import library "prelude/types/int_literal";
9+
710
// Object destruction, including running `fn destroy()`. Note this is distinct
811
// from memory deallocation.
912
interface Destroy {
1013
fn Op[addr self: Self*]();
1114
}
1215

13-
// Provide a default blanket impl for trivial destruction.
14-
impl forall [T:! type] T as Destroy {
16+
// Add destruction for essential builtin types. This can't be done earlier
17+
// because `Destroy` is using them.
18+
// TODO: This should match trivial destruction.
19+
impl bool as Destroy {
20+
fn Op[addr self: Self*]() = "no_op";
21+
}
22+
impl type as Destroy {
23+
fn Op[addr self: Self*]() = "no_op";
24+
}
25+
impl forall [PointeeT:! type] PointeeT* as Destroy {
1526
fn Op[addr self: Self*]() = "no_op";
1627
}
28+
29+
// Handles builtin aggregate type destruction.
30+
private fn CanAggregateDestroy() -> type = "type.can_aggregate_destroy";
31+
impl forall [AggregateT:! CanAggregateDestroy()] AggregateT as Destroy {
32+
fn Op[addr self: Self*]() = "type.aggregate_destroy";
33+
}
34+
35+
// `const` instances always use the non-`const` destructor.
36+
impl forall [NonConstT:! Destroy] const NonConstT as Destroy {
37+
fn Op[addr self: Self*]() { (self unsafe as NonConstT*)->(Destroy.Op)(); }
38+
}

toolchain/check/impl_lookup.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,22 @@ static auto TypeCanAggregateDestroy(Context& context,
548548
-> bool {
549549
auto inst = context.insts().Get(
550550
context.constant_values().GetInstId(query_self_const_id));
551-
return inst.Is<SemIR::StructType>() || inst.Is<SemIR::TupleType>();
551+
CARBON_KIND_SWITCH(inst) {
552+
case CARBON_KIND(SemIR::ClassType class_type): {
553+
// Carbon classes will generate a `Destroy` impl, but we use this to
554+
// provide destruction for `Cpp`-scoped classes.
555+
// TODO: Don't provide this for C++ types that lack a destructor.
556+
auto class_info = context.classes().Get(class_type.class_id);
557+
return context.name_scopes().Get(class_info.scope_id).is_cpp_scope();
558+
}
559+
case SemIR::ArrayType::Kind:
560+
case SemIR::MaybeUnformedType::Kind:
561+
case SemIR::StructType::Kind:
562+
case SemIR::TupleType::Kind:
563+
return true;
564+
default:
565+
return false;
566+
}
552567
}
553568

554569
auto LookupImplWitness(Context& context, SemIR::LocId loc_id,

toolchain/check/implicit_type_impls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Carbon::Check {
1111

1212
// Constructs `impl <class> as Destroy { ... }`, with appropriate implementation
1313
// based on the `destroy` function and members.
14+
// TODO: Also generate the impl for `partial T` for non-final types.
1415
auto MakeClassDestroyImpl(Context& context, SemIR::ClassId class_id) -> void;
1516

1617
} // namespace Carbon::Check

toolchain/check/testdata/array/basics.carbon

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ var a: array(1, 1);
181181
// CHECK:STDOUT: %tuple.type.14a: type = tuple_type (%tuple.type.734, %tuple.type.734) [concrete]
182182
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
183183
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
184-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.c4b: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete]
185-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.100: %T.as.Destroy.impl.Op.type.c4b = struct_value () [concrete]
184+
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanAggregateDestroy>> [concrete]
185+
// CHECK:STDOUT: %facet_value: %type_where = facet_value %array_type, () [concrete]
186+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.f05: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value) [concrete]
187+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.6cc: %AggregateT.as_type.as.Destroy.impl.Op.type.f05 = struct_value () [concrete]
186188
// CHECK:STDOUT: }
187189
// CHECK:STDOUT:
188190
// CHECK:STDOUT: imports {
@@ -209,8 +211,8 @@ var a: array(1, 1);
209211
// CHECK:STDOUT: %F.call.loc10_40: init %tuple.type.734 = call %F.ref.loc10_38() to %.loc10_41.2
210212
// CHECK:STDOUT: %.loc10_41.3: %tuple.type.14a = tuple_literal (%F.call.loc10_35, %F.call.loc10_40)
211213
// CHECK:STDOUT: %.loc10_41.4: init %array_type = array_init (%F.call.loc10_35, %F.call.loc10_40) to %v.var
212-
// CHECK:STDOUT: %.loc10_3: init %array_type = converted %.loc10_41.3, %.loc10_41.4
213-
// CHECK:STDOUT: assign %v.var, %.loc10_3
214+
// CHECK:STDOUT: %.loc10_3.1: init %array_type = converted %.loc10_41.3, %.loc10_41.4
215+
// CHECK:STDOUT: assign %v.var, %.loc10_3.1
214216
// CHECK:STDOUT: %.loc10_28: type = splice_block %array_type [concrete = constants.%array_type] {
215217
// CHECK:STDOUT: %C.ref.loc10_17: type = name_ref C, file.%C.decl [concrete = constants.%C]
216218
// CHECK:STDOUT: %C.ref.loc10_20: type = name_ref C, file.%C.decl [concrete = constants.%C]
@@ -221,11 +223,13 @@ var a: array(1, 1);
221223
// CHECK:STDOUT: %array_type: type = array_type %int_2, %.loc10_24.2 [concrete = constants.%array_type]
222224
// CHECK:STDOUT: }
223225
// CHECK:STDOUT: %v: ref %array_type = bind_name v, %v.var
224-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %v.var, constants.%T.as.Destroy.impl.Op.100
226+
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%array_type, () [concrete = constants.%facet_value]
227+
// CHECK:STDOUT: %.loc10_3.2: %type_where = converted constants.%array_type, %facet_value [concrete = constants.%facet_value]
228+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %v.var, constants.%AggregateT.as_type.as.Destroy.impl.Op.6cc
225229
// CHECK:STDOUT: <elided>
226-
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %v.var, %T.as.Destroy.impl.Op.specific_fn
230+
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %v.var, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn
227231
// CHECK:STDOUT: %addr: %ptr.c6b = addr_of %v.var
228-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
232+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
229233
// CHECK:STDOUT: <elided>
230234
// CHECK:STDOUT: }
231235
// CHECK:STDOUT:
@@ -240,10 +244,13 @@ var a: array(1, 1);
240244
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete]
241245
// CHECK:STDOUT: %ptr.7fe: type = ptr_type %tuple.type [concrete]
242246
// CHECK:STDOUT: %pattern_type.8c1: type = pattern_type %tuple.type [concrete]
243-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.13b: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type) [concrete]
244-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.02a: %T.as.Destroy.impl.Op.type.13b = struct_value () [concrete]
245-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e84: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete]
246-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.3e0: %T.as.Destroy.impl.Op.type.e84 = struct_value () [concrete]
247+
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanAggregateDestroy>> [concrete]
248+
// CHECK:STDOUT: %facet_value.c7f: %type_where = facet_value %tuple.type, () [concrete]
249+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.b05: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value.c7f) [concrete]
250+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.1d6: %AggregateT.as_type.as.Destroy.impl.Op.type.b05 = struct_value () [concrete]
251+
// CHECK:STDOUT: %facet_value.4cf: %type_where = facet_value %array_type, () [concrete]
252+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.7a9: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value.4cf) [concrete]
253+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.190: %AggregateT.as_type.as.Destroy.impl.Op.type.7a9 = struct_value () [concrete]
247254
// CHECK:STDOUT: }
248255
// CHECK:STDOUT:
249256
// CHECK:STDOUT: imports {
@@ -279,16 +286,20 @@ var a: array(1, 1);
279286
// CHECK:STDOUT: %.loc8_21.6: type = converted %.loc8_21.2, constants.%tuple.type [concrete = constants.%tuple.type]
280287
// CHECK:STDOUT: }
281288
// CHECK:STDOUT: %b: ref %tuple.type = bind_name b, %b.var
282-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: <bound method> = bound_method %b.var, constants.%T.as.Destroy.impl.Op.02a
289+
// CHECK:STDOUT: %facet_value.loc8: %type_where = facet_value constants.%tuple.type, () [concrete = constants.%facet_value.c7f]
290+
// CHECK:STDOUT: %.loc8_3: %type_where = converted constants.%tuple.type, %facet_value.loc8 [concrete = constants.%facet_value.c7f]
291+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound.loc8: <bound method> = bound_method %b.var, constants.%AggregateT.as_type.as.Destroy.impl.Op.1d6
283292
// CHECK:STDOUT: <elided>
284-
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.1
293+
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %b.var, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn.1
285294
// CHECK:STDOUT: %addr.loc8: %ptr.7fe = addr_of %b.var
286-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8)
287-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7: <bound method> = bound_method %a.var, constants.%T.as.Destroy.impl.Op.3e0
295+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8)
296+
// CHECK:STDOUT: %facet_value.loc7: %type_where = facet_value constants.%array_type, () [concrete = constants.%facet_value.4cf]
297+
// CHECK:STDOUT: %.loc7_3: %type_where = converted constants.%array_type, %facet_value.loc7 [concrete = constants.%facet_value.4cf]
298+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound.loc7: <bound method> = bound_method %a.var, constants.%AggregateT.as_type.as.Destroy.impl.Op.190
288299
// CHECK:STDOUT: <elided>
289-
// CHECK:STDOUT: %bound_method.loc7: <bound method> = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2
300+
// CHECK:STDOUT: %bound_method.loc7: <bound method> = bound_method %a.var, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn.2
290301
// CHECK:STDOUT: %addr.loc7: %ptr.20b = addr_of %a.var
291-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7)
302+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7)
292303
// CHECK:STDOUT: <elided>
293304
// CHECK:STDOUT: }
294305
// CHECK:STDOUT:
@@ -306,11 +317,14 @@ var a: array(1, 1);
306317
// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %array_type [concrete]
307318
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
308319
// CHECK:STDOUT: %array: %array_type = tuple_value (%empty_tuple) [concrete]
309-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.839: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type) [concrete]
310-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.571: %T.as.Destroy.impl.Op.type.839 = struct_value () [concrete]
320+
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanAggregateDestroy>> [concrete]
321+
// CHECK:STDOUT: %facet_value.132: %type_where = facet_value %tuple.type, () [concrete]
322+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.2ee: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value.132) [concrete]
323+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.7ed: %AggregateT.as_type.as.Destroy.impl.Op.type.2ee = struct_value () [concrete]
311324
// CHECK:STDOUT: %ptr.652: type = ptr_type %tuple.type [concrete]
312-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8cb: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete]
313-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.36f: %T.as.Destroy.impl.Op.type.8cb = struct_value () [concrete]
325+
// CHECK:STDOUT: %facet_value.c1b: %type_where = facet_value %array_type, () [concrete]
326+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.c21: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value.c1b) [concrete]
327+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.e50: %AggregateT.as_type.as.Destroy.impl.Op.type.c21 = struct_value () [concrete]
314328
// CHECK:STDOUT: }
315329
// CHECK:STDOUT:
316330
// CHECK:STDOUT: imports {
@@ -333,25 +347,29 @@ var a: array(1, 1);
333347
// CHECK:STDOUT: %.loc8_27.4: init %empty_tuple.type = tuple_init () to %.loc8_27.3 [concrete = constants.%empty_tuple]
334348
// CHECK:STDOUT: %.loc8_27.5: init %empty_tuple.type = converted %tuple.elem0, %.loc8_27.4 [concrete = constants.%empty_tuple]
335349
// CHECK:STDOUT: %.loc8_27.6: init %array_type = array_init (%.loc8_27.5) to %t.var [concrete = constants.%array]
336-
// CHECK:STDOUT: %.loc8_3: init %array_type = converted %F.call, %.loc8_27.6 [concrete = constants.%array]
337-
// CHECK:STDOUT: assign %t.var, %.loc8_3
350+
// CHECK:STDOUT: %.loc8_3.1: init %array_type = converted %F.call, %.loc8_27.6 [concrete = constants.%array]
351+
// CHECK:STDOUT: assign %t.var, %.loc8_3.1
338352
// CHECK:STDOUT: %.loc8_21: type = splice_block %array_type [concrete = constants.%array_type] {
339353
// CHECK:STDOUT: %.loc8_17.1: %empty_tuple.type = tuple_literal ()
340354
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
341355
// CHECK:STDOUT: %.loc8_17.2: type = converted %.loc8_17.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
342356
// CHECK:STDOUT: %array_type: type = array_type %int_1, %.loc8_17.2 [concrete = constants.%array_type]
343357
// CHECK:STDOUT: }
344358
// CHECK:STDOUT: %t: ref %array_type = bind_name t, %t.var
345-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_27: <bound method> = bound_method %.loc8_27.2, constants.%T.as.Destroy.impl.Op.571
359+
// CHECK:STDOUT: %facet_value.loc8_27: %type_where = facet_value constants.%tuple.type, () [concrete = constants.%facet_value.132]
360+
// CHECK:STDOUT: %.loc8_27.7: %type_where = converted constants.%tuple.type, %facet_value.loc8_27 [concrete = constants.%facet_value.132]
361+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound.loc8_27: <bound method> = bound_method %.loc8_27.2, constants.%AggregateT.as_type.as.Destroy.impl.Op.7ed
346362
// CHECK:STDOUT: <elided>
347-
// CHECK:STDOUT: %bound_method.loc8_27: <bound method> = bound_method %.loc8_27.2, %T.as.Destroy.impl.Op.specific_fn.1
363+
// CHECK:STDOUT: %bound_method.loc8_27: <bound method> = bound_method %.loc8_27.2, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn.1
348364
// CHECK:STDOUT: %addr.loc8_27: %ptr.652 = addr_of %.loc8_27.2
349-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_27: init %empty_tuple.type = call %bound_method.loc8_27(%addr.loc8_27)
350-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_3: <bound method> = bound_method %t.var, constants.%T.as.Destroy.impl.Op.36f
365+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call.loc8_27: init %empty_tuple.type = call %bound_method.loc8_27(%addr.loc8_27)
366+
// CHECK:STDOUT: %facet_value.loc8_3: %type_where = facet_value constants.%array_type, () [concrete = constants.%facet_value.c1b]
367+
// CHECK:STDOUT: %.loc8_3.2: %type_where = converted constants.%array_type, %facet_value.loc8_3 [concrete = constants.%facet_value.c1b]
368+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound.loc8_3: <bound method> = bound_method %t.var, constants.%AggregateT.as_type.as.Destroy.impl.Op.e50
351369
// CHECK:STDOUT: <elided>
352-
// CHECK:STDOUT: %bound_method.loc8_3: <bound method> = bound_method %t.var, %T.as.Destroy.impl.Op.specific_fn.2
370+
// CHECK:STDOUT: %bound_method.loc8_3: <bound method> = bound_method %t.var, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn.2
353371
// CHECK:STDOUT: %addr.loc8_3: %ptr.b99 = addr_of %t.var
354-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_3: init %empty_tuple.type = call %bound_method.loc8_3(%addr.loc8_3)
372+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call.loc8_3: init %empty_tuple.type = call %bound_method.loc8_3(%addr.loc8_3)
355373
// CHECK:STDOUT: <elided>
356374
// CHECK:STDOUT: }
357375
// CHECK:STDOUT:

toolchain/check/testdata/array/import.carbon

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ fn F() -> array(i32, 1) {
7979
// CHECK:STDOUT: %Copy.facet.c49: %Copy.type = facet_value %i32, (%Copy.impl_witness.a32) [concrete]
8080
// CHECK:STDOUT: %.7fa: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet.c49 [concrete]
8181
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.f59, @Int.as.Copy.impl.Op(%int_32) [concrete]
82-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e2a: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete]
83-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.95f: %T.as.Destroy.impl.Op.type.e2a = struct_value () [concrete]
82+
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanAggregateDestroy>> [concrete]
83+
// CHECK:STDOUT: %facet_value: %type_where = facet_value %array_type, () [concrete]
84+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.type.b6e: type = fn_type @AggregateT.as_type.as.Destroy.impl.Op, @AggregateT.as_type.as.Destroy.impl(%facet_value) [concrete]
85+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.91f: %AggregateT.as_type.as.Destroy.impl.Op.type.b6e = struct_value () [concrete]
8486
// CHECK:STDOUT: }
8587
// CHECK:STDOUT:
8688
// CHECK:STDOUT: imports {
@@ -105,11 +107,13 @@ fn F() -> array(i32, 1) {
105107
// 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]
106108
// CHECK:STDOUT: %bound_method.loc6_15.2: <bound method> = bound_method %.loc6_15.2, %specific_fn
107109
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_15.2(%.loc6_15.2)
108-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc6_12.2, constants.%T.as.Destroy.impl.Op.95f
110+
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%array_type, () [concrete = constants.%facet_value]
111+
// CHECK:STDOUT: %.loc6_12.3: %type_where = converted constants.%array_type, %facet_value [concrete = constants.%facet_value]
112+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc6_12.2, constants.%AggregateT.as_type.as.Destroy.impl.Op.91f
109113
// CHECK:STDOUT: <elided>
110-
// CHECK:STDOUT: %bound_method.loc6_12: <bound method> = bound_method %.loc6_12.2, %T.as.Destroy.impl.Op.specific_fn
114+
// CHECK:STDOUT: %bound_method.loc6_12: <bound method> = bound_method %.loc6_12.2, %AggregateT.as_type.as.Destroy.impl.Op.specific_fn
111115
// CHECK:STDOUT: %addr: %ptr.830 = addr_of %.loc6_12.2
112-
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc6_12(%addr)
116+
// CHECK:STDOUT: %AggregateT.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc6_12(%addr)
113117
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return
114118
// CHECK:STDOUT: }
115119
// CHECK:STDOUT:

0 commit comments

Comments
 (0)