Skip to content

Commit 3bcd726

Browse files
committed
Warn if a package binary module is loaded from SDK
Resolves rdar://107074380
1 parent 21109a3 commit 3bcd726

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,11 +1007,16 @@ ERROR(module_not_testable,Fatal,
10071007
ERROR(module_not_compiled_for_private_import,none,
10081008
"module %0 was not compiled for private import", (Identifier))
10091009

1010-
ERROR(in_package_module_not_compiled_from_source,Fatal,
1011-
"module %0 is in package '%1' but was built from interface '%2'; "
1012-
"modules of the same package can only be loaded if built from source",
1010+
ERROR(in_package_module_not_compiled_from_source,none,
1011+
"module %0 is in package '%1' but was built from interface; "
1012+
"modules of the same package can only be loaded if built from source: %2",
10131013
(Identifier, StringRef, StringRef))
10141014

1015+
WARNING(in_package_module_not_compiled_locally,none,
1016+
"module %0 is in package %1 but was loaded from SDK; "
1017+
"modules of the same package are expected to be loaded from local build directory: %2",
1018+
(Identifier, Identifier, StringRef))
1019+
10151020
ERROR(import_restriction_conflict,none,
10161021
"module %0 cannot be both "
10171022
"%select{implementation-only|SPI only|exported}1 and "

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1960,9 +1960,23 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
19601960
// diagnostics.
19611961
(void)ID->getDecls();
19621962

1963+
auto target = ID->getModule();
1964+
if (target->isNonUserModule() && // target module is in distributed SDK
1965+
getASTContext().LangOpts.PackageName == target->getPackageName().str()) {
1966+
// If reached here, a binary module (.swiftmodule) instead of interface of the
1967+
// target was loaded for the main module, where both belong to the same package;
1968+
// this is an expected behavior, but it should have been loaded from the local
1969+
// build directory, not from distributed SDK. In such case, we show a warning.
1970+
auto &diags = ID->getASTContext().Diags;
1971+
diags.diagnose(target->getLoc(),
1972+
diag::in_package_module_not_compiled_locally,
1973+
target->getBaseIdentifier(),
1974+
target->getPackageName(),
1975+
target->getModuleFilename());
1976+
}
1977+
19631978
// Report the public import of a private module.
19641979
if (ID->getASTContext().LangOpts.LibraryLevel == LibraryLevel::API) {
1965-
auto target = ID->getModule();
19661980
auto importer = ID->getModuleContext();
19671981
if (target &&
19681982
!ID->getAttrs().hasAttribute<ImplementationOnlyAttr>() &&
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// --- Prepare SDK (.swiftmodule).
5+
// RUN: %empty-directory(%t/SDK)
6+
// RUN: mkdir -p %t/SDK/Frameworks/LibInSDK.framework/Modules/LibInSDK.swiftmodule
7+
// RUN: %target-swift-frontend \
8+
// RUN: -emit-module \
9+
// RUN: -module-name LibInSDK \
10+
// RUN: -package-name libPkg \
11+
// RUN: -o %t/SDK/Frameworks/LibInSDK.framework/Modules/LibInSDK.swiftmodule/%module-target-triple.swiftmodule \
12+
// RUN: -swift-version 5 \
13+
// RUN: %t/Lib.swift
14+
15+
// RUN: test -f %t/SDK/Frameworks/LibInSDK.framework/Modules/LibInSDK.swiftmodule/%module-target-triple.swiftmodule
16+
17+
// RUN: %target-swift-frontend -typecheck %t/Client1.swift -package-name libPkg -sdk %t/SDK -I %t -I %t/SDK/Frameworks/LibInSDK.framework/Modules 2> %t/result.output
18+
// RUN: %FileCheck %s < %t/result.output
19+
// CHECK: warning: module 'LibInSDK' is in package 'libPkg' but was loaded from SDK; modules of the same package are expected to be loaded from local build directory: {{.*}}/SDK/Frameworks/LibInSDK.framework/Modules/LibInSDK.swiftmodule/{{.*}}.swiftmodule
20+
21+
// RUN: %target-swift-frontend -module-name LibLocal -emit-module -emit-module-path %t/LibLocal.swiftmodule -parse-as-library %t/Lib.swift -package-name libPkg
22+
// RUN: test -f %t/LibLocal.swiftmodule
23+
24+
// RUN: %target-swift-frontend -typecheck %t/Client2.swift -package-name libPkg -I %t
25+
26+
//--- Lib.swift
27+
package func log(level: Int) {}
28+
29+
//--- Client1.swift
30+
import LibInSDK
31+
32+
func someFunc() {
33+
log(level: 1)
34+
}
35+
36+
//--- Client2.swift
37+
import LibLocal
38+
39+
func someFunc() {
40+
log(level: 1)
41+
}
42+
43+

test/Serialization/load_package_module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
// RUN: not %target-swift-frontend -module-name ClientInSamePkg %t/ClientLoadInterfaceModule.swift -emit-module -emit-module-path %t/ClientInSamePkg.swiftmodule -package-name mypkg -I %t 2> %t/resultA.output
1111
// RUN: %FileCheck %s -check-prefix CHECK-A < %t/resultA.output
12-
// CHECK-A: error: module 'LibFromInterface' is in package 'mypkg' but was built from interface '{{.*}}LibFromInterface.swiftinterface'; modules of the same package can only be loaded if built from source
12+
// CHECK-A: error: module 'LibFromInterface' is in package 'mypkg' but was built from interface; modules of the same package can only be loaded if built from source: {{.*}}LibFromInterface.swiftinterface
1313

1414
// RUN: not %target-swift-frontend -module-name ClientInDiffPkg %t/ClientLoadInterfaceModule.swift -emit-module -emit-module-path %t/ClientInDiffPkg.swiftmodule -package-name otherPkg -I %t 2> %t/resultB.output
1515
// RUN: %FileCheck %s -check-prefix CHECK-B < %t/resultB.output

0 commit comments

Comments
 (0)