Skip to content

Commit a824e5a

Browse files
committed
Sema: Refactor getDisallowedOriginKind() to take an ExportContext
Converting the innermost DeclContext into a Decl won't work if the innermost DeclContext is the parent context of a VarDecl. Instead, use the relevant bit of state from the ExportContext, which is computed correctly. This fixes a regression caused by an earlier commit in this PR which our test suite did not catch.
1 parent 3044c05 commit a824e5a

6 files changed

+39
-22
lines changed

Diff for: lib/Sema/ResilienceDiagnostics.cpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,8 @@ TypeChecker::diagnoseDeclRefExportability(SourceLoc loc,
152152

153153
auto downgradeToWarning = DowngradeToWarning::No;
154154

155-
auto *DC = where.getDeclContext();
156155
auto originKind = getDisallowedOriginKind(
157-
D,
158-
*DC->getParentSourceFile(),
159-
DC->getInnermostDeclarationDeclContext(),
160-
downgradeToWarning);
156+
D, where, downgradeToWarning);
161157
if (originKind == DisallowedOriginKind::None)
162158
return false;
163159

@@ -195,11 +191,9 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
195191
if (!where.mustOnlyReferenceExportedDecls())
196192
return false;
197193

198-
auto *DC = where.getDeclContext();
199194
auto originKind = getDisallowedOriginKind(
200195
rootConf->getDeclContext()->getAsDecl(),
201-
*DC->getParentSourceFile(),
202-
DC->getInnermostDeclarationDeclContext());
196+
where);
203197
if (originKind == DisallowedOriginKind::None)
204198
return false;
205199

Diff for: lib/Sema/TypeCheckAccess.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -1460,22 +1460,22 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14601460
/// Local variant to swift::getDisallowedOriginKind for downgrade to warnings.
14611461
DisallowedOriginKind
14621462
swift::getDisallowedOriginKind(const Decl *decl,
1463-
const SourceFile &userSF,
1464-
const Decl *userContext,
1463+
ExportContext where,
14651464
DowngradeToWarning &downgradeToWarning) {
14661465
downgradeToWarning = DowngradeToWarning::No;
14671466
ModuleDecl *M = decl->getModuleContext();
1468-
if (userSF.isImportedImplementationOnly(M)) {
1467+
auto *SF = where.getDeclContext()->getParentSourceFile();
1468+
if (SF->isImportedImplementationOnly(M)) {
14691469
// Temporarily downgrade implementation-only exportability in SPI to
14701470
// a warning.
1471-
if (userContext->isSPI())
1471+
if (where.isSPI())
14721472
downgradeToWarning = DowngradeToWarning::Yes;
14731473

14741474
// Implementation-only imported, cannot be reexported.
14751475
return DisallowedOriginKind::ImplementationOnly;
1476-
} else if (decl->isSPI() && !userContext->isSPI()) {
1476+
} else if (decl->isSPI() && !where.isSPI()) {
14771477
// SPI can only be exported in SPI.
1478-
return userContext->getModuleContext() == M ?
1478+
return where.getDeclContext()->getParentModule() == M ?
14791479
DisallowedOriginKind::SPILocal :
14801480
DisallowedOriginKind::SPIImported;
14811481
}
@@ -1842,10 +1842,9 @@ static void checkExtensionGenericParamAccess(const ExtensionDecl *ED) {
18421842
}
18431843

18441844
DisallowedOriginKind swift::getDisallowedOriginKind(const Decl *decl,
1845-
const SourceFile &userSF,
1846-
const Decl *declContext) {
1845+
ExportContext where) {
18471846
auto downgradeToWarning = DowngradeToWarning::No;
1848-
return getDisallowedOriginKind(decl, userSF, declContext, downgradeToWarning);
1847+
return getDisallowedOriginKind(decl, where, downgradeToWarning);
18491848
}
18501849

18511850
void swift::checkAccessControl(Decl *D) {

Diff for: lib/Sema/TypeCheckAccess.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
namespace swift {
2323

2424
class Decl;
25+
class ExportContext;
2526
class SourceFile;
2627

2728
/// Performs access-related checks for \p D.
@@ -55,12 +56,10 @@ enum class DowngradeToWarning: bool {
5556
/// Returns the kind of origin, implementation-only import or SPI declaration,
5657
/// that restricts exporting \p decl from the given file and context.
5758
DisallowedOriginKind getDisallowedOriginKind(const Decl *decl,
58-
const SourceFile &userSF,
59-
const Decl *userContext);
59+
ExportContext where);
6060

6161
DisallowedOriginKind getDisallowedOriginKind(const Decl *decl,
62-
const SourceFile &userSF,
63-
const Decl *userContext,
62+
ExportContext where,
6463
DowngradeToWarning &downgradeToWarning);
6564

6665
} // end namespace swift

Diff for: lib/Sema/TypeCheckAvailability.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,19 @@ bool swift::isExported(const Decl *D) {
9898
ExportContext ExportContext::forDeclSignature(Decl *D) {
9999
auto *DC = D->getInnermostDeclContext();
100100
auto fragileKind = DC->getFragileFunctionKind();
101+
101102
bool spi = D->isSPI();
103+
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
104+
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i < e; ++i) {
105+
if (auto *VD = PBD->getAnchoringVarDecl(i)) {
106+
if (VD->isSPI()) {
107+
spi = true;
108+
break;
109+
}
110+
}
111+
}
112+
}
113+
102114
bool exported = ::isExported(D);
103115

104116
return ExportContext(DC, fragileKind, spi, exported);

Diff for: lib/Sema/TypeCheckProtocol.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4337,9 +4337,11 @@ static void checkExportability(Type depTy, Type replacementTy,
43374337
conformance->getRootConformance();
43384338
ModuleDecl *M = rootConformance->getDeclContext()->getParentModule();
43394339

4340+
auto where = ExportContext::forDeclSignature(
4341+
DC->getInnermostDeclarationDeclContext());
43404342
auto originKind = getDisallowedOriginKind(
43414343
rootConformance->getDeclContext()->getAsDecl(),
4342-
*SF, DC->getAsDecl());
4344+
where);
43434345
if (originKind == DisallowedOriginKind::None)
43444346
return;
43454347

Diff for: test/SPI/spi_members.swift

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@_spi(Foo)
4+
public class Bar {}
5+
6+
public struct Foo {
7+
public init() {}
8+
9+
@_spi(Foo) public func method(_: Bar) {}
10+
@_spi(Foo) public var property: Bar { Bar() }
11+
}

0 commit comments

Comments
 (0)