mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 08:34:43 +01:00
ExprCategory for guaranteed-in-place initializing expressions (#6623)
The primary change in this PR is to split the `Initializing` expression category into separate `ReprInitializing` and `InPlaceInitializing` categories, depending on whether initialization uses the types initializing representation, or is guaranteed to be in place. It also rationalizes and documents the SemIR-level semantics of those categories (including where #5545's "ephemeral entire reference" category will fit), and introduces two new inst kinds to close gaps exposed in the process. Some additional secondary changes: - Consistently format the storage arguments of initializers with `to`, regardless of whether initialization is in-place, and document the `to` notation. - Rename some inst kinds and functions, and restructure some of the code, for clarity and consistency with the new documentation. - Resolve a TODO to handle more category conversions in `CategoryConverter`, in order to make it easier to reason about category conversions. See #6588 and the review history of this PR for background. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
2980e6bcbb
commit
e5b05a1fac
+41
-28
@@ -1651,13 +1651,13 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc22_44.1: ref %i128 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc22_44.2: %ptr.974 = addr_of %.loc22_44.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call.loc22: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc22_44.1, %addr.loc22_44.2)
|
||||
// CHECK:STDOUT: %.loc22_44.2: init %i128 = in_place_init %foo__carbon_thunk.call.loc22, %.loc22_44.1
|
||||
// CHECK:STDOUT: %.loc22_44.2: init %i128 to %.loc22_44.1 = mark_in_place_init %foo__carbon_thunk.call.loc22
|
||||
// CHECK:STDOUT: %.loc22_10: type = splice_block %i128.loc22 [concrete = constants.%i128] {
|
||||
// CHECK:STDOUT: %int_128.loc22: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
|
||||
// CHECK:STDOUT: %i128.loc22: type = class_type @Int, @Int(constants.%int_128) [concrete = constants.%i128]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc22_44.3: %i128 = value_of_initializer %.loc22_44.2
|
||||
// CHECK:STDOUT: %.loc22_44.4: %i128 = converted %.loc22_44.2, %.loc22_44.3
|
||||
// CHECK:STDOUT: %.loc22_44.3: ref %i128 = temporary %.loc22_44.1, %.loc22_44.2
|
||||
// CHECK:STDOUT: %.loc22_44.4: %i128 = acquire_value %.loc22_44.3
|
||||
// CHECK:STDOUT: %d: %i128 = value_binding d, %.loc22_44.4
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type.57d = value_binding_pattern e [concrete]
|
||||
@@ -1683,13 +1683,13 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc25_45.1: ref %i128 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc25_45.2: %ptr.974 = addr_of %.loc25_45.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call.loc25: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc25_45.1, %addr.loc25_45.2)
|
||||
// CHECK:STDOUT: %.loc25_45.2: init %i128 = in_place_init %foo__carbon_thunk.call.loc25, %.loc25_45.1
|
||||
// CHECK:STDOUT: %.loc25_45.2: init %i128 to %.loc25_45.1 = mark_in_place_init %foo__carbon_thunk.call.loc25
|
||||
// CHECK:STDOUT: %.loc25_10: type = splice_block %i128.loc25 [concrete = constants.%i128] {
|
||||
// CHECK:STDOUT: %int_128.loc25: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
|
||||
// CHECK:STDOUT: %i128.loc25: type = class_type @Int, @Int(constants.%int_128) [concrete = constants.%i128]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc25_45.3: %i128 = value_of_initializer %.loc25_45.2
|
||||
// CHECK:STDOUT: %.loc25_45.4: %i128 = converted %.loc25_45.2, %.loc25_45.3
|
||||
// CHECK:STDOUT: %.loc25_45.3: ref %i128 = temporary %.loc25_45.1, %.loc25_45.2
|
||||
// CHECK:STDOUT: %.loc25_45.4: %i128 = acquire_value %.loc25_45.3
|
||||
// CHECK:STDOUT: %e: %i128 = value_binding e, %.loc25_45.4
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %f.patt: %pattern_type.57d = value_binding_pattern f [concrete]
|
||||
@@ -1715,13 +1715,13 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc28_45.1: ref %i128 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc28_45.2: %ptr.974 = addr_of %.loc28_45.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call.loc28: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc28_45.1, %addr.loc28_45.2)
|
||||
// CHECK:STDOUT: %.loc28_45.2: init %i128 = in_place_init %foo__carbon_thunk.call.loc28, %.loc28_45.1
|
||||
// CHECK:STDOUT: %.loc28_45.2: init %i128 to %.loc28_45.1 = mark_in_place_init %foo__carbon_thunk.call.loc28
|
||||
// CHECK:STDOUT: %.loc28_10: type = splice_block %i128.loc28 [concrete = constants.%i128] {
|
||||
// CHECK:STDOUT: %int_128.loc28: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
|
||||
// CHECK:STDOUT: %i128.loc28: type = class_type @Int, @Int(constants.%int_128) [concrete = constants.%i128]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc28_45.3: %i128 = value_of_initializer %.loc28_45.2
|
||||
// CHECK:STDOUT: %.loc28_45.4: %i128 = converted %.loc28_45.2, %.loc28_45.3
|
||||
// CHECK:STDOUT: %.loc28_45.3: ref %i128 = temporary %.loc28_45.1, %.loc28_45.2
|
||||
// CHECK:STDOUT: %.loc28_45.4: %i128 = acquire_value %.loc28_45.3
|
||||
// CHECK:STDOUT: %f: %i128 = value_binding f, %.loc28_45.4
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %g.patt: %pattern_type.57d = value_binding_pattern g [concrete]
|
||||
@@ -1747,22 +1747,30 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc31_64.1: ref %i128 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc31_64.2: %ptr.974 = addr_of %.loc31_64.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call.loc31: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc31_64.1, %addr.loc31_64.2)
|
||||
// CHECK:STDOUT: %.loc31_64.2: init %i128 = in_place_init %foo__carbon_thunk.call.loc31, %.loc31_64.1
|
||||
// CHECK:STDOUT: %.loc31_64.2: init %i128 to %.loc31_64.1 = mark_in_place_init %foo__carbon_thunk.call.loc31
|
||||
// CHECK:STDOUT: %.loc31_10: type = splice_block %i128.loc31 [concrete = constants.%i128] {
|
||||
// CHECK:STDOUT: %int_128.loc31: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
|
||||
// CHECK:STDOUT: %i128.loc31: type = class_type @Int, @Int(constants.%int_128) [concrete = constants.%i128]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc31_64.3: %i128 = value_of_initializer %.loc31_64.2
|
||||
// CHECK:STDOUT: %.loc31_64.4: %i128 = converted %.loc31_64.2, %.loc31_64.3
|
||||
// CHECK:STDOUT: %.loc31_64.3: ref %i128 = temporary %.loc31_64.1, %.loc31_64.2
|
||||
// CHECK:STDOUT: %.loc31_64.4: %i128 = acquire_value %.loc31_64.3
|
||||
// CHECK:STDOUT: %g: %i128 = value_binding g, %.loc31_64.4
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc31: <bound method> = bound_method %.loc31_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc31: init %empty_tuple.type = call %DestroyOp.bound.loc31(%.loc31_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc28: <bound method> = bound_method %.loc28_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc28: init %empty_tuple.type = call %DestroyOp.bound.loc28(%.loc28_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc25: <bound method> = bound_method %.loc25_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc25: init %empty_tuple.type = call %DestroyOp.bound.loc25(%.loc25_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc22: <bound method> = bound_method %.loc22_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc22: init %empty_tuple.type = call %DestroyOp.bound.loc22(%.loc22_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc31_64: <bound method> = bound_method %.loc31_64.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc31_64: init %empty_tuple.type = call %DestroyOp.bound.loc31_64(%.loc31_64.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc31_25: <bound method> = bound_method %.loc31_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc31_25: init %empty_tuple.type = call %DestroyOp.bound.loc31_25(%.loc31_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc28_45: <bound method> = bound_method %.loc28_45.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc28_45: init %empty_tuple.type = call %DestroyOp.bound.loc28_45(%.loc28_45.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc28_25: <bound method> = bound_method %.loc28_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc28_25: init %empty_tuple.type = call %DestroyOp.bound.loc28_25(%.loc28_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc25_45: <bound method> = bound_method %.loc25_45.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc25_45: init %empty_tuple.type = call %DestroyOp.bound.loc25_45(%.loc25_45.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc25_25: <bound method> = bound_method %.loc25_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc25_25: init %empty_tuple.type = call %DestroyOp.bound.loc25_25(%.loc25_25.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc22_44: <bound method> = bound_method %.loc22_44.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc22_44: init %empty_tuple.type = call %DestroyOp.bound.loc22_44(%.loc22_44.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc22_25: <bound method> = bound_method %.loc22_25.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc22_25: init %empty_tuple.type = call %DestroyOp.bound.loc22_25(%.loc22_25.4)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -2194,16 +2202,18 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc7_27.1: ref %f64.d77 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc7_27.2: %ptr.bcc = addr_of %.loc7_27.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc7_27.1, %addr.loc7_27.2)
|
||||
// CHECK:STDOUT: %.loc7_27.2: init %f64.d77 = in_place_init %foo__carbon_thunk.call, %.loc7_27.1
|
||||
// CHECK:STDOUT: %.loc7_27.2: init %f64.d77 to %.loc7_27.1 = mark_in_place_init %foo__carbon_thunk.call
|
||||
// CHECK:STDOUT: %.loc7_10: type = splice_block %f64 [concrete = constants.%f64.d77] {
|
||||
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
|
||||
// CHECK:STDOUT: %f64: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc7_27.3: %f64.d77 = value_of_initializer %.loc7_27.2
|
||||
// CHECK:STDOUT: %.loc7_27.4: %f64.d77 = converted %.loc7_27.2, %.loc7_27.3
|
||||
// CHECK:STDOUT: %.loc7_27.3: ref %f64.d77 = temporary %.loc7_27.1, %.loc7_27.2
|
||||
// CHECK:STDOUT: %.loc7_27.4: %f64.d77 = acquire_value %.loc7_27.3
|
||||
// CHECK:STDOUT: %d: %f64.d77 = value_binding d, %.loc7_27.4
|
||||
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %.loc7_24.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc7_24.4)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc7_27: <bound method> = bound_method %.loc7_27.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc7_27: init %empty_tuple.type = call %DestroyOp.bound.loc7_27(%.loc7_27.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc7_24: <bound method> = bound_method %.loc7_24.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc7_24: init %empty_tuple.type = call %DestroyOp.bound.loc7_24(%.loc7_24.4)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -2340,9 +2350,12 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc15_19.1: ref %f64.d77 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc15_19.2: %ptr.bcc = addr_of %.loc15_19.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc15_19.1, %addr.loc15_19.2)
|
||||
// CHECK:STDOUT: %.loc15_19.2: init %f64.d77 = in_place_init %foo__carbon_thunk.call, %.loc15_19.1
|
||||
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %.loc15_11.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc15_11.4)
|
||||
// CHECK:STDOUT: %.loc15_19.2: init %f64.d77 to %.loc15_19.1 = mark_in_place_init %foo__carbon_thunk.call
|
||||
// CHECK:STDOUT: %.loc15_19.3: ref %f64.d77 = temporary %.loc15_19.1, %.loc15_19.2
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc15_19: <bound method> = bound_method %.loc15_19.3, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc15_19: init %empty_tuple.type = call %DestroyOp.bound.loc15_19(%.loc15_19.3)
|
||||
// CHECK:STDOUT: %DestroyOp.bound.loc15_11: <bound method> = bound_method %.loc15_11.4, constants.%DestroyOp
|
||||
// CHECK:STDOUT: %DestroyOp.call.loc15_11: init %empty_tuple.type = call %DestroyOp.bound.loc15_11(%.loc15_11.4)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user