@@ -78,10 +78,48 @@ public struct UnsafeValue<Element: AnyObject> {
7878 }
7979
8080 // Access the underlying value at +0, guaranteeing its lifetime by base.
81+ //
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 {
83+ // CHECK: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
84+ // CHECK: [[COPY_BOX:%.*]] = alloc_box
85+ // CHECK: [[COPY_PROJ:%.*]] = project_box [[COPY_BOX]]
86+ // CHECK: store [[UNSAFE_VALUE]] to [trivial] [[COPY_PROJ]]
87+ // CHECK: [[VALUE_ADDR:%.*]] = begin_access [read] [unknown] [[COPY_PROJ]]
88+ // CHECK: [[STR_VALUE_ADDR:%.*]] = struct_element_addr [[VALUE_ADDR]]
89+ // 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]]
93+ // CHECK: [[GUARANTEED_REF_DEP_ON_BASE:%.*]] = mark_dependence [[GUARANTEED_REF]] : $Element on [[BASE]]
94+ // CHECK: end_access [[VALUE_ADDR]]
95+ // CHECK: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
96+ // CHECK: end_borrow [[GUARANTEED_REF_OPTIONAL]]
97+ // CHECK: destroy_value [[COPY_BOX]]
98+ // CHECK: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF'
99+ //
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 {
101+ // CANONICAL: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
102+ // 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]]
106+ // CANONICAL: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
107+ // CANONICAL: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF'
108+ //
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 {
110+ // OPT: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed (@guaranteed Element) -> @out Result, [[UNSAFE_VALUE:%.*]] : $UnsafeValue<Element>):
111+ // 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]]
115+ // OPT: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]])
116+ // OPT: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base1fqd_0_qd___qd_0_xXEtr0_lF'
81117 @_transparent
82118 @inlinable
83- func withGuaranteeingBase< Base> ( base: Base , f: ( Element ) -> ( ) ) {
84- // TODO: Once we have a builtin for mark_dependence, fill this in.
119+ func withGuaranteeingBase< Base, Result> ( base: Base , f: ( Element ) -> Result ) -> Result {
120+ // Just so we can not mark self as mutating. This is just a bitwise copy.
121+ var tmp = self
122+ return f ( Builtin . convertUnownedUnsafeToGuaranteed ( base, & tmp. _value) )
85123 }
86124
87125 // If the unmanaged value was initialized with a copy, release the underlying value.
0 commit comments