Skip to content

Commit 14c639b

Browse files
committed
[Index] Index only system modules in the SDK
Indexing a module from the swiftinterface puts the swiftinterface version in the cache. Subsequent builds don't see the adjacent swiftmodule file. This can break test clients that need the adjacent swiftmodule information. To avoid this scenario, ensure that we only index system modules in the SDK, not local versions. rdar://102207620
1 parent 5b9aef9 commit 14c639b

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,10 @@ class ModuleDecl
859859
/// applicable.
860860
StringRef getModuleLoadedFilename() const;
861861

862+
/// \returns true if this module is defined under the SDK path.
863+
/// If no SDK path is defined, this always returns false.
864+
bool isSDKModule() const;
865+
862866
/// \returns true if this module is the "swift" standard library module.
863867
bool isStdlibModule() const;
864868

lib/AST/Module.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,6 +1996,18 @@ StringRef ModuleDecl::getModuleLoadedFilename() const {
19961996
return StringRef();
19971997
}
19981998

1999+
bool ModuleDecl::isSDKModule() const {
2000+
if (getASTContext().SearchPathOpts.getSDKPath().empty())
2001+
return false;
2002+
2003+
auto sdkPath = SmallString<8>(),
2004+
modulePath = SmallString<8>();
2005+
llvm::sys::path::native(getASTContext().SearchPathOpts.getSDKPath(), sdkPath);
2006+
llvm::sys::path::native(getModuleSourceFilename(), modulePath);
2007+
2008+
return modulePath.startswith(sdkPath);
2009+
}
2010+
19992011
bool ModuleDecl::isStdlibModule() const {
20002012
return !getParent() && getName() == getASTContext().StdlibModuleName;
20012013
}

lib/Index/IndexRecord.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,12 @@ static void addModuleDependencies(ArrayRef<ImportedModule> imports,
447447
}
448448
} else {
449449
// Serialized AST file.
450-
// Only index system modules (essentially stdlib and overlays).
450+
// Only index system modules from the SDK, and the stdlib.
451451
// We don't officially support binary swift modules, so normally
452452
// the index data for user modules would get generated while
453453
// building them.
454454
if (mod->isSystemModule() && indexSystemModules &&
455+
(mod->isSDKModule() || mod->isStdlibModule()) &&
455456
(!skipStdlib || !mod->isStdlibModule())) {
456457
emitDataForSwiftSerializedModule(mod, indexStorePath,
457458
indexClangModules,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/cache)
3+
// RUN: %empty-directory(%t/idx)
4+
// RUN: %empty-directory(%t/sdk)
5+
// RUN: split-file %s %t
6+
7+
/// Create a Swift module to import.
8+
// RUN: cp %t/module.modulemap %t/sdk/
9+
// RUN: %target-swift-frontend -emit-module \
10+
// RUN: -enable-library-evolution -swift-version 5 \
11+
// RUN: -emit-module-path %t/sdk/LocalSystemModule.swiftmodule \
12+
// RUN: -emit-module-interface-path %t/sdk/LocalSystemModule.swiftinterface \
13+
// RUN: %t/LocalSystemModule.swift -I %t/sdk \
14+
// RUN: -enable-testing
15+
16+
/// Build a test client once with indexing, not setting an SDK.
17+
// RUN: %target-swift-frontend -typecheck %t/TestClient.swift \
18+
// RUN: -I %t/sdk -module-cache-path %t/cache \
19+
// RUN: -index-system-modules \
20+
// RUN: -index-store-path %t/idx \
21+
// RUN: -index-ignore-stdlib \
22+
// RUN: -sdk %t/someothersdk -Rmodule-loading 2>&1 \
23+
// RUN: | %FileCheck -check-prefix=CHECK-SWIFTMODULE %s
24+
// CHECK-SWIFTMODULE: source: '{{.*}}LocalSystemModule.swiftmodule'
25+
26+
/// Build the test client again not setting an SDK, this one should still use
27+
/// the adjacent module that is built for testing.
28+
// RUN: %target-swift-frontend -typecheck %t/TestClient.swift \
29+
// RUN: -I %t/sdk -module-cache-path %t/cache \
30+
// RUN: -sdk %t/someothersdk -Rmodule-loading 2>&1 \
31+
// RUN: | %FileCheck -check-prefix=CHECK-SWIFTMODULE %s
32+
33+
/// @testable import of a module in the SDK works once but not after it's cached.
34+
// RUN: %empty-directory(%t/idx)
35+
// RUN: %target-swift-frontend -typecheck %t/TestClient.swift \
36+
// RUN: -I %t/sdk -module-cache-path %t/cache \
37+
// RUN: -index-system-modules \
38+
// RUN: -index-store-path %t/idx \
39+
// RUN: -index-ignore-stdlib \
40+
// RUN: -sdk %t/sdk -Rmodule-loading 2>&1 \
41+
// RUN: | %FileCheck -check-prefix=CHECK-SWIFTMODULE %s
42+
43+
/// Failing case when building against the cached swiftmodule.
44+
// RUN: %target-swift-frontend -typecheck %t/TestClient.swift \
45+
// RUN: -I %t/sdk -module-cache-path %t/cache \
46+
// RUN: -sdk %t/sdk -Rmodule-loading \
47+
// RUN: -verify -verify-ignore-unknown -show-diagnostics-after-fatal 2>&1
48+
49+
//--- module.modulemap
50+
51+
module LocalSystemModule [system] { }
52+
53+
//--- LocalSystemModule.swift
54+
55+
@_exported import LocalSystemModule
56+
57+
//--- TestClient.swift
58+
59+
@testable import LocalSystemModule // expected-error {{module 'LocalSystemModule' was not compiled for testing}}
60+
// expected-remark @-1 {{LocalSystemModule.swiftinterface}}

0 commit comments

Comments
 (0)