Skip to content

Commit 29786c0

Browse files
committed
Warn on multiple '-swift-module-file' options
1 parent 89268e9 commit 29786c0

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ ERROR(error_stdlib_module_name,none,
213213
"module name \"%0\" is reserved for the standard library"
214214
"%select{|; use -module-name flag to specify an alternate name}1",
215215
(StringRef, bool))
216+
WARNING(warn_multiple_module_inputs_same_name,none,
217+
"multiple Swift module file inputs with identifier \"%0\": replacing '%1' with '%2'",
218+
(StringRef, StringRef, StringRef))
216219

217220
ERROR(error_bad_export_as_name,none,
218221
"export-as name \"%0\" is not a valid identifier",

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2282,7 +2282,15 @@ static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModule
22822282
Diags.diagnose(SourceLoc(), diag::error_bad_module_name, moduleName, false);
22832283
return true;
22842284
}
2285-
ExplicitSwiftModuleInputs.insert(std::make_pair(moduleName, modulePath));
2285+
2286+
auto priorEntryIt = ExplicitSwiftModuleInputs.find(moduleName);
2287+
if (priorEntryIt != ExplicitSwiftModuleInputs.end()) {
2288+
Diags.diagnose(SourceLoc(), diag::warn_multiple_module_inputs_same_name,
2289+
moduleName, priorEntryIt->getValue(), modulePath);
2290+
ExplicitSwiftModuleInputs[moduleName] = modulePath;
2291+
} else
2292+
ExplicitSwiftModuleInputs.insert(std::make_pair(moduleName, modulePath));
2293+
22862294
return false;
22872295
}
22882296

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/module-cache)
3+
// RUN: %empty-directory(%t/Inputs/Foo.swiftmodule)
4+
// RUN: split-file %s %t
5+
6+
// Step 1: build swift interface and swift module side by side
7+
// RUN: %target-swift-frontend -emit-module %t/Foo.swift -emit-module-path %t/Inputs/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo -user-module-version 22
8+
9+
// Step 2: scan dependency should give us the binary module we specify with 'swift-module-file'
10+
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
11+
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=CHECK-INPUT
12+
13+
// Step 3: ensure that versioned canImport still applies with direct -swift-module-file
14+
// RUN: %target-swift-frontend -scan-dependencies %t/test_too_new.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
15+
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=CHECK-MISSING
16+
17+
// CHECK-INPUT: "swiftPrebuiltExternal": "Foo"
18+
// CHECK-MISSING-NOT: "swiftPrebuiltExternal": "Foo"
19+
20+
//--- Foo.swift
21+
public func foo() {}
22+
23+
//--- test.swift
24+
#if canImport(Foo)
25+
import Foo
26+
#endif
27+
28+
//--- test_too_new.swift
29+
#if canImport(Foo, _version: 23)
30+
import Foo
31+
#endif

test/ScanDependencies/explicit-scanner-input.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,25 @@
99
// Step 2: scan dependency should give us the binary module we specify with 'swift-module-file'
1010
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
1111
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=CHECK-INPUT
12+
13+
// Step 3: ensure that if multiple inputs for the same module are specified then a warning is emitted and the latter is preferred
14+
// RUN: echo "Gibberish" > %t/Inputs/Foo.swiftmodule/NotAModule.swiftmodule
15+
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/NotAModule.swiftmodule -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name -diagnostic-style llvm 2>&1 | %FileCheck %s -check-prefix=CHECK-WARN-MULTIPLE
16+
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=CHECK-INPUT
17+
18+
// Step 4: verify that the usual invalid module candidate diagnostics apply
19+
// RUN: echo "Not Really a module" > %t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
20+
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name -diagnostic-style llvm 2>&1 | %FileCheck %s -check-prefix=CHECK-INVALID-MODULE-DIAG
21+
1222
// CHECK-INPUT: "swiftPrebuiltExternal": "Foo"
23+
// CHECK-WARN-MULTIPLE: warning: multiple Swift module file inputs with identifier "Foo": replacing '{{.*}}NotAModule.swiftmodule'
24+
25+
// CHECK-INVALID-MODULE-DIAG: warning: module file '{{.*}}Foo.swiftmodule{{/|\\}}{{.*}}.swiftmodule' is incompatible with this Swift compiler: malformed
26+
// CHECK-INVALID-MODULE-DIAG: error: Unable to find module dependency: 'Foo'
27+
// CHECK-INVALID-MODULE-DIAG: note: a dependency of main module 'deps'
1328

1429
//--- Foo.swift
1530
public func foo() {}
1631

1732
//--- test.swift
18-
#if canImport(Foo)
1933
import Foo
20-
#endif

0 commit comments

Comments
 (0)