Skip to content

Commit d2ea34c

Browse files
committed
[Explicit Module Builds] Switch versioned 'canImport' to return 'true' when encountering unversioned candidate
Specifically, when the scanner found a candidate which does not carry a user-specified version, it will pass '-module-can-import Foo' to compilation. During compilation, if the check is versioned but the candidate is unversioned, evaluate the check to 'true' to restore the behavior we had with implicitly-built modules. Resolves rdar://148134993
1 parent 86bfe3a commit d2ea34c

File tree

6 files changed

+91
-25
lines changed

6 files changed

+91
-25
lines changed

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ class ASTContext final {
11841184
/// module is loaded in full.
11851185
bool canImportModuleImpl(ImportPath::Module ModulePath, SourceLoc loc,
11861186
llvm::VersionTuple version, bool underlyingVersion,
1187-
bool updateFailingList,
1187+
bool isSourceCanImport,
11881188
llvm::VersionTuple &foundVersion) const;
11891189

11901190
/// Add successful canImport modules.

lib/AST/ASTContext.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,7 +2674,7 @@ void ASTContext::addSucceededCanImportModule(
26742674
bool ASTContext::canImportModuleImpl(ImportPath::Module ModuleName,
26752675
SourceLoc loc, llvm::VersionTuple version,
26762676
bool underlyingVersion,
2677-
bool updateFailingList,
2677+
bool isSourceCanImport,
26782678
llvm::VersionTuple &foundVersion) const {
26792679
SmallString<64> FullModuleName;
26802680
ModuleName.getString(FullModuleName);
@@ -2692,21 +2692,14 @@ bool ASTContext::canImportModuleImpl(ImportPath::Module ModuleName,
26922692
if (version.empty())
26932693
return true;
26942694

2695-
if (underlyingVersion) {
2696-
if (!Found->second.UnderlyingVersion.empty())
2697-
return version <= Found->second.UnderlyingVersion;
2698-
} else {
2699-
if (!Found->second.Version.empty())
2700-
return version <= Found->second.Version;
2701-
}
2702-
2703-
// If the canImport information is coming from the command-line, then no
2704-
// need to continue the search, return false. For checking modules that are
2705-
// not passed from command-line, allow fallback to the module loading since
2706-
// this is not in a canImport request context that has already been resolved
2707-
// by scanner.
2708-
if (!SearchPathOpts.CanImportModuleInfo.empty())
2709-
return false;
2695+
if (underlyingVersion)
2696+
return Found->second.UnderlyingVersion.empty()
2697+
? true
2698+
: version <= Found->second.UnderlyingVersion;
2699+
else
2700+
return Found->second.Version.empty()
2701+
? true
2702+
: version <= Found->second.Version;
27102703
}
27112704

27122705
if (version.empty()) {
@@ -2720,7 +2713,7 @@ bool ASTContext::canImportModuleImpl(ImportPath::Module ModuleName,
27202713
return true;
27212714
}
27222715

2723-
if (updateFailingList)
2716+
if (isSourceCanImport)
27242717
FailedModuleImportNames.insert(ModuleNameStr);
27252718

27262719
return false;

test/Parse/ConditionalCompilation/can_import_options.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ func canImportVersioned() {
7373
#endif
7474

7575
#if canImport(Bar, _underlyingVersion: 113.33)
76-
// Bar is a Swift module with no underlying clang module.
77-
let underlyingMinorSmaller = 1
76+
// Bar is an unversioned Swift module with no underlying clang module.
77+
let underlyingMinorSmaller = 1 // expected-warning {{initialization of immutable value 'underlyingMinorSmaller' was never used; consider replacing with assignment to '_' or removing it}}
7878
#endif
7979

8080
#if canImport(Bar)

test/Parse/ConditionalCompilation/can_import_version.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ func canImportVersioned() {
6868
#endif
6969

7070
#if canImport(Foo, _underlyingVersion: 113.33)
71-
// Foo is a Swift module with no underlying clang module.
72-
let underlyingMinorSmaller = 1
71+
// Foo is an unversioned Swift module with no underlying clang module.
72+
let underlyingMinorSmaller = 1 // expected-warning {{initialization of immutable value 'underlyingMinorSmaller' was never used; consider replacing with assignment to '_' or removing it}}
7373
#endif
7474

7575
#if canImport(Foo)
@@ -136,7 +136,7 @@ func canImportVersionedString() {
136136
#endif
137137

138138
#if canImport(Foo, _underlyingVersion: "113.33")
139-
// Foo is a Swift module with no underlying clang module.
140-
let underlyingMinorSmaller = 1
139+
// Foo is an unversioned Swift module with no underlying clang module.
140+
let underlyingMinorSmaller = 1 // expected-warning {{initialization of immutable value 'underlyingMinorSmaller' was never used; consider replacing with assignment to '_' or removing it}}
141141
#endif
142142
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// REQUIRES: executable_test
2+
// RUN: %empty-directory(%t)
3+
// RUN: %empty-directory(%t/inputs)
4+
// RUN: %empty-directory(%t/module-cache)
5+
// RUN: split-file %s %t
6+
7+
// - Fixup the input module file map
8+
// RUN: sed -e "s|INPUTSDIR|%/t/inputs|g" %t/map.json.template > %t/map.json.template1
9+
// RUN: sed -e "s|STDLIBMOD|%/stdlib_module|g" %t/map.json.template1 > %t/map.json.template2
10+
// RUN: sed -e "s|ONONEMOD|%/ononesupport_module|g" %t/map.json.template2 > %t/map.json.template3
11+
// RUN: sed -e "s|MYLIBMOD|%/t/inputs/MyLib.swiftmodule|g" %t/map.json.template3 > %t/map.json.template4
12+
// RUN: sed -e "s|SWIFTLIBDIR|%swift-lib-dir|g" %t/map.json.template4 > %t/map.json
13+
14+
// - Set up explicit dependencies for MyExe
15+
// RUN: %target-swift-emit-pcm -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/SwiftShims.pcm
16+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/inputs/MyLib.swiftmodule %t/MyLib.swift -module-name MyLib -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-implicit-swift-modules -explicit-swift-module-map-file %t/map.json
17+
18+
// - Build MyExe
19+
// RUN: %target-swift-frontend -c %t/MyExe.swift -I %t/inputs -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-implicit-swift-modules -explicit-swift-module-map-file %t/map.json -module-can-import MyLib -verify
20+
21+
//--- map.json.template
22+
[
23+
{
24+
"moduleName": "Swift",
25+
"modulePath": "STDLIBMOD",
26+
"isFramework": false
27+
},
28+
{
29+
"moduleName": "SwiftOnoneSupport",
30+
"modulePath": "ONONEMOD",
31+
"isFramework": false
32+
},
33+
{
34+
"moduleName": "SwiftShims",
35+
"isFramework": false,
36+
"clangModuleMapPath": "SWIFTLIBDIR/swift/shims/module.modulemap",
37+
"clangModulePath": "INPUTSDIR/SwiftShims.pcm"
38+
},
39+
{
40+
"moduleName": "MyLib",
41+
"modulePath": "MYLIBMOD",
42+
"isFramework": false
43+
}
44+
]
45+
46+
//--- MyLib.swift
47+
public func Foo() {
48+
print("foo")
49+
}
50+
51+
//--- MyExe.swift
52+
#if canImport(MyLib, _version: 42)
53+
#warning("versioned canImport() of unversioned module is working")
54+
// expected-warning@-1{{versioned canImport() of unversioned module is working}}
55+
#else
56+
#warning("versioned canImport() of unversioned module is broken")
57+
#endif
58+

test/ScanDependencies/module_deps_can_import.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/unversionedInputs)
23
// RUN: split-file %s %t
3-
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %t/main.swift -module-name Test -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %t/include -swift-version 4
4+
5+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/unversionedUnputs/Foo.swiftmodule %t/Foo.swift -module-name Foo -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import
6+
7+
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %t/main.swift -module-name Test -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %t/include -I %t/unversionedUnputs
48

59
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps.json Test directDependencies | %FileCheck %s
610

@@ -17,13 +21,24 @@
1721
// CMD-NEXT: "ClangTest.Sub"
1822
// CMD-NEXT: "-module-can-import"
1923
// CMD-NEXT: "F"
24+
// CMD-NEXT: "-module-can-import"
25+
// CMD-NEXT: "Foo"
2026
// CMD-NEXT: "-module-can-import-version"
2127
// CMD-NEXT: "Version"
2228
// CMD-NEXT: "100.1"
2329
// CMD-NEXT: "0"
2430

31+
//--- Foo.swift
32+
public func Foo() {
33+
print("foo")
34+
}
35+
2536
//--- main.swift
2637

38+
#if canImport(Foo, _version: 44)
39+
import Foo
40+
#endif
41+
2742
#if canImport(Missing)
2843
import G
2944
#endif

0 commit comments

Comments
 (0)