1919@MainActor
2020@resultBuilder
2121public enum AtomEffectBuilder {
22+ public static func buildBlock( ) -> some AtomEffect {
23+ EmptyEffect ( )
24+ }
25+
2226 public static func buildBlock< Effect: AtomEffect > ( _ effect: Effect ) -> Effect {
2327 effect
2428 }
2529
26- public static func buildBlock< each Effect : AtomEffect > ( _ effect: repeat each Effect ) -> some AtomEffect {
27- if #available( iOS 17 , macOS 14 , tvOS 17 , watchOS 10 , * ) {
28- return BlockEffect ( repeat each effect)
29- }
30- else {
31- return BlockBCEffect ( repeat each effect)
32- }
30+ // NB: The combination of variadic type and opaque return type in iOS 16 fails to demangle
31+ // the witness for the return type, which causes a runtime crash.
32+ // Once iOS 16 support is dropped, this function will be changed to return an opaque type.
33+ public static func buildBlock< each Effect : AtomEffect > ( _ effect: repeat each Effect ) -> BlockEffect {
34+ BlockEffect ( repeat each effect)
3335 }
3436
3537 public static func buildIf< Effect: AtomEffect > ( _ effect: Effect ? ) -> some AtomEffect {
@@ -54,6 +56,46 @@ public enum AtomEffectBuilder {
5456}
5557
5658public extension AtomEffectBuilder {
59+ // Use type pack once it is available in iOS 17 or newer.
60+ // struct BlockEffect<each Effect: AtomEffect>: AtomEffect
61+ struct BlockEffect : AtomEffect {
62+ private let _initializing : @MainActor ( Context ) -> Void
63+ private let _initialized : @MainActor ( Context ) -> Void
64+ private let _updated : @MainActor ( Context ) -> Void
65+ private let _released : @MainActor ( Context ) -> Void
66+
67+ internal init < each Effect : AtomEffect > ( _ effect: repeat each Effect ) {
68+ _initializing = { context in
69+ repeat ( each effect) . initializing ( context: context)
70+ }
71+ _initialized = { context in
72+ repeat ( each effect) . initialized ( context: context)
73+ }
74+ _updated = { context in
75+ repeat ( each effect) . updated ( context: context)
76+ }
77+ _released = { context in
78+ repeat ( each effect) . released ( context: context)
79+ }
80+ }
81+
82+ public func initializing( context: Context ) {
83+ _initializing ( context)
84+ }
85+
86+ public func initialized( context: Context ) {
87+ _initialized ( context)
88+ }
89+
90+ public func updated( context: Context ) {
91+ _updated ( context)
92+ }
93+
94+ public func released( context: Context ) {
95+ _released ( context)
96+ }
97+ }
98+
5799 struct ConditionalEffect < TrueEffect: AtomEffect , FalseEffect: AtomEffect > : AtomEffect {
58100 internal enum Storage {
59101 case trueEffect( TrueEffect )
@@ -108,68 +150,7 @@ public extension AtomEffectBuilder {
108150}
109151
110152private extension AtomEffectBuilder {
111- @available ( iOS 17 , macOS 14 , tvOS 17 , watchOS 10 , * )
112- struct BlockEffect < each Effect : AtomEffect > : AtomEffect {
113- private let effect : ( repeat each Effect )
114-
115- init ( _ effect: repeat each Effect ) {
116- self . effect = ( repeat each effect)
117- }
118-
119- func initializing( context: Context ) {
120- repeat ( each effect) . initializing ( context: context)
121- }
122-
123- func initialized( context: Context ) {
124- repeat ( each effect) . initialized ( context: context)
125- }
126-
127- func updated( context: Context ) {
128- repeat ( each effect) . updated ( context: context)
129- }
130-
131- func released( context: Context ) {
132- repeat ( each effect) . released ( context: context)
133- }
134- }
135-
136- struct BlockBCEffect : AtomEffect {
137- private let _initializing : @MainActor ( Context ) -> Void
138- private let _initialized : @MainActor ( Context ) -> Void
139- private let _updated : @MainActor ( Context ) -> Void
140- private let _released : @MainActor ( Context ) -> Void
141-
142- init < each Effect : AtomEffect > ( _ effect: repeat each Effect ) {
143- _initializing = { context in
144- repeat ( each effect) . initializing ( context: context)
145- }
146- _initialized = { context in
147- repeat ( each effect) . initialized ( context: context)
148- }
149- _updated = { context in
150- repeat ( each effect) . updated ( context: context)
151- }
152- _released = { context in
153- repeat ( each effect) . released ( context: context)
154- }
155- }
156-
157- func initializing( context: Context ) {
158- _initializing ( context)
159- }
160-
161- func initialized( context: Context ) {
162- _initialized ( context)
163- }
164-
165- func updated( context: Context ) {
166- _updated ( context)
167- }
168-
169- func released( context: Context ) {
170- _released ( context)
171- }
172- }
153+ struct EmptyEffect : AtomEffect { }
173154
174155 struct IfEffect < Effect: AtomEffect > : AtomEffect {
175156 private let effect : Effect ?
0 commit comments