1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/// Test @_spiOnly exportability type-checking
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
/// Generate dependencies.
// RUN: %target-swift-frontend -emit-module %t/PublicLib.swift \
// RUN: -module-name PublicLib -emit-module-path %t/PublicLib.swiftmodule \
// RUN: -swift-version 5 -enable-library-evolution
// RUN: %target-swift-frontend -emit-module %t/SPIOnlyImportedLib.swift \
// RUN: -module-name SPIOnlyImportedLib \
// RUN: -emit-module-path %t/SPIOnlyImportedLib.swiftmodule \
// RUN: -swift-version 5 -enable-library-evolution -I %t
/// Test the client.
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t -verify \
// RUN: -experimental-spi-only-imports
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t -verify \
// RUN: -experimental-spi-only-imports \
// RUN: -enable-library-evolution
/// Generate the swiftinterface of the working code and verify it.
// RUN: %target-swift-emit-module-interfaces(%t/Client.swiftinterface, %t/Client.private.swiftinterface) \
// RUN: %t/Client.swift -I %t -DSKIP_ERRORS \
// RUN: -experimental-spi-only-imports
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.swiftinterface) -I %t
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.private.swiftinterface) -I %t
//--- PublicLib.swift
public struct PublicType {
public init() {}
}
public protocol PublicProtocol {}
public func conformanceUse(_ a: PublicProtocol) {}
@propertyWrapper
public struct PublicPropertyWrapper<T> {
public var wrappedValue: T
public init(wrappedValue value: T) { self.wrappedValue = value }
public init(_ value: T) { self.wrappedValue = value }
}
//--- SPIOnlyImportedLib.swift
import PublicLib
public func spiOnlyFunc() -> String { fatalError() }
public protocol SPIOnlyProto {
}
public struct SPIOnlyStruct {
public init() {}
public func structMethod() {}
}
public class SPIOnlyClass<P: PublicProtocol> {
public init(p: P) {}
public func classMethod() {}
}
public enum SPIOnlyEnum {
case A
case B
public func enumMethod() {}
}
extension PublicType {
public func spiOnlyExtensionMethod() {}
}
extension PublicType : PublicProtocol {}
@propertyWrapper
public struct SPIOnlyPropertyWrapper<T> {
public var wrappedValue: T
public init(wrappedValue value: T) { self.wrappedValue = value }
public init(_ value: T) { self.wrappedValue = value }
}
//--- Client.swift
import PublicLib
@_spiOnly import SPIOnlyImportedLib
#if !SKIP_ERRORS
public func publicUser<T: SPIOnlyProto>(_ a: SPIOnlyStruct, t: T) -> SPIOnlyStruct { fatalError() }
// expected-error @-1 2 {{cannot use struct 'SPIOnlyStruct' here; 'SPIOnlyImportedLib' was imported for SPI only}}
// expected-error @-2 {{cannot use protocol 'SPIOnlyProto' here; 'SPIOnlyImportedLib' was imported for SPI only}}
#endif
@_spi(X) public func spiUser(_ a: SPIOnlyStruct) -> SPIOnlyStruct { fatalError() }
internal func internalUser(_ a: SPIOnlyStruct) -> SPIOnlyStruct { fatalError() }
#if !SKIP_ERRORS
@inlinable
public func publicInlinableUser() {
_ = spiOnlyFunc() // expected-error {{global function 'spiOnlyFunc()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
var x: SPIOnlyStruct // expected-error {{struct 'SPIOnlyStruct' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
x = SPIOnlyStruct() // expected-error {{struct 'SPIOnlyStruct' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
// expected-error @-1 {{initializer 'init()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
x.structMethod() // expected-error {{instance method 'structMethod()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
var c: SPIOnlyClass<PublicType> // expected-error {{generic class 'SPIOnlyClass' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
c = SPIOnlyClass(p: PublicType()) // expected-error {{generic class 'SPIOnlyClass' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
// expected-error @-1 {{initializer 'init(p:)' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
c.classMethod() // expected-error {{instance method 'classMethod()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
var e: SPIOnlyEnum // expected-error {{enum 'SPIOnlyEnum' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
e = .A // expected-error {{enum case 'A' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
e.enumMethod() // expected-error {{instance method 'enumMethod()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
let p: PublicType = PublicType()
p.spiOnlyExtensionMethod() // expected-error {{instance method 'spiOnlyExtensionMethod()' cannot be used in an '@inlinable' function because 'SPIOnlyImportedLib' was imported for SPI only}}
conformanceUse(p) // expected-error{{cannot use conformance of 'PublicType' to 'PublicProtocol' here; 'SPIOnlyImportedLib' was imported for SPI only}}
}
#endif
@inlinable @_spi(X)
public func spiInlinableUser() {
_ = spiOnlyFunc()
var x: SPIOnlyStruct
x = SPIOnlyStruct()
x.structMethod()
let p: PublicType = PublicType()
p.spiOnlyExtensionMethod()
conformanceUse(p)
}
public func implementationDetailsUser() {
_ = spiOnlyFunc()
var x: SPIOnlyStruct
x = SPIOnlyStruct()
x.structMethod()
let p: PublicType = PublicType()
p.spiOnlyExtensionMethod()
conformanceUse(p)
}
public struct ClientStruct {
#if !SKIP_ERRORS
public var a: SPIOnlyStruct // expected-error {{cannot use struct 'SPIOnlyStruct' here; 'SPIOnlyImportedLib' was imported for SPI only}}
@SPIOnlyPropertyWrapper(42) public var aWrapped: Any // expected-error {{cannot use generic struct 'SPIOnlyPropertyWrapper' as property wrapper here; 'SPIOnlyImportedLib' was imported for SPI only}}
#endif
@PublicPropertyWrapper(SPIOnlyStruct()) public var bWrapped: Any
}
|