Skip to content

Commit 4c9a9ca

Browse files
authored
Merge pull request #85039 from xymus/exportability-var-diag
Sema: Custom diagnostic for var decls referencing a restricted type
2 parents 1ba32b2 + 2d339c1 commit 4c9a9ca

19 files changed

+128
-120
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3831,7 +3831,8 @@ ERROR(decl_from_hidden_module,none,
38313831
"in an extension with public or '@usableFromInline' members|"
38323832
"in an extension with conditional conformances|"
38333833
"in a public or '@usableFromInline' conformance|"
3834-
"in an '@available' attribute here}1; "
3834+
"in an '@available' attribute here|"
3835+
"in a property declaration marked public or in a '@frozen' or '@usableFromInline' context}1; "
38353836
"%select{%2 has been imported as implementation-only|"
38363837
"it is an SPI imported from %2|"
38373838
"it is SPI|"
@@ -3848,7 +3849,8 @@ ERROR(typealias_desugars_to_type_from_hidden_module,none,
38483849
"in an extension with public or '@usableFromInline' members|"
38493850
"in an extension with conditional conformance|"
38503851
"in a public or '@usableFromInline' conformance|"
3851-
"<<ERROR>>}3 "
3852+
"<<ERROR>>|"
3853+
"in a property declaration marked public or in a '@frozen' or '@usableFromInline' context}3 "
38523854
"because %select{%4 has been imported as implementation-only|"
38533855
"it is an SPI imported from %4|"
38543856
"<<ERROR>>|"
@@ -3863,7 +3865,8 @@ ERROR(conformance_from_implementation_only_module,none,
38633865
"as result builder here|"
38643866
"in an extension with public or '@usableFromInline' members|"
38653867
"in an extension with conditional conformances|"
3866-
"<<ERROR>>|<<ERROR>>}2; "
3868+
"<<ERROR>>|<<ERROR>>|"
3869+
"in a property declaration marked public or in a '@frozen' or '@usableFromInline' context}2; "
38673870
"%select{%3 has been imported as implementation-only|"
38683871
"the conformance is declared as SPI in %3|"
38693872
"the conformance is declared as SPI|"

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ static bool shouldDiagnoseDeclAccess(const ValueDecl *D,
263263
case ExportabilityReason::General:
264264
case ExportabilityReason::ResultBuilder:
265265
case ExportabilityReason::PropertyWrapper:
266+
case ExportabilityReason::PublicVarDecl:
266267
return false;
267268
}
268269
}

lib/Sema/TypeCheckAccess.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,7 +2376,8 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
23762376
if (seenVars.count(theVar))
23772377
return;
23782378

2379-
checkType(theVar->getValueInterfaceType(), /*typeRepr*/nullptr, theVar);
2379+
checkType(theVar->getValueInterfaceType(), /*typeRepr*/nullptr, theVar,
2380+
ExportabilityReason::PublicVarDecl);
23802381

23812382
for (auto attr : theVar->getAttachedPropertyWrappers()) {
23822383
checkType(attr->getType(), attr->getTypeRepr(), theVar,
@@ -2398,7 +2399,8 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
23982399
});
23992400

24002401
checkType(TP->hasType() ? TP->getType() : Type(),
2401-
TP->getTypeRepr(), anyVar ? (Decl *)anyVar : (Decl *)PBD);
2402+
TP->getTypeRepr(), anyVar ? (Decl *)anyVar : (Decl *)PBD,
2403+
ExportabilityReason::PublicVarDecl);
24022404

24032405
// Check the property wrapper types.
24042406
if (anyVar) {

lib/Sema/TypeCheckAvailability.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ enum class DeclAvailabilityFlag : uint8_t {
6969
using DeclAvailabilityFlags = OptionSet<DeclAvailabilityFlag>;
7070

7171
// This enum must be kept in sync with
72-
// diag::decl_from_hidden_module and
72+
// diag::decl_from_hidden_module,
73+
// diag::typealias_desugars_to_type_from_hidden_module, and
7374
// diag::conformance_from_implementation_only_module.
7475
enum class ExportabilityReason : unsigned {
7576
General,
@@ -79,6 +80,7 @@ enum class ExportabilityReason : unsigned {
7980
ExtensionWithConditionalConformances,
8081
Inheritance,
8182
AvailableAttribute,
83+
PublicVarDecl,
8284
};
8385

8486
/// A description of the restrictions on what declarations can be referenced

test/Availability/spi-available-context.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ public class Bar {
1818

1919
@available(macOS 10.10, iOS 8.0, *)
2020
public class Baz {
21-
public var macos: MacOSSPIProto? // expected-error {{cannot use protocol 'MacOSSPIProto' here; it is SPI}}
21+
public var macos: MacOSSPIProto? // expected-error {{cannot use protocol 'MacOSSPIProto' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is SPI}}
2222
public var ios: iOSSPIProto?
2323
}

test/Availability/spi-available-swift-module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ import Foo
2121

2222
@available(macOS 10.10, iOS 8.0, *)
2323
public struct Foo {
24-
public var macos: MacOSSPIClass // expected-error {{cannot use class 'MacOSSPIClass' here; it is an SPI imported from 'Foo'}}
24+
public var macos: MacOSSPIClass // expected-error {{cannot use class 'MacOSSPIClass' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from 'Foo'}}
2525
public var ios: iOSSPIClass
2626
}

test/ClangImporter/availability_spi_as_unavailable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import SPIContainer
99
@_spi(a) public let a: SPIInterface1 = .init()
1010
@_spi(a) public let b: SPIInterface2 = .init()
1111

12-
public let c: SPIInterface1 = .init() // expected-error{{cannot use class 'SPIInterface1' here; it is an SPI imported from 'SPIContainer'}}
13-
public let d: SPIInterface2 = .init() // expected-error{{cannot use class 'SPIInterface2' here; it is an SPI imported from 'SPIContainer'}}
12+
public let c: SPIInterface1 = .init() // expected-error{{cannot use class 'SPIInterface1' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from 'SPIContainer'}}
13+
public let d: SPIInterface2 = .init() // expected-error{{cannot use class 'SPIInterface2' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from 'SPIContainer'}}
1414

1515
@inlinable
1616
public func inlinableUsingSPI() {
@@ -21,7 +21,7 @@ public func inlinableUsingSPI() {
2121
public let e: SPIInterface2 = .init()
2222

2323
@available(iOS, unavailable)
24-
public let f: SPIInterface2 = .init() // expected-error{{cannot use class 'SPIInterface2' here; it is an SPI imported from 'SPIContainer'}}
24+
public let f: SPIInterface2 = .init() // expected-error{{cannot use class 'SPIInterface2' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from 'SPIContainer'}}
2525

2626
@inlinable
2727
@available(macOS, unavailable)

test/ClangImporter/availability_spi_as_unavailable_bridging_header.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
@_spi(a) public let a: SPIInterface1
66
@_spi(a) public let b: SPIInterface2
77

8-
public let c: SPIInterface1 // expected-error{{cannot use class 'SPIInterface1' here; it is an SPI imported from '__ObjC'}}
9-
public let d: SPIInterface2 // expected-error{{cannot use class 'SPIInterface2' here; it is an SPI imported from '__ObjC'}}
8+
public let c: SPIInterface1 // expected-error{{cannot use class 'SPIInterface1' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from '__ObjC'}}
9+
public let d: SPIInterface2 // expected-error{{cannot use class 'SPIInterface2' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from '__ObjC'}}
1010

1111
@inlinable
1212
public func inlinableUsingSPI() { // expected-warning{{public declarations should have an availability attribute with an introduction version}}

test/ClangImporter/availability_spi_transitive.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ import SPIContainerImporter
55

66
@_spi(a) public let a: SPIInterface1
77

8-
public let c: SPIInterface1 // expected-error{{cannot use class 'SPIInterface1' here; it is an SPI imported from 'SPIContainer'}}
8+
public let c: SPIInterface1 // expected-error{{cannot use class 'SPIInterface1' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; it is an SPI imported from 'SPIContainer'}}

test/SPI/implementation_only_spi_import_exposability.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public protocol IOIProtocol {}
3434

3535
public struct PublicStruct : IOIProtocol, SPIProtocol { // expected-error {{cannot use protocol 'IOIProtocol' in a public or '@usableFromInline' conformance; 'Lib' has been imported as implementation-only}}
3636
// expected-error @-1 {{cannot use protocol 'SPIProtocol' in a public or '@usableFromInline' conformance; 'Lib' has been imported as implementation-only}}
37-
public var spiStruct = SPIStruct() // expected-error {{cannot use struct 'SPIStruct' here; 'Lib' has been imported as implementation-only}}
38-
public var ioiStruct = IOIStruct() // expected-error {{cannot use struct 'IOIStruct' here; 'Lib' has been imported as implementation-only}}
37+
public var spiStruct = SPIStruct() // expected-error {{cannot use struct 'SPIStruct' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'Lib' has been imported as implementation-only}}
38+
public var ioiStruct = IOIStruct() // expected-error {{cannot use struct 'IOIStruct' in a property declaration marked public or in a '@frozen' or '@usableFromInline' context; 'Lib' has been imported as implementation-only}}
3939

4040
@inlinable
4141
public func publicInlinable() {

0 commit comments

Comments
 (0)