Skip to content

Commit d8b5a43

Browse files
committed
NFC: Increase test coverage for SPI enum elements.
These tests identified a gap in type checking the exportability of case statements. Unfortunately this gap is not simple to close, since exportability is usually checked during availability checking but availability checking isn't appropriate for case statements and there isn't existing infrastructure to check exportability independently.
1 parent c9d084d commit d8b5a43

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

test/SPI/Inputs/spi_helper.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,8 @@ public struct PublicStruct {
8989
@_spi(HelperSPI) public struct IntLike: ExpressibleByIntegerLiteral, Equatable {
9090
@_spi(HelperSPI) public init(integerLiteral: Int) {}
9191
}
92+
93+
public enum PublicEnum {
94+
case publicCase
95+
@_spi(HelperSPI) case spiCase
96+
}

test/SPI/export_spi_from_spi_module.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,32 @@
1111
public init() {}
1212
}
1313
@_spi(S) public protocol SPIProtocol {}
14+
public enum PublicEnum {
15+
case publicCase
16+
@_spi(S) case spiCase
17+
}
1418

1519
public func useOfSPITypeOk(_ p0: SPIProtocol, p1: SPIClass) -> SPIClass { fatalError() }
1620

1721
@inlinable
18-
func inlinable() -> SPIClass {
22+
public func inlinable() -> SPIClass {
1923
spiFunc()
2024
_ = SPIClass()
2125
}
2226

27+
@inlinable
28+
public func inlinable(_ e: PublicEnum) {
29+
switch e {
30+
case .publicCase: break
31+
case .spiCase: break
32+
@unknown default: break
33+
}
34+
35+
if case .spiCase = e {}
36+
37+
_ = PublicEnum.spiCase
38+
}
39+
2340
@frozen public struct FrozenStruct {
2441
public var spiInFrozen = SPIStruct()
2542
var spiTypeInFrozen = SPIStruct()

test/SPI/public_client.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ internalFunc() // expected-error {{cannot find 'internalFunc' in scope}}
2727
let c = SPIClass() // expected-error {{cannot find 'SPIClass' in scope}}
2828
let s = SPIStruct() // expected-error {{cannot find 'SPIStruct' in scope}}
2929
SPIEnum().spiMethod() // expected-error {{cannot find 'SPIEnum' in scope}}
30+
_ = PublicEnum.spiCase // expected-error {{'spiCase' is inaccessible due to '@_spi' protection level}}
3031

3132
var ps = PublicStruct()
3233
let _ = PublicStruct(alt_init: 1) // expected-error {{argument passed to call that takes no arguments}}

test/SPI/spi_client.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ print(s.spiVar)
4040

4141
SPIEnum().spiMethod()
4242
SPIEnum.A.spiMethod()
43+
_ = PublicEnum.spiCase
4344

4445
var ps = PublicStruct()
4546
let _ = PublicStruct(alt_init: 1)

test/SPI/spi_enum_element.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution
3+
4+
public enum PublicEnum {
5+
case publicCase
6+
@_spi(S) case spiCase
7+
}
8+
9+
@inlinable public func publicInlinableFunc(_ e: PublicEnum) {
10+
switch e {
11+
case .publicCase: break
12+
case .spiCase: break // FIXME: this should be diagnosed with "cannot use enum case 'spiCase' here; it is SPI"
13+
@unknown default: break
14+
}
15+
16+
if case .spiCase = e {} // FIXME: this should be diagnosed with "cannot use enum case 'spiCase' here; it is SPI"
17+
18+
_ = PublicEnum.spiCase // expected-error {{enum case 'spiCase' cannot be used in an '@inlinable' function because it is SPI}}
19+
}
20+
21+
@_spi(S)
22+
@inlinable public func spiInlinableFunc(_ e: PublicEnum) {
23+
switch e {
24+
case .publicCase: break
25+
case .spiCase: break
26+
@unknown default: break
27+
}
28+
29+
if case .spiCase = e {}
30+
31+
_ = PublicEnum.spiCase
32+
}
33+
34+
public struct PublicStruct {}
35+
@_spi(S) public struct SPIStruct {} // expected-note {{type declared here}}
36+
37+
public enum PublicEnumWithPayloads {
38+
case publicCasePublicPayload(_ s: PublicStruct)
39+
case publicCaseSPIPayload(_ s: SPIStruct) // expected-error {{cannot use struct 'SPIStruct' here; it is SPI}}
40+
@_spi(S) case spiCasePublicPayload(_ s: PublicStruct)
41+
@_spi(S) case spiCaseSPIPayload(_ s: SPIStruct)
42+
}
43+
44+
@_spi(S)
45+
public enum SPIEnumWithPayloads {
46+
case publicPayloadCase(_ s: PublicStruct)
47+
case spiPayloadCase(_ s: SPIStruct)
48+
}

0 commit comments

Comments
 (0)