AST: Only treat @backDeployed functions as fragile on platforms with an active attribute.

Previously, typechecking and SILGen would treat a function body as fragile as long as the declaration had a `@backDeployed` attribute, regardless of the platform specified by the attribute. This was overly conservative since back deployed functions are only emitted into the client on specific platforms. Now a `@backDeployed` function can reference non-`public` declarations on the platforms it is resilient on:

```
@backDeployed(before: iOS 15)
public func foo() {
  #if os(iOS)
  // Fragile; this code may be emitted into the client.
  #else
  // Resilient; this code won't ever be exposed to clients.
  #endif
}
```

Resolves rdar://105298520
This commit is contained in:
Allan Shortlidge
2023-02-21 22:42:34 -08:00
parent 11c32fa943
commit f1a8740ba5
11 changed files with 102 additions and 44 deletions

View File

@@ -5,17 +5,19 @@
// RUN: %target-swift-typecheck-module-from-interface(%t/Test.swiftinterface)
// RUN: %FileCheck %s < %t/Test.swiftinterface
// REQUIRES: OS=macosx
public struct TopLevelStruct {
// TODO: Print `@backDeployed` in swiftinterfaces (rdar://104920183)
// CHECK: @_backDeploy(before: macOS 12.0)
// CHECK: public func backDeployedFunc_SinglePlatform() -> Swift.Int { return 42 }
// CHECK: public func backDeployedFunc_SinglePlatform() -> Swift.Int { return 41 }
@backDeployed(before: macOS 12.0)
public func backDeployedFunc_SinglePlatform() -> Int { return 42 }
public func backDeployedFunc_SinglePlatform() -> Int { return 41 }
// CHECK: @_backDeploy(before: macOS 12.0, iOS 15.0)
// CHECK: public func backDeployedFunc_MultiPlatform() -> Swift.Int { return 43 }
// CHECK: public func backDeployedFunc_MultiPlatform() -> Swift.Int { return 42 }
@backDeployed(before: macOS 12.0, iOS 15.0)
public func backDeployedFunc_MultiPlatform() -> Int { return 43 }
public func backDeployedFunc_MultiPlatform() -> Int { return 42 }
// CHECK: @_backDeploy(before: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0)
// CHECK: public func backDeployedFunc_MultiPlatformSeparate() -> Swift.Int { return 43 }
@@ -27,15 +29,15 @@ public struct TopLevelStruct {
// CHECK: @_backDeploy(before: macOS 12.0)
// CHECK: public var backDeployedComputedProperty: Swift.Int {
// CHECK: get { 44 }
// CHECK: }
// CHECK-NEXT: get { 44 }
// CHECK-NEXT: }
@backDeployed(before: macOS 12.0)
public var backDeployedComputedProperty: Int { 44 }
// CHECK: @_backDeploy(before: macOS 12.0)
// CHECK: public var backDeployedPropertyWithAccessors: Swift.Int {
// CHECK: get { 45 }
// CHECK: }
// CHECK-NEXT: get { 45 }
// CHECK-NEXT: }
@backDeployed(before: macOS 12.0)
public var backDeployedPropertyWithAccessors: Int {
get { 45 }
@@ -43,27 +45,42 @@ public struct TopLevelStruct {
// CHECK: @_backDeploy(before: macOS 12.0)
// CHECK: public subscript(index: Swift.Int) -> Swift.Int {
// CHECK: get { 46 }
// CHECK: }
// CHECK-NEXT: get { 46 }
// CHECK-NEXT: }
@backDeployed(before: macOS 12.0)
public subscript(index: Int) -> Int {
get { 46 }
}
}
// CHECK: @_backDeploy(before: iOS 15.0)
// CHECK: public func backDeployedFunc_iOSOnly() -> Swift.Int
// CHECK-NOT: return 99
@backDeployed(before: iOS 15.0)
public func backDeployedFunc_iOSOnly() -> Int { return 99 }
// CHECK: @_backDeploy(before: macOS 12.0)
// CHECK: public func backDeployTopLevelFunc1() -> Swift.Int { return 47 }
// CHECK: public func backDeployTopLevelFunc_macOS() -> Swift.Int {
// CHECK-NEXT: return 47
// CHECK-NEXT: }
// CHECK-NOT: fatalError()
@backDeployed(before: macOS 12.0)
public func backDeployTopLevelFunc1() -> Int { return 47 }
public func backDeployTopLevelFunc_macOS() -> Int {
#if os(macOS)
return 47
#else
fatalError()
#endif
}
// MARK: - Availability macros
// CHECK: @_backDeploy(before: macOS 12.1)
// CHECK: public func backDeployTopLevelFunc2() -> Swift.Int { return 48 }
// CHECK: public func backDeployTopLevelFunc_macOS12_1() -> Swift.Int { return 48 }
@backDeployed(before: _macOS12_1)
public func backDeployTopLevelFunc2() -> Int { return 48 }
public func backDeployTopLevelFunc_macOS12_1() -> Int { return 48 }
// CHECK: @_backDeploy(before: macOS 12.1, iOS 15.1)
// CHECK: public func backDeployTopLevelFunc3() -> Swift.Int { return 49 }
// CHECK: public func backDeployTopLevelFunc_myProject() -> Swift.Int { return 49 }
@backDeployed(before: _myProject 1.0)
public func backDeployTopLevelFunc3() -> Int { return 49 }
public func backDeployTopLevelFunc_myProject() -> Int { return 49 }