Skip to content

Commit a22e65e

Browse files
committed
Move logic to TypeCheckAccess.getDisallowedOriginKind
1 parent e20b0f8 commit a22e65e

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,25 +1447,55 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14471447
///
14481448
/// Local variant to swift::getDisallowedOriginKind for downgrade to warnings.
14491449
DisallowedOriginKind
1450-
swift::getDisallowedOriginKind(const Decl *decl,
1451-
ExportContext where,
1450+
swift::getDisallowedOriginKind(const Decl *decl, ExportContext where,
14521451
DowngradeToWarning &downgradeToWarning) {
14531452
downgradeToWarning = DowngradeToWarning::No;
14541453
ModuleDecl *M = decl->getModuleContext();
1454+
14551455
auto *SF = where.getDeclContext()->getParentSourceFile();
14561456
if (SF->isImportedImplementationOnly(M)) {
1457+
14571458
// Temporarily downgrade implementation-only exportability in SPI to
14581459
// a warning.
14591460
if (where.isSPI())
14601461
downgradeToWarning = DowngradeToWarning::Yes;
14611462

1463+
// Even if the current module is @_implementationOnly, Swift should
1464+
// not report an error in the cases where the decl is also exported from
1465+
// a non @_implementationOnly module. Thus, we look at all the imported
1466+
// modules and see if we can find the decl in a non @_implementationOnly
1467+
// module.
1468+
1469+
SmallVector<ImportedModule, 4> importedModules;
1470+
SF->getImportedModules(
1471+
importedModules,
1472+
ModuleDecl::ImportFilter(
1473+
{ModuleDecl::ImportFilterKind::Exported,
1474+
ModuleDecl::ImportFilterKind::Default,
1475+
ModuleDecl::ImportFilterKind::SPIAccessControl,
1476+
ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay}));
1477+
auto nlOptions = NL_QualifiedDefault | NL_IncludeUsableFromInline;
1478+
if (auto val = dyn_cast<ValueDecl>(decl)) {
1479+
for (auto &importedModule : importedModules) {
1480+
SmallVector<ValueDecl *, 4> candidateDecls;
1481+
namelookup::lookupInModule(
1482+
importedModule.importedModule, val->getName(), candidateDecls,
1483+
NLKind::UnqualifiedLookup, namelookup::ResolutionKind::Overloadable,
1484+
importedModule.importedModule, nlOptions);
1485+
for (auto *candidateDecl : candidateDecls) {
1486+
if (candidateDecl->getFormalAccess() >= AccessLevel::Public) {
1487+
return DisallowedOriginKind::None;
1488+
}
1489+
}
1490+
}
1491+
}
14621492
// Implementation-only imported, cannot be reexported.
14631493
return DisallowedOriginKind::ImplementationOnly;
14641494
} else if (decl->isSPI() && !where.isSPI()) {
14651495
// SPI can only be exported in SPI.
1466-
return where.getDeclContext()->getParentModule() == M ?
1467-
DisallowedOriginKind::SPILocal :
1468-
DisallowedOriginKind::SPIImported;
1496+
return where.getDeclContext()->getParentModule() == M
1497+
? DisallowedOriginKind::SPILocal
1498+
: DisallowedOriginKind::SPIImported;
14691499
}
14701500

14711501
return DisallowedOriginKind::None;

0 commit comments

Comments
 (0)