File tree Expand file tree Collapse file tree 4 files changed +37
-16
lines changed Expand file tree Collapse file tree 4 files changed +37
-16
lines changed Original file line number Diff line number Diff line change @@ -2049,10 +2049,8 @@ bool Decl::isSPI() const {
2049
2049
}
2050
2050
2051
2051
ArrayRef<Identifier> Decl::getSPIGroups () const {
2052
- if (auto vd = dyn_cast<ValueDecl>(this )) {
2053
- if (vd->getFormalAccess () < AccessLevel::Public)
2054
- return ArrayRef<Identifier>();
2055
- } else if (!isa<ExtensionDecl>(this ))
2052
+ if (!isa<ValueDecl>(this ) &&
2053
+ !isa<ExtensionDecl>(this ))
2056
2054
return ArrayRef<Identifier>();
2057
2055
2058
2056
return evaluateOrDefault (getASTContext ().evaluator ,
@@ -2063,10 +2061,8 @@ ArrayRef<Identifier> Decl::getSPIGroups() const {
2063
2061
llvm::ArrayRef<Identifier>
2064
2062
SPIGroupsRequest::evaluate (Evaluator &evaluator, const Decl *decl) const {
2065
2063
// Applies only to public ValueDecls and ExtensionDecls.
2066
- if (auto vd = dyn_cast<ValueDecl>(decl))
2067
- assert (vd->getFormalAccess () >= AccessLevel::Public);
2068
- else
2069
- assert (isa<ExtensionDecl>(decl));
2064
+ assert (isa<ValueDecl>(decl) ||
2065
+ isa<ExtensionDecl>(decl));
2070
2066
2071
2067
// First, look for local attributes.
2072
2068
llvm::SetVector<Identifier> spiGroups;
Original file line number Diff line number Diff line change @@ -885,7 +885,8 @@ void AttributeChecker::visitSPIAccessControlAttr(SPIAccessControlAttr *attr) {
885
885
if (auto VD = dyn_cast<ValueDecl>(D)) {
886
886
// VD must be public or open to use an @_spi attribute.
887
887
auto declAccess = VD->getFormalAccess ();
888
- if (declAccess < AccessLevel::Public) {
888
+ if (declAccess < AccessLevel::Public &&
889
+ !VD->getAttrs ().hasAttribute <UsableFromInlineAttr>()) {
889
890
diagnoseAndRemoveAttr (attr,
890
891
diag::spi_attribute_on_non_public,
891
892
declAccess,
Original file line number Diff line number Diff line change 1
- // Checks for SPI declarations and limited exposability
1
+ // Checks for SPI declarations and limited exportability.
2
2
3
3
// RUN: %empty-directory(%t)
4
4
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5
5
5
6
+ // Without -enable-library-evolution the exportability check looks at struct internal properties.
7
+ // RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5
8
+
6
9
// SPI declarations
7
10
@_spi ( MySPI) public func spiFunc( ) { } // expected-note {{global function 'spiFunc()' is not '@usableFromInline' or public}}
8
11
@_spi ( + ) public func invalidSPIName( ) { } // expected-error {{expected an SPI identifier as subject of the '@_spi' attribute}}
@@ -55,3 +58,26 @@ public struct PublicStructWithProperties {
55
58
public var a : SPIClass // expected-error {{cannot use class 'SPIClass' here; it is SPI}}
56
59
public var b = SPIClass ( ) // expected-error {{cannot use class 'SPIClass' here; it is SPI}}
57
60
}
61
+
62
+ @_spi ( S)
63
+ @usableFromInline
64
+ func usableFromInlineFunc( _ a: SPIStruct ) -> SPIStruct {
65
+ fatalError ( )
66
+ }
67
+
68
+ @_spi ( S)
69
+ public final class ClassWithUsables {
70
+ @usableFromInline
71
+ var usableFromInlineVar = SPIClass ( )
72
+
73
+ @usableFromInline
74
+ func usableFromInlineFunc( _ a: SPIStruct ) -> SPIStruct {
75
+ fatalError ( )
76
+ }
77
+ }
78
+
79
+ @_spi ( S)
80
+ public struct NestedParent {
81
+ public struct Nested { }
82
+ let nested : Nested
83
+ }
Original file line number Diff line number Diff line change @@ -241,9 +241,8 @@ extension NormalProtoAssocHolder {
241
241
242
242
@_spi ( AcceptInSPI)
243
243
@inlinable public func SPIlocalTypeAlias( ) {
244
- // FIXME these should be accepted.
245
- typealias LocalUser = NormalProtoAssocHolder < NormalStruct > // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
246
- typealias LocalGenericUser < T> = ( T , NormalProtoAssocHolder < NormalStruct > ) // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
244
+ typealias LocalUser = NormalProtoAssocHolder < NormalStruct >
245
+ typealias LocalGenericUser < T> = ( T , NormalProtoAssocHolder < NormalStruct > )
247
246
248
247
typealias LocalProtoAssoc < T: NormalProto > = T . Assoc
249
248
_ = LocalProtoAssoc < NormalStruct > ( )
@@ -258,9 +257,8 @@ extension NormalProtoAssocHolder {
258
257
259
258
@_spi ( AcceptInSPI)
260
259
@inlinable public func SPIlocalFunctions( ) {
261
- // FIXME these should be accepted.
262
- func local( _: NormalProtoAssocHolder < NormalStruct > ) { } // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
263
- func localReturn( ) -> NormalProtoAssocHolder < NormalStruct > { fatalError ( ) } // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
260
+ func local( _: NormalProtoAssocHolder < NormalStruct > ) { }
261
+ func localReturn( ) -> NormalProtoAssocHolder < NormalStruct > { fatalError ( ) }
264
262
let _ = { ( _: NormalProtoAssocHolder < NormalStruct > ) in return }
265
263
let _ = { ( ) -> NormalProtoAssocHolder < NormalStruct > in fatalError ( ) }
266
264
}
You can’t perform that action at this time.
0 commit comments