mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Reimplement destroy as an interface (#5678)
This changes `Destroy` to use an interface for its implementation. Note that this change includes a lot of test updates. Even when `Destroy` is a no-op, it still causes code generation as part of determining that. Originally I was trying to use ranges to cut down the scope of this, and to a degree I think they have. But a flipside here is that cases where no destructors should be generated -- particularly globals -- would be needed to completely remove destructor calls. Even for ranges, the range can often include the destructor placement. So I've shifted frame-of-thought a little: accept a bunch of destructor churn, because destructors are needed and will be prevalent. The verbosity is a feature of the design to make desugaring apparent in IR, not a bug.
This commit is contained in:
+30
@@ -112,6 +112,7 @@ fn CallFAndGIncomplete() {
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -197,6 +198,7 @@ fn CallFAndGIncomplete() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %CallFAndGIncomplete.type: type = fn_type @CallFAndGIncomplete [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %CallFAndGIncomplete: %CallFAndGIncomplete.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ReturnCUnused.type: type = fn_type @ReturnCUnused [concrete]
|
||||
// CHECK:STDOUT: %ReturnCUnused: %ReturnCUnused.type = struct_value () [concrete]
|
||||
@@ -209,6 +211,17 @@ fn CallFAndGIncomplete() {
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
|
||||
// CHECK:STDOUT: %ReturnDUsed.type: type = fn_type @ReturnDUsed [concrete]
|
||||
// CHECK:STDOUT: %ReturnDUsed: %ReturnDUsed.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.1 [concrete]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.2, @impl(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.45e: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%D) [concrete]
|
||||
// CHECK:STDOUT: %Op.type.548: type = fn_type @Op.2, @impl(%D) [concrete]
|
||||
// CHECK:STDOUT: %Op.2d4: %Op.type.548 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %D, (%Destroy.impl_witness.45e) [concrete]
|
||||
// CHECK:STDOUT: %.64e: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet [concrete]
|
||||
// CHECK:STDOUT: %Op.specific_fn: <specific function> = specific_function %Op.2d4, @Op.2(%D) [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -220,10 +233,15 @@ fn CallFAndGIncomplete() {
|
||||
// CHECK:STDOUT: %Main.ReturnDUsed: %ReturnDUsed.type = import_ref Main//incomplete_return, ReturnDUsed, loaded [concrete = constants.%ReturnDUsed]
|
||||
// CHECK:STDOUT: %Main.Call = import_ref Main//incomplete_return, Call, unloaded
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Destroy = %Core.Destroy
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Main.import_ref.8f2: <witness> = import_ref Main//incomplete_return, loc37_10, loaded [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: %Main.import_ref.cab = import_ref Main//incomplete_return, inst20 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_23, loaded [symbolic = @impl.%Op (constants.%Op.46f)]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -266,6 +284,18 @@ fn CallFAndGIncomplete() {
|
||||
// CHECK:STDOUT: %.loc34_15.1: ref %D = temporary_storage
|
||||
// CHECK:STDOUT: %ReturnDUsed.call: init %D = call %ReturnDUsed.ref() to %.loc34_15.1
|
||||
// CHECK:STDOUT: %.loc34_15.2: ref %D = temporary %.loc34_15.1, %ReturnDUsed.call
|
||||
// CHECK:STDOUT: %impl.elem0.loc34: %.64e = impl_witness_access constants.%Destroy.impl_witness.45e, element0 [concrete = constants.%Op.2d4]
|
||||
// CHECK:STDOUT: %bound_method.loc34_15.1: <bound method> = bound_method %.loc34_15.1, %impl.elem0.loc34
|
||||
// CHECK:STDOUT: %specific_fn.loc34: <specific function> = specific_function %impl.elem0.loc34, @Op.2(constants.%D) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc34_15.2: <bound method> = bound_method %.loc34_15.1, %specific_fn.loc34
|
||||
// CHECK:STDOUT: %.loc34_15.3: %D = bind_value %.loc34_15.1
|
||||
// CHECK:STDOUT: %no_op.loc34: init %empty_tuple.type = call %bound_method.loc34_15.2(%.loc34_15.3)
|
||||
// CHECK:STDOUT: %impl.elem0.loc33: %.64e = impl_witness_access constants.%Destroy.impl_witness.45e, element0 [concrete = constants.%Op.2d4]
|
||||
// CHECK:STDOUT: %bound_method.loc33_17.1: <bound method> = bound_method %.loc33_17.1, %impl.elem0.loc33
|
||||
// CHECK:STDOUT: %specific_fn.loc33: <specific function> = specific_function %impl.elem0.loc33, @Op.2(constants.%D) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc33_17.2: <bound method> = bound_method %.loc33_17.1, %specific_fn.loc33
|
||||
// CHECK:STDOUT: %.loc33_17.3: %D = bind_value %.loc33_17.1
|
||||
// CHECK:STDOUT: %no_op.loc33: init %empty_tuple.type = call %bound_method.loc33_17.2(%.loc33_17.3)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user