diff --git a/Sources/OpenSwiftUICore/Render/GeometryEffect/GeometryEffect.swift b/Sources/OpenSwiftUICore/Render/GeometryEffect/GeometryEffect.swift index 908ea34d0..fe145f161 100644 --- a/Sources/OpenSwiftUICore/Render/GeometryEffect/GeometryEffect.swift +++ b/Sources/OpenSwiftUICore/Render/GeometryEffect/GeometryEffect.swift @@ -16,7 +16,7 @@ package import OpenGraphShims /// The only change the effect makes to the view's ancestors and descendants is /// to change the coordinate transform to and from them. @available(OpenSwiftUI_v1_0, *) -public protocol GeometryEffect: Animatable, ViewModifier where Body == Never { +public protocol GeometryEffect: Animatable, ViewModifier, _RemoveGlobalActorIsolation where Body == Never { /// Returns the current value of the effect. func effectValue(size: CGSize) -> ProjectionTransform diff --git a/Sources/OpenSwiftUICore/Util/ImpossibleActor.swift b/Sources/OpenSwiftUICore/Util/ImpossibleActor.swift deleted file mode 100644 index c4fe416b9..000000000 --- a/Sources/OpenSwiftUICore/Util/ImpossibleActor.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// ImpossibleActor.swift -// OpenSwiftUICore -// -// Audited for iOS 18.0 -// Status: Complete - -@globalActor -public actor _ImpossibleActor: Sendable { - public static var shared = _ImpossibleActor() -} - -@_marker -@_ImpossibleActor -public protocol _RemoveGlobalActorIsolation {} diff --git a/Sources/OpenSwiftUICore/Util/_RemoveGlobalActor.swift b/Sources/OpenSwiftUICore/Util/_RemoveGlobalActor.swift new file mode 100644 index 000000000..b0eb6ce62 --- /dev/null +++ b/Sources/OpenSwiftUICore/Util/_RemoveGlobalActor.swift @@ -0,0 +1,26 @@ +// +// _RemoveGlobalActor.swift +// OpenSwiftUICore +// +// Audited for 6.5.4 +// Status: Complete +// ID: E36588D6F4797F7C6EF26CC7E1C2D1CE + +@globalActor +public actor _ImpossibleActor: Sendable { + public static var shared = _ImpossibleActor() + + public nonisolated var unownedExecutor: UnownedSerialExecutor { + _ImpossibleExecutor().asUnownedSerialExecutor() + } +} + +private final class _ImpossibleExecutor: SerialExecutor { + func enqueue(_ job: consuming ExecutorJob) { + preconditionFailure("_RemoveGlobalActorIsolation is not intended to be used as a stand-alone protocol with a global actor isolation.") + } +} + +@_marker +@_ImpossibleActor +public protocol _RemoveGlobalActorIsolation {} diff --git a/Tests/OpenSwiftUICoreTests/Util/_RemoveGlobalActorTests.swift b/Tests/OpenSwiftUICoreTests/Util/_RemoveGlobalActorTests.swift new file mode 100644 index 000000000..f9deb261e --- /dev/null +++ b/Tests/OpenSwiftUICoreTests/Util/_RemoveGlobalActorTests.swift @@ -0,0 +1,33 @@ +// +// _RemoveGlobalActorTests.swift +// OpenSwiftUICoreTests + +import OpenSwiftUICore +import Testing + +// MARK: - _RemoveGlobalActorTests + +struct _RemoveGlobalActorTests { + @MainActor + protocol P {} + + @Test + func removeGlobalActorIsolation() { + struct A: P, _RemoveGlobalActorIsolation { + static func p() {} + } + A.p() + } + + #if compiler(>=6.2) + @Test + func standaloneConstraintCrash() async { + struct B: _RemoveGlobalActorIsolation { + static func p() {} + } + await #expect(processExitsWith: .failure) { + await B.p() + } + } + #endif +}