Skip to content

Commit ae9bc59

Browse files
authored
Merge pull request #60659 from xymus/print-missing-imports
[ModuleInterface] Print missing imports in swiftinterface
2 parents 982fb87 + 66a994b commit ae9bc59

12 files changed

+111
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5855,6 +5855,10 @@ ERROR(inlinable_typealias_desugars_to_type_from_hidden_module,
58555855
"%4 was not imported by this file}5",
58565856
(DeclName, StringRef, StringRef, unsigned, Identifier, unsigned))
58575857

5858+
NOTE(missing_import_inserted,
5859+
none, "The missing import of module %0 will be added implicitly",
5860+
(Identifier))
5861+
58585862
ERROR(availability_macro_in_inlinable, none,
58595863
"availability macro cannot be used in " FRAGILE_FUNC_KIND "0",
58605864
(unsigned))

include/swift/AST/FileUnit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
271271
getImportedModules(SmallVectorImpl<ImportedModule> &imports,
272272
ModuleDecl::ImportFilter filter) const {}
273273

274+
/// Lists modules that are not imported from this file and used in API.
275+
virtual void
276+
getMissingImportedModules(SmallVectorImpl<ImportedModule> &imports) const {}
277+
274278
/// \see ModuleDecl::getImportedModulesForLookup
275279
virtual void getImportedModulesForLookup(
276280
SmallVectorImpl<ImportedModule> &imports) const {

include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,10 @@ class ModuleDecl
712712
void getImportedModules(SmallVectorImpl<ImportedModule> &imports,
713713
ImportFilter filter = ImportFilterKind::Exported) const;
714714

715+
/// Lists modules that are not imported from a file and used in API.
716+
void
717+
getMissingImportedModules(SmallVectorImpl<ImportedModule> &imports) const;
718+
715719
/// Looks up which modules are imported by this module, ignoring any that
716720
/// won't contain top-level decls.
717721
///

include/swift/AST/SourceFile.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,15 @@ class SourceFile final : public FileUnit {
399399

400400
SWIFT_DEBUG_DUMPER(dumpSeparatelyImportedOverlays());
401401

402+
llvm::SmallDenseSet<ImportedModule> MissingImportedModules;
403+
404+
void addMissingImportedModule(ImportedModule module) const {
405+
const_cast<SourceFile *>(this)->MissingImportedModules.insert(module);
406+
}
407+
408+
void getMissingImportedModules(
409+
SmallVectorImpl<ImportedModule> &imports) const override;
410+
402411
void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
403412
const SmallVectorImpl<ValueDecl *> &getCachedVisibleDecls() const;
404413

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ struct ModuleInterfaceOptions {
5353
/// when PrintSPIs is true.
5454
bool ExperimentalSPIImports = false;
5555

56+
/// Print imports that are missing from the source and used in API.
57+
bool PrintMissingImports = true;
58+
5659
/// Intentionally print invalid syntax into the file.
5760
bool DebugPrintInvalidSyntax = false;
5861

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,11 @@ def experimental_spi_imports :
900900
Flag<["-"], "experimental-spi-imports">,
901901
HelpText<"Enable experimental support for SPI imports">;
902902

903+
def disable_print_missing_imports_in_module_interface :
904+
Flag<["-"], "disable-print-missing-imports-in-module-interface">,
905+
HelpText<"Disable adding to the module interface imports used from API and "
906+
"missing from the sources">;
907+
903908
// [FIXME: Clang-type-plumbing] Make this a SIL-only option once we start
904909
// unconditionally emitting non-canonical Clang types in swiftinterfaces.
905910
def experimental_print_full_convention :

lib/AST/Module.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,11 @@ void ModuleDecl::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
15701570
FORWARD(getImportedModules, (modules, filter));
15711571
}
15721572

1573+
void ModuleDecl::getMissingImportedModules(
1574+
SmallVectorImpl<ImportedModule> &imports) const {
1575+
FORWARD(getMissingImportedModules, (imports));
1576+
}
1577+
15731578
void
15741579
SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
15751580
ModuleDecl::ImportFilter filter) const {
@@ -1604,6 +1609,12 @@ SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
16041609
}
16051610
}
16061611

1612+
void SourceFile::getMissingImportedModules(
1613+
SmallVectorImpl<ImportedModule> &modules) const {
1614+
for (auto module : MissingImportedModules)
1615+
modules.push_back(module);
1616+
}
1617+
16071618
void SourceFile::dumpSeparatelyImportedOverlays() const {
16081619
for (auto &pair : separatelyImportedOverlays) {
16091620
auto &underlying = std::get<0>(pair);
@@ -2535,6 +2546,21 @@ RestrictedImportKind SourceFile::getRestrictedImportKind(const ModuleDecl *modul
25352546
if (imports.isImportedBy(module, getParentModule()))
25362547
return RestrictedImportKind::None;
25372548

2549+
if (importKind == RestrictedImportKind::Implicit &&
2550+
(module->getLibraryLevel() == LibraryLevel::API ||
2551+
getParentModule()->getLibraryLevel() != LibraryLevel::API)) {
2552+
// Hack to fix swiftinterfaces in case of missing imports.
2553+
// We can get rid of this logic when we don't leak the use of non-locally
2554+
// imported things in API.
2555+
ImportPath::Element pathElement = {module->getName(), SourceLoc()};
2556+
auto pathArray = getASTContext().AllocateCopy(
2557+
llvm::makeArrayRef(pathElement));
2558+
auto missingImport = ImportedModule(
2559+
ImportPath::Access(pathArray),
2560+
const_cast<ModuleDecl *>(module));
2561+
addMissingImportedModule(missingImport);
2562+
}
2563+
25382564
return importKind;
25392565
}
25402566

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
373373
Args.hasArg(OPT_experimental_spi_imports);
374374
Opts.DebugPrintInvalidSyntax |=
375375
Args.hasArg(OPT_debug_emit_invalid_swiftinterface_syntax);
376+
Opts.PrintMissingImports =
377+
!Args.hasArg(OPT_disable_print_missing_imports_in_module_interface);
376378

377379
if (const Arg *A = Args.getLastArg(OPT_library_level)) {
378380
StringRef contents = A->getValue();

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ static void printImports(raw_ostream &out,
219219

220220
SmallVector<ImportedModule, 8> allImports;
221221
M->getImportedModules(allImports, allImportFilter);
222+
223+
if (Opts.PrintMissingImports)
224+
M->getMissingImportedModules(allImports);
225+
222226
ImportedModule::removeDuplicates(allImports);
223227
diagnoseScopedImports(M->getASTContext().Diags, allImports);
224228

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc,
144144
}
145145
D->diagnose(diag::kind_declared_here, DescriptiveDeclKind::Type);
146146

147+
if (originKind == DisallowedOriginKind::ImplicitlyImported &&
148+
!ctx.LangOpts.isSwiftVersionAtLeast(6))
149+
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
150+
definingModule->getName());
151+
147152
return true;
148153
}
149154

@@ -190,7 +195,13 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
190195
D->getDescriptiveKind(), D->getName(),
191196
fragileKind.getSelector(), definingModule->getName(),
192197
static_cast<unsigned>(originKind));
198+
199+
if (originKind == DisallowedOriginKind::ImplicitlyImported &&
200+
downgradeToWarning == DowngradeToWarning::Yes)
201+
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
202+
definingModule->getName());
193203
}
204+
194205
return true;
195206
}
196207

@@ -245,5 +256,10 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
245256
!ctx.LangOpts.EnableConformanceAvailabilityErrors) ||
246257
originKind == DisallowedOriginKind::ImplicitlyImported,
247258
6);
259+
260+
if (originKind == DisallowedOriginKind::ImplicitlyImported &&
261+
!ctx.LangOpts.isSwiftVersionAtLeast(6))
262+
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
263+
M->getName());
248264
return true;
249265
}

0 commit comments

Comments
 (0)