mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Handle destruction for return statements (#5785)
This just catches uses equivalent to `return;` and `return <expr>;`. Note it's just extending the current implicit return logic, not really adding much unique here. I'm still delaying break and continue because those require partial destruction, which is more work and I want to be careful to get it right.
This commit is contained in:
+49
-14
@@ -24,6 +24,7 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete]
|
||||
@@ -46,14 +47,33 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.2 [concrete]
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.3, @impl.49c(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.711: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl.49c(%ptr.235) [concrete]
|
||||
// CHECK:STDOUT: %Op.type.ba2: type = fn_type @Op.3, @impl.49c(%ptr.235) [concrete]
|
||||
// CHECK:STDOUT: %Op.649: %Op.type.ba2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.2bf: %Destroy.type = facet_value %ptr.235, (%Destroy.impl_witness.711) [concrete]
|
||||
// CHECK:STDOUT: %.a79: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.2bf [concrete]
|
||||
// CHECK:STDOUT: %Op.specific_fn.829: <specific function> = specific_function %Op.649, @Op.3(%ptr.235) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.64e: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl.49c(%i32) [concrete]
|
||||
// CHECK:STDOUT: %Op.type.a17: type = fn_type @Op.3, @impl.49c(%i32) [concrete]
|
||||
// CHECK:STDOUT: %Op.e6a: %Op.type.a17 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.5f7: %Destroy.type = facet_value %i32, (%Destroy.impl_witness.64e) [concrete]
|
||||
// CHECK:STDOUT: %.ab7: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.5f7 [concrete]
|
||||
// CHECK:STDOUT: %Op.specific_fn.014: <specific function> = specific_function %Op.e6a, @Op.3(%i32) [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs
|
||||
// CHECK:STDOUT: .Destroy = %Core.Destroy
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
@@ -61,6 +81,9 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: %Core.import_ref.a5b: @impl.4f9.%Convert.type (%Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @impl.4f9.%Convert (constants.%Convert.f06)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @impl.4f9 [concrete]
|
||||
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.49c.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_29, loaded [symbolic = @impl.49c.%Op (constants.%Op.46f)]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl.49c [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -88,10 +111,10 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %n.var: ref %i32 = var %n.var_patt
|
||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %impl.elem0.loc16_3.1: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.1: <bound method> = bound_method %int_0, %impl.elem0.loc16_3.1 [concrete = constants.%Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc16_3.1: <specific function> = specific_function %impl.elem0.loc16_3.1, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.2: <bound method> = bound_method %int_0, %specific_fn.loc16_3.1 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %bound_method.loc16_3.2(%int_0) [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: %.loc16_3: init %i32 = converted %int_0, %int.convert_checked [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: assign %n.var, %.loc16_3
|
||||
@@ -104,20 +127,32 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: %p.patt: %pattern_type.fe8 = binding_pattern p [concrete]
|
||||
// CHECK:STDOUT: %p.var_patt: %pattern_type.fe8 = var_pattern %p.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %p.var: ref %ptr = var %p.var_patt
|
||||
// CHECK:STDOUT: %p.var: ref %ptr.235 = var %p.var_patt
|
||||
// CHECK:STDOUT: %n.ref: ref %i32 = name_ref n, %n
|
||||
// CHECK:STDOUT: %addr: %ptr = addr_of %n.ref
|
||||
// CHECK:STDOUT: assign %p.var, %addr
|
||||
// CHECK:STDOUT: %.loc17: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %addr.loc17_17: %ptr.235 = addr_of %n.ref
|
||||
// CHECK:STDOUT: assign %p.var, %addr.loc17_17
|
||||
// CHECK:STDOUT: %.loc17: type = splice_block %ptr [concrete = constants.%ptr.235] {
|
||||
// CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc17 [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc17 [concrete = constants.%ptr.235]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %p: ref %ptr = bind_name p, %p.var
|
||||
// CHECK:STDOUT: %p.ref: ref %ptr = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc19_11: %ptr = bind_value %p.ref
|
||||
// CHECK:STDOUT: %p: ref %ptr.235 = bind_name p, %p.var
|
||||
// CHECK:STDOUT: %p.ref: ref %ptr.235 = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc19_11: %ptr.235 = bind_value %p.ref
|
||||
// CHECK:STDOUT: %.loc19_10.1: ref %i32 = deref %.loc19_11
|
||||
// CHECK:STDOUT: %.loc19_10.2: %i32 = bind_value %.loc19_10.1
|
||||
// CHECK:STDOUT: %impl.elem0.loc17: %.a79 = impl_witness_access constants.%Destroy.impl_witness.711, element0 [concrete = constants.%Op.649]
|
||||
// CHECK:STDOUT: %bound_method.loc17_3.1: <bound method> = bound_method %p.var, %impl.elem0.loc17
|
||||
// CHECK:STDOUT: %specific_fn.loc17: <specific function> = specific_function %impl.elem0.loc17, @Op.3(constants.%ptr.235) [concrete = constants.%Op.specific_fn.829]
|
||||
// CHECK:STDOUT: %bound_method.loc17_3.2: <bound method> = bound_method %p.var, %specific_fn.loc17
|
||||
// CHECK:STDOUT: %addr.loc17_3: %ptr.5d5 = addr_of %p.var
|
||||
// CHECK:STDOUT: %no_op.loc17: init %empty_tuple.type = call %bound_method.loc17_3.2(%addr.loc17_3)
|
||||
// CHECK:STDOUT: %impl.elem0.loc16_3.2: %.ab7 = impl_witness_access constants.%Destroy.impl_witness.64e, element0 [concrete = constants.%Op.e6a]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.3: <bound method> = bound_method %n.var, %impl.elem0.loc16_3.2
|
||||
// CHECK:STDOUT: %specific_fn.loc16_3.2: <specific function> = specific_function %impl.elem0.loc16_3.2, @Op.3(constants.%i32) [concrete = constants.%Op.specific_fn.014]
|
||||
// CHECK:STDOUT: %bound_method.loc16_3.4: <bound method> = bound_method %n.var, %specific_fn.loc16_3.2
|
||||
// CHECK:STDOUT: %addr.loc16: %ptr.235 = addr_of %n.var
|
||||
// CHECK:STDOUT: %no_op.loc16: init %empty_tuple.type = call %bound_method.loc16_3.4(%addr.loc16)
|
||||
// CHECK:STDOUT: return %.loc19_10.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user