diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 376af17ade6..3417f901231 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -264,24 +264,24 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID, moduleFramework += ".framework"; isFramework = true; - auto tryFrameworkImport = [&](StringRef frameworkPath) -> bool { + auto tryFrameworkImport = [&](StringRef frameworkPath) -> Optional { currPath = frameworkPath; llvm::sys::path::append(currPath, moduleFramework.str()); // Check if the framework directory exists if (!fs.exists(currPath)) { - return false; + return None; } // Frameworks always use architecture-specific files within a .swiftmodule // directory. llvm::sys::path::append(currPath, "Modules", fileNames.module.str()); - return findTargetSpecificModuleFiles().getValueOr(false); + return findTargetSpecificModuleFiles(); }; for (const auto &framepath : Ctx.SearchPathOpts.FrameworkSearchPaths) { - if (tryFrameworkImport(framepath.Path)) - return true; + if (auto outcome = tryFrameworkImport(framepath.Path)) + return outcome.getValue(); } if (Ctx.LangOpts.Target.isOSDarwin()) { @@ -290,13 +290,13 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID, SmallString<256> scratch; scratch = Ctx.SearchPathOpts.SDKPath; llvm::sys::path::append(scratch, "System", "Library", "Frameworks"); - if (tryFrameworkImport(scratch)) - return true; + if (auto outcome = tryFrameworkImport(scratch)) + return outcome.getValue(); scratch = Ctx.SearchPathOpts.SDKPath; llvm::sys::path::append(scratch, "Library", "Frameworks"); - if (tryFrameworkImport(scratch)) - return true; + if (auto outcome = tryFrameworkImport(scratch)) + return outcome.getValue(); } } diff --git a/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk-framework.swift b/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk-framework.swift new file mode 100644 index 00000000000..a9441ce33a9 --- /dev/null +++ b/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk-framework.swift @@ -0,0 +1,31 @@ +// RUN: %empty-directory(%t/BuildDir/Lib.framework/Modules/Lib.swiftmodule) +// RUN: %empty-directory(%t/SecondBuildDir/Lib.framework/Modules/Lib.swiftmodule) +// RUN: %empty-directory(%t/ModuleCache) + +// RUN: echo 'public func showsUpInBothPlaces() {}' > %t/Lib.swift + +// 1. Create a .swiftinterface file containing just one API, and put it inside a second build dir (without a .swiftmodule) +// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib + +// 2. Add a new API to the module, and compile just the serialized version in the build dir. +// RUN: echo 'public func onlyInTheCompiledModule() {}' >> %t/Lib.swift +// RUN: %target-swift-frontend -emit-module %t/Lib.swift -o %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftmodule -emit-parseable-module-interface-path %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib + +// 3. Make sure when we compile this test file, we can access both APIs since we'll +// load the compiled .swiftmodule instead of the .swiftinterface in the SDK. +// RUN: %target-swift-frontend -typecheck %s -F %t/BuildDir -F %t/SecondBuildDir -module-cache-path %t/ModuleCache + +// 4. Make sure we didn't compile any .swiftinterfaces into the module cache. +// RUN: ls %t/ModuleCache | not grep 'swiftmodule' + +// 5. This should also work if the swiftinterface isn't present in the first build dir. +// RUN: rm %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface +// RUN: %target-swift-frontend -typecheck %s -F %t/BuildDir -F %t/SecondBuildDir -module-cache-path %t/ModuleCache + +// 6. Make sure we /still/ didn't compile any .swiftinterfaces into the module cache. +// RUN: ls %t/ModuleCache | not grep 'swiftmodule' + +import Lib + +showsUpInBothPlaces() +onlyInTheCompiledModule() diff --git a/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk.swift b/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk.swift index daf0323403f..83adb3828eb 100644 --- a/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk.swift +++ b/test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk.swift @@ -5,7 +5,7 @@ // RUN: echo 'public func showsUpInBothPlaces() {}' > %t/Lib.swift // 1. Create a .swiftinterface file containing just one API, and put it inside a second build dir (without a .swiftmodule) -// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.swiftmodule/%target-cpu.swiftinterface +// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib // 2. Add a new API to the module, and compile just the serialized version in the build dir. // RUN: echo 'public func onlyInTheCompiledModule() {}' >> %t/Lib.swift @@ -18,7 +18,14 @@ // 4. Make sure we didn't compile any .swiftinterfaces into the module cache. // RUN: ls %t/ModuleCache | not grep 'swiftmodule' +// 5. This should also work if the swiftinterface isn't present in the first build dir. +// RUN: rm %t/BuildDir/Lib.swiftinterface +// RUN: %target-swift-frontend -typecheck %s -I %t/BuildDir -I %t/SecondBuildDir -module-cache-path %t/ModuleCache + +// 6. Make sure we /still/ didn't compile any .swiftinterfaces into the module cache. +// RUN: ls %t/ModuleCache | not grep 'swiftmodule' + import Lib showsUpInBothPlaces() -onlyInTheCompiledModule() \ No newline at end of file +onlyInTheCompiledModule()