From 26c420723b27273c9c7e4c06b98f7af57032a877 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Thu, 23 Jan 2025 14:11:16 -0800 Subject: [PATCH] [ModuleInterface] Determine package-only resolution need based on input mode Instead of requested action. In implicit builds, implicit interface build sub-invocations inherit their parent invocation's requested action, which the code was failing to detect that we were building an interface, not source, and erroneously resulted in enabling in-package module dependency resolution. Resolves rdar://143505814 --- lib/Frontend/CompilerInvocation.cpp | 5 +-- ...es-on-non-package-interface-implicit.swift | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/ModuleInterface/no-package-dependencies-on-non-package-interface-implicit.swift diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index a7112d069300a..7cbc2df7ea748 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2297,9 +2297,10 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, Opts.ScannerModuleValidation |= Args.hasFlag(OPT_scanner_module_validation, OPT_no_scanner_module_validation, CASOpts.EnableCaching); + bool buildingFromInterface = - FrontendOptions::doesActionBuildModuleFromInterface( - FrontendOpts.RequestedAction); + FrontendOpts.InputMode == + FrontendOptions::ParseInputMode::SwiftModuleInterface; auto firstInputPath = FrontendOpts.InputsAndOutputs.hasInputs() ? FrontendOpts.InputsAndOutputs.getFilenameOfFirstInput() diff --git a/test/ModuleInterface/no-package-dependencies-on-non-package-interface-implicit.swift b/test/ModuleInterface/no-package-dependencies-on-non-package-interface-implicit.swift new file mode 100644 index 0000000000000..85724913b7554 --- /dev/null +++ b/test/ModuleInterface/no-package-dependencies-on-non-package-interface-implicit.swift @@ -0,0 +1,35 @@ +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/module-cache) +// RUN: %empty-directory(%t/Swift) +// RUN: %empty-directory(%t/OtherSwift) +// RUN: split-file %s %t + +// Build in-package ModuleC +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/OtherSwift/ModuleC.swiftmodule -module-name ModuleC -package-name TestPak %t/C.swift + +// Build in-package ModuleB +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Swift/ModuleB.swiftmodule -enable-library-evolution -emit-module-interface-path %t/Swift/ModuleB.swiftinterface -module-name ModuleB -package-name TestPak %t/B.swift -I%t/OtherSwift + +// Build in-package ModuleA +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Swift/ModuleA.swiftmodule -enable-library-evolution -emit-module-interface-path %t/Swift/ModuleA.swiftinterface -module-name ModuleA -package-name TestPak %t/A.swift -I%t/Swift -I%t/OtherSwift + +// Remove binary module for A to make sure an implicit interface compile gets triggered +// RUN: rm %t/Swift/ModuleA.swiftmodule +// Remove in-package-only dependency of B to ensure that if the compiler looks for it, compilation will fail +// RUN: rm %t/OtherSwift/ModuleC.swiftmodule + +// Build out-of-package client source +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Swift/Client.swiftmodule -module-name Client %t/Client.swift -I%t/Swift + +//--- C.swift +public func c() {} + +//--- B.swift +package import ModuleC + +//--- A.swift +@_exported public import ModuleB + +//--- Client.swift +import ModuleA +