[AST/Sema/SIL] Implement @_inheritActorContext(always)

- Extend `@_inheritActorContext` attribute to support optional `always` modifier.
  The new modifier will make closure context isolated even if the parameter is not
  captured by the closure.
- Implementation `@_inheritActorContext` attribute validation - it could only be
  used on parameter that have `@Sendable` or `sending` and `@isolated(any)` or
  `async` function type (downgraded to a warning until future major Swift mode
  to avoid source compatibility issues).
- Add a new language feature that guards use of `@_inheritActorContext(always)` in swift interface files
- Update `getLoweredLocalCaptures` to add an entry for isolation parameter implicitly captured by `@_inheritActorContext(always)`
- Update serialization code to store `always` modifier

(cherry picked from commit 04d46760bb)
(cherry picked from commit c050e8f75a)
(cherry picked from commit c0aca5384b)
(cherry picked from commit a4f6d710cf)
(cherry picked from commit 6c911f5d42)
(cherry picked from commit 17b8f7ef12)
This commit is contained in:
Pavel Yaskevich
2025-05-12 00:10:28 -07:00
parent 3db1314ba8
commit e12201769d
33 changed files with 583 additions and 288 deletions

View File

@@ -0,0 +1,43 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library
// RUN: %FileCheck %s < %t/Library.swiftinterface
// CHECK-NOT: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK: public func globalTest(@_inheritActorContext _: @Sendable () async -> Swift.Void)
// CHECK-NOT: #endif
public func globalTest(@_inheritActorContext _: @Sendable () async -> Void) {}
// CHECK: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK-NEXT: public func globalTestAlways(@_inheritActorContext(always) _: @Sendable () async -> Swift.Void)
// CHECK-NEXT: #endif
public func globalTestAlways(@_inheritActorContext(always) _: @Sendable () async -> Void) {}
public struct Test {
// CHECK-NOT: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK: public init(@_inheritActorContext x: @Sendable () async -> Swift.Int)
// CHECK-NOT: #endif
public init(@_inheritActorContext x: @Sendable () async -> Int) {}
// CHECK: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK-NEXT: #if compiler(>=5.3) && $SendingArgsAndResults
// CHECK-NEXT: public init(@_inheritActorContext(always) y: sending () async -> Swift.Void)
// CHECK-NEXT: #else
// CHECK-NEXT: public init(@_inheritActorContext(always) y: () async -> Swift.Void)
// CHECK-NEXT: #endif
// CHECK-NEXT: #endif
public init(@_inheritActorContext(always) y: sending () async -> Void) {}
// CHECK-NOT: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK: public subscript(@_inheritActorContext _: @Sendable () async -> Swift.Void) -> Swift.Bool {
// CHECK-NEXT: get
// CHECK-NEXT: }
// CHECK-NOT: #endif
public subscript(@_inheritActorContext _: @Sendable () async -> Void) -> Bool { false }
// CHECK: #if compiler(>=5.3) && $AlwaysInheritActorContext
// CHECK-NEXT: public subscript(@_inheritActorContext(always) _: @Sendable (Swift.Int) async -> Swift.Void) -> Swift.Bool {
// CHECK-NEXT: get
// CHECK-NEXT: }
public subscript(@_inheritActorContext(always) _: @Sendable (Int) async -> Void) -> Bool { false }
}