@@ -1447,25 +1447,55 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
1447
1447
// /
1448
1448
// / Local variant to swift::getDisallowedOriginKind for downgrade to warnings.
1449
1449
DisallowedOriginKind
1450
- swift::getDisallowedOriginKind (const Decl *decl,
1451
- ExportContext where,
1450
+ swift::getDisallowedOriginKind (const Decl *decl, ExportContext where,
1452
1451
DowngradeToWarning &downgradeToWarning) {
1453
1452
downgradeToWarning = DowngradeToWarning::No;
1454
1453
ModuleDecl *M = decl->getModuleContext ();
1454
+
1455
1455
auto *SF = where.getDeclContext ()->getParentSourceFile ();
1456
1456
if (SF->isImportedImplementationOnly (M)) {
1457
+
1457
1458
// Temporarily downgrade implementation-only exportability in SPI to
1458
1459
// a warning.
1459
1460
if (where.isSPI ())
1460
1461
downgradeToWarning = DowngradeToWarning::Yes;
1461
1462
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
+ }
1462
1492
// Implementation-only imported, cannot be reexported.
1463
1493
return DisallowedOriginKind::ImplementationOnly;
1464
1494
} else if (decl->isSPI () && !where.isSPI ()) {
1465
1495
// 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;
1469
1499
}
1470
1500
1471
1501
return DisallowedOriginKind::None;
0 commit comments