@@ -9,13 +9,7 @@ import Swift
9
9
@frozen
10
10
public struct UnsafeValue < Element: AnyObject > {
11
11
@usableFromInline
12
- internal unowned(unsafe) var _value : Element ?
13
-
14
- @_transparent
15
- @inlinable
16
- public init ( ) {
17
- _value = nil
18
- }
12
+ internal unowned(unsafe) var _value : Element
19
13
20
14
// Create a new unmanaged value that owns the underlying value. This unmanaged
21
15
// value must after use be deinitialized by calling the function deinitialize()
@@ -24,7 +18,7 @@ public struct UnsafeValue<Element: AnyObject> {
24
18
@_transparent
25
19
@inlinable
26
20
public init ( copying newValue: __shared Element) {
27
- self . init ( )
21
+ Builtin . retain ( newValue )
28
22
_value = newValue
29
23
}
30
24
@@ -34,15 +28,14 @@ public struct UnsafeValue<Element: AnyObject> {
34
28
// CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s11unsafevalue11UnsafeValueV14unsafelyAssignACyxGxh_tcfC : $@convention(method) <Element where Element : AnyObject> (@guaranteed Element, @thin UnsafeValue<Element>.Type) -> UnsafeValue<Element> {
35
29
// CHECK: bb0([[INPUT_ELEMENT:%.*]] : @guaranteed $Element,
36
30
// CHECK: [[BOX:%.*]] = alloc_box
37
- // CHECK: [[UNINIT_BOX:%.*]] = mark_uninitialized [delegatingself ] [[BOX]]
31
+ // CHECK: [[UNINIT_BOX:%.*]] = mark_uninitialized [rootself ] [[BOX]]
38
32
// CHECK: [[PROJECT_UNINIT_BOX:%.*]] = project_box [[UNINIT_BOX]]
39
- // CHECK: [[DELEGATING_INIT_RESULT:%.*]] = apply {{%.*}}<Element>(
40
- // CHECK: assign [[DELEGATING_INIT_RESULT]] to [[PROJECT_UNINIT_BOX]]
41
- // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT_UNINIT_BOX]]
33
+ // CHECK: [[COPY_INPUT_ELEMENT:%.*]] = copy_value [[INPUT_ELEMENT]]
34
+ // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[PROJECT_UNINIT_BOX]]
42
35
// CHECK: [[STRUCT_ACCESS:%.*]] = struct_element_addr [[ACCESS]]
43
- // CHECK: [[OPT_INPUT_ELEMENT :%.*]] = enum $Optional<Element>, #Optional.some!enumelt.1, [[INPUT_ELEMENT ]]
44
- // CHECK: [[UNMANAGED_OPT_INPUT_ELEMENT:%.* ]] = ref_to_unmanaged [[OPT_INPUT_ELEMENT ]]
45
- // CHECK: store [[UNMANAGED_OPT_INPUT_ELEMENT]] to [trivial] [[STRUCT_ACCESS ]]
36
+ // CHECK: [[UNMANAGED_INPUT_ELEMENT :%.*]] = ref_to_unmanaged [[COPY_INPUT_ELEMENT ]]
37
+ // CHECK: assign [[UNMANAGED_INPUT_ELEMENT ]] to [[STRUCT_ACCESS ]]
38
+ // CHECK: destroy_value [[COPY_INPUT_ELEMENT ]]
46
39
// CHECK: end_access [[ACCESS]]
47
40
// CHECK: [[RESULT:%.*]] = load [trivial] [[PROJECT_UNINIT_BOX]]
48
41
// CHECK: destroy_value [[UNINIT_BOX]]
@@ -52,89 +45,87 @@ public struct UnsafeValue<Element: AnyObject> {
52
45
// CANONICAL-LABEL: sil [transparent] [serialized] @$s11unsafevalue11UnsafeValueV14unsafelyAssignACyxGxh_tcfC : $@convention(method) <Element where Element : AnyObject> (@guaranteed Element, @thin UnsafeValue<Element>.Type) -> UnsafeValue<Element> {
53
46
// CANONICAL: bb0([[INPUT_ELEMENT:%.*]] : $Element,
54
47
// CANONICAL-NEXT: debug_value
55
- // TODO(gottesmm): release_value on a .none shouldn't exist.
56
- // CANONICAL-NEXT: [[NONE:%.*]] = enum $Optional<Element>, #Optional.none!enumelt
57
- // CANONICAL-NEXT: release_value [[NONE]]
58
- // CANONICAL-NEXT: [[ENUM:%.*]] = enum $Optional<Element>, #Optional.some!enumelt.1, [[INPUT_ELEMENT]]
59
- // CANONICAL-NEXT: [[UNMANAGED_ENUM:%.*]] = ref_to_unmanaged [[ENUM]]
60
- // CANONICAL-NEXT: [[RESULT:%.*]] = struct $UnsafeValue<Element> ([[UNMANAGED_ENUM]] : $@sil_unmanaged Optional<Element>)
61
- // CANONICAL-NEXT: tuple
48
+ // CANONICAL-NEXT: [[UNMANAGED_ELEMENT:%.*]] = ref_to_unmanaged [[INPUT_ELEMENT]]
49
+ // CANONICAL-NEXT: [[RESULT:%.*]] = struct $UnsafeValue<Element> ([[UNMANAGED_ELEMENT]] : $@sil_unmanaged Element)
62
50
// CANONICAL-NEXT: return [[RESULT]]
63
51
// CANONICAL: } // end sil function '$s11unsafevalue11UnsafeValueV14unsafelyAssignACyxGxh_tcfC'
64
52
//
65
53
// OPT-LABEL: sil [transparent] @$s11unsafevalue11UnsafeValueV14unsafelyAssignACyxGxh_tcfC : $@convention(method) <Element where Element : AnyObject> (@guaranteed Element, @thin UnsafeValue<Element>.Type) -> UnsafeValue<Element> {
66
54
// OPT: bb0([[INPUT_ELEMENT:%.*]] : $Element,
67
55
// OPT-NEXT: debug_value
68
- // OPT-NEXT: [[ENUM:%.*]] = enum $Optional<Element>, #Optional.some!enumelt.1, [[INPUT_ELEMENT]]
69
- // OPT-NEXT: [[UNMANAGED_ENUM:%.*]] = ref_to_unmanaged [[ENUM]]
70
- // OPT-NEXT: [[RESULT:%.*]] = struct $UnsafeValue<Element> ([[UNMANAGED_ENUM]] : $@sil_unmanaged Optional<Element>)
56
+ // OPT-NEXT: [[UNMANAGED_ELEMENT:%.*]] = ref_to_unmanaged [[INPUT_ELEMENT]]
57
+ // OPT-NEXT: [[RESULT:%.*]] = struct $UnsafeValue<Element> ([[UNMANAGED_ELEMENT]] : $@sil_unmanaged Element)
71
58
// OPT-NEXT: return [[RESULT]]
72
59
// OPT: } // end sil function '$s11unsafevalue11UnsafeValueV14unsafelyAssignACyxGxh_tcfC'
73
60
@_transparent
74
61
@inlinable
75
62
public init ( unsafelyAssign newValue: __shared Element) {
76
- self . init ( )
77
- Builtin . convertStrongToUnownedUnsafe ( newValue, & _value)
63
+ _value = newValue
78
64
}
79
65
80
66
// Access the underlying value at +0, guaranteeing its lifetime by base.
81
67
//
82
- // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
68
+ // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
83
69
// CHECK: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
84
70
// CHECK: [[COPY_BOX:%.*]] = alloc_box
85
71
// CHECK: [[COPY_PROJ:%.*]] = project_box [[COPY_BOX]]
86
72
// CHECK: store [[UNSAFE_VALUE]] to [trivial] [[COPY_PROJ]]
87
73
// CHECK: [[VALUE_ADDR:%.*]] = begin_access [read] [unknown] [[COPY_PROJ]]
88
74
// CHECK: [[STR_VALUE_ADDR:%.*]] = struct_element_addr [[VALUE_ADDR]]
89
75
// CHECK: [[UNMANAGED_VALUE:%.*]] = load [trivial] [[STR_VALUE_ADDR]]
90
- // CHECK: [[UNOWNED_REF_OPTIONAL:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
91
- // CHECK: [[GUARANTEED_REF_OPTIONAL:%.*]] = unchecked_ownership_conversion [[UNOWNED_REF_OPTIONAL]]
92
- // CHECK: [[GUARANTEED_REF:%.*]] = unchecked_enum_data [[GUARANTEED_REF_OPTIONAL]]
76
+ // CHECK: [[UNOWNED_REF:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
77
+ // CHECK: [[GUARANTEED_REF:%.*]] = unchecked_ownership_conversion [[UNOWNED_REF]]
93
78
// CHECK: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[GUARANTEED_REF]] : $Element on [[BASE]]
94
79
// CHECK: end_access [[VALUE_ADDR]]
95
80
// CHECK: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
96
- // CHECK: end_borrow [[GUARANTEED_REF_OPTIONAL ]]
81
+ // CHECK: end_borrow [[GUARANTEED_REF ]]
97
82
// CHECK: destroy_value [[COPY_BOX]]
98
- // CHECK: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF '
83
+ // CHECK: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF '
99
84
//
100
- // CANONICAL-LABEL: sil [transparent] [serialized] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
85
+ // CANONICAL-LABEL: sil [transparent] [serialized] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
101
86
// CANONICAL: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
102
87
// CANONICAL: [[UNMANAGED_VALUE:%.*]] = struct_extract [[UNSAFE_VALUE]]
103
- // CANONICAL: [[UNOWNED_REF_OPTIONAL:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
104
- // CANONICAL: [[GUARANTEED_REF:%.*]] = unchecked_enum_data [[UNOWNED_REF_OPTIONAL]]
105
- // CANONICAL: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[GUARANTEED_REF]] : $Element on [[BASE]]
88
+ // CANONICAL: [[UNOWNED_REF:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
89
+ // CANONICAL: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[UNOWNED_REF]] : $Element on [[BASE]]
106
90
// CANONICAL: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
107
- // CANONICAL: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF '
91
+ // CANONICAL: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF '
108
92
//
109
- // OPT-LABEL: sil [transparent] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
93
+ // OPT-LABEL: sil [transparent] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF : $@convention(method) <Element where Element : AnyObject><Base, Result> (@in_guaranteed Base, @noescape @callee_guaranteed (@guaranteed Element) -> @out Result, UnsafeValue<Element>) -> @out Result {
110
94
// OPT: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
111
95
// OPT: [[UNMANAGED_VALUE:%.*]] = struct_extract [[UNSAFE_VALUE]]
112
- // OPT: [[UNOWNED_REF_OPTIONAL:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
113
- // OPT: [[GUARANTEED_REF:%.*]] = unchecked_enum_data [[UNOWNED_REF_OPTIONAL]]
114
- // OPT: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[GUARANTEED_REF]] : $Element on [[BASE]]
96
+ // OPT: [[UNOWNED_REF:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]]
97
+ // OPT: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[UNOWNED_REF]] : $Element on [[BASE]]
115
98
// OPT: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
116
- // OPT: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF '
99
+ // OPT: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF '
117
100
@_transparent
118
101
@inlinable
119
- func withGuaranteeingBase< Base, Result> ( base: Base , f: ( Element ) -> Result ) -> Result {
102
+ func withGuaranteeingBase< Base, Result> ( base: Base , _ f: ( Element ) -> Result ) -> Result {
120
103
// Just so we can not mark self as mutating. This is just a bitwise copy.
121
104
var tmp = self
122
105
return f ( Builtin . convertUnownedUnsafeToGuaranteed ( base, & tmp. _value) )
123
106
}
124
107
108
+ @_transparent
109
+ @inlinable
110
+ func assumingGuaranteeingBase< Result> ( _ f: ( Element ) -> Result ) -> Result {
111
+ // Just so we can not mark self as mutating. This is just a bitwise copy.
112
+ let fakeBase : Int ? = nil
113
+ return withGuaranteeingBase ( base: fakeBase, f)
114
+ }
115
+
125
116
// If the unmanaged value was initialized with a copy, release the underlying value.
126
117
//
127
118
// This will insert a release that can not be removed by the optimizer.
128
119
@_transparent
129
120
@inlinable
130
121
mutating func deinitialize( ) {
131
- _value = nil
122
+ Builtin . release ( _value)
132
123
}
133
124
134
125
// Return a new strong reference to the unmanaged value.
135
126
//
136
127
// This will insert a retain that can not be removed by the optimizer!
137
128
@_transparent
138
129
@inlinable
139
- public var strongRef : Element { _value. unsafelyUnwrapped }
130
+ public var strongRef : Element { _value }
140
131
}
0 commit comments