Skip to content

Commit d900706

Browse files
authored
Merge pull request #64600 from apple/es-warn
Warn if a package binary module is loaded from SDK
2 parents b73143a + f87ba95 commit d900706

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 should be built locally from source only: %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: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1960,9 +1960,25 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
19601960
// diagnostics.
19611961
(void)ID->getDecls();
19621962

1963+
auto target = ID->getModule();
1964+
if (!getASTContext().LangOpts.PackageName.empty() &&
1965+
getASTContext().LangOpts.PackageName == target->getPackageName().str() &&
1966+
!target->isNonSwiftModule() && // target is a Swift module
1967+
target->isNonUserModule()) { // target module is in distributed SDK
1968+
// If reached here, a binary module (.swiftmodule) instead of interface of the
1969+
// target was loaded for the main module, where both belong to the same package;
1970+
// this is an expected behavior, but it should have been loaded from the local
1971+
// build directory, not from distributed SDK. In such case, we show a warning.
1972+
auto &diags = ID->getASTContext().Diags;
1973+
diags.diagnose(ID,
1974+
diag::in_package_module_not_compiled_locally,
1975+
target->getBaseIdentifier(),
1976+
target->getPackageName(),
1977+
target->getModuleFilename());
1978+
}
1979+
19631980
// Report the public import of a private module.
19641981
if (ID->getASTContext().LangOpts.LibraryLevel == LibraryLevel::API) {
1965-
auto target = ID->getModule();
19661982
auto importer = ID->getModuleContext();
19671983
if (target &&
19681984
!ID->getAttrs().hasAttribute<ImplementationOnlyAttr>() &&
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 -verify -verify-ignore-unknown %t/Client1.swift -package-name libPkg -sdk %t/SDK -I %t -I %t/SDK/Frameworks/LibInSDK.framework/Modules
18+
19+
// RUN: %target-swift-frontend -module-name LibLocal -emit-module -emit-module-path %t/LibLocal.swiftmodule -parse-as-library %t/Lib.swift -package-name libPkg
20+
// RUN: test -f %t/LibLocal.swiftmodule
21+
22+
// RUN: %target-swift-frontend -typecheck -verify %t/Client2.swift -package-name libPkg -I %t
23+
24+
//--- Lib.swift
25+
package func log(level: Int) {}
26+
27+
//--- Client1.swift
28+
import LibInSDK // expected-warning {{module 'LibInSDK' is in package 'libPkg' but was loaded from SDK; modules of the same package should be built locally from source only}}
29+
30+
func someFunc() {
31+
log(level: 1)
32+
}
33+
34+
//--- Client2.swift
35+
import LibLocal
36+
37+
func someFunc() {
38+
log(level: 1)
39+
}
40+
41+

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)