@@ -240,12 +240,21 @@ struct ModuleRebuildInfo {
240240 InterfacePreferred,
241241 CompilerHostModule,
242242 Blocklisted,
243+ DistributedInterfaceByDefault,
244+ };
245+ // Keep aligned with diag::module_interface_ignored_reason.
246+ enum class ReasonModuleInterfaceIgnored {
247+ NotIgnored,
248+ LocalModule,
249+ Blocklisted,
250+ Debugger,
243251 };
244252 struct CandidateModule {
245253 std::string path;
246254 std::optional<serialization::Status> serializationStatus;
247255 ModuleKind kind;
248256 ReasonIgnored reasonIgnored;
257+ ReasonModuleInterfaceIgnored reasonModuleInterfaceIgnored;
249258 SmallVector<std::string, 10 > outOfDateDependencies;
250259 SmallVector<std::string, 10 > missingDependencies;
251260 };
@@ -259,6 +268,7 @@ struct ModuleRebuildInfo {
259268 std::nullopt ,
260269 ModuleKind::Normal,
261270 ReasonIgnored::NotIgnored,
271+ ReasonModuleInterfaceIgnored::NotIgnored,
262272 {},
263273 {}});
264274 return candidateModules.back ();
@@ -290,13 +300,21 @@ struct ModuleRebuildInfo {
290300 .missingDependencies .push_back (depPath.str ());
291301 }
292302
293- // / Sets the reason that the module at \c path was ignored. If this is
303+ // / Sets the reason that the module at \c modulePath was ignored. If this is
294304 // / anything besides \c NotIgnored a note will be added stating why the module
295305 // / was ignored.
296306 void addIgnoredModule (StringRef modulePath, ReasonIgnored reasonIgnored) {
297307 getOrInsertCandidateModule (modulePath).reasonIgnored = reasonIgnored;
298308 }
299309
310+ // / Record why no swiftinterfaces were preferred over the binary swiftmodule
311+ // / at \c modulePath.
312+ void addIgnoredModuleInterface (StringRef modulePath,
313+ ReasonModuleInterfaceIgnored reasonIgnored) {
314+ getOrInsertCandidateModule (modulePath).reasonModuleInterfaceIgnored =
315+ reasonIgnored;
316+ }
317+
300318 // / Determines if we saw the given module path and registered is as out of
301319 // / date.
302320 bool sawOutOfDateModule (StringRef modulePath) {
@@ -367,7 +385,7 @@ struct ModuleRebuildInfo {
367385 // We may have found multiple failing modules, that failed for different
368386 // reasons. Emit a note for each of them.
369387 for (auto &mod : candidateModules) {
370- // If a the compiled module was ignored, diagnose the reason.
388+ // If the compiled module was ignored, diagnose the reason.
371389 if (mod.reasonIgnored != ReasonIgnored::NotIgnored) {
372390 diags.diagnose (loc, diag::compiled_module_ignored_reason, mod.path ,
373391 (unsigned )mod.reasonIgnored );
@@ -399,6 +417,19 @@ struct ModuleRebuildInfo {
399417 }
400418 }
401419 }
420+
421+ // / Emits a diagnostic for the reason why binary swiftmodules were preferred
422+ // / over textual swiftinterfaces.
423+ void diagnoseIgnoredModuleInterfaces (ASTContext &ctx, SourceLoc loc) {
424+ for (auto &mod : candidateModules) {
425+ auto interfaceIgnore = mod.reasonModuleInterfaceIgnored ;
426+ if (interfaceIgnore == ReasonModuleInterfaceIgnored::NotIgnored)
427+ continue ;
428+
429+ ctx.Diags .diagnose (loc, diag::module_interface_ignored_reason,
430+ mod.path , (unsigned )interfaceIgnore);
431+ }
432+ }
402433};
403434
404435// / Constructs the full path of the dependency \p dep by prepending the SDK
@@ -761,6 +792,12 @@ class ModuleInterfaceLoaderImpl {
761792 return pathStartsWith (hostPath, path);
762793 }
763794
795+ bool isInSDK (StringRef path) {
796+ StringRef sdkPath = ctx.SearchPathOpts .getSDKPath ();
797+ if (sdkPath.empty ()) return false ;
798+ return pathStartsWith (sdkPath, path);
799+ }
800+
764801 bool isInSystemFrameworks (StringRef path, bool publicFramework) {
765802 StringRef sdkPath = ctx.SearchPathOpts .getSDKPath ();
766803 if (sdkPath.empty ()) return false ;
@@ -775,26 +812,64 @@ class ModuleInterfaceLoaderImpl {
775812
776813 std::pair<std::string, std::string> getCompiledModuleCandidates () {
777814 using ReasonIgnored = ModuleRebuildInfo::ReasonIgnored;
815+ using ReasonModuleInterfaceIgnored =
816+ ModuleRebuildInfo::ReasonModuleInterfaceIgnored;
778817 std::pair<std::string, std::string> result;
779- // Should we attempt to load a swiftmodule adjacent to the swiftinterface?
780- bool shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules ;
781818
782- if (modulePath.contains (" .sdk" )) {
783- if (ctx.blockListConfig .hasBlockListAction (moduleName,
784- BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule)) {
785- shouldLoadAdjacentModule = false ;
786- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::Blocklisted);
819+ bool ignoreByDefault = ctx.blockListConfig .hasBlockListAction (
820+ " Swift_UseSwiftinterfaceByDefault" ,
821+ BlockListKeyKind::ModuleName,
822+ BlockListAction::ShouldUseBinaryModule);
823+ bool shouldLoadAdjacentModule;
824+ if (ignoreByDefault) {
825+ ReasonModuleInterfaceIgnored ignore =
826+ ReasonModuleInterfaceIgnored::NotIgnored;
827+
828+ if (!isInSDK (modulePath) &&
829+ !isInResourceHostDir (modulePath)) {
830+ ignore = ReasonModuleInterfaceIgnored::LocalModule;
831+ } else if (ctx.blockListConfig .hasBlockListAction (moduleName,
832+ BlockListKeyKind::ModuleName,
833+ BlockListAction::ShouldUseBinaryModule)) {
834+ ignore = ReasonModuleInterfaceIgnored::Blocklisted;
835+ } else if (ctx.LangOpts .DebuggerSupport ) {
836+ ignore = ReasonModuleInterfaceIgnored::Debugger;
787837 }
788- }
789838
790- // Don't use the adjacent swiftmodule for frameworks from the public
791- // Frameworks folder of the SDK.
792- if (isInSystemFrameworks (modulePath, /* publicFramework*/ true )) {
793- shouldLoadAdjacentModule = false ;
794- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::PublicFramework);
795- } else if (isInResourceHostDir (modulePath)) {
796- shouldLoadAdjacentModule = false ;
797- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::CompilerHostModule);
839+ shouldLoadAdjacentModule =
840+ ignore != ReasonModuleInterfaceIgnored::NotIgnored;
841+ if (shouldLoadAdjacentModule) {
842+ // Prefer the swiftmodule.
843+ rebuildInfo.addIgnoredModuleInterface (modulePath, ignore);
844+ } else {
845+ // Prefer the swiftinterface.
846+ rebuildInfo.addIgnoredModule (modulePath,
847+ ReasonIgnored::DistributedInterfaceByDefault);
848+ }
849+ } else {
850+ // Should we attempt to load a swiftmodule adjacent to the swiftinterface?
851+ shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules ;
852+
853+ if (modulePath.contains (" .sdk" )) {
854+ if (ctx.blockListConfig .hasBlockListAction (moduleName,
855+ BlockListKeyKind::ModuleName,
856+ BlockListAction::ShouldUseTextualModule)) {
857+ shouldLoadAdjacentModule = false ;
858+ rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::Blocklisted);
859+ }
860+ }
861+
862+ // Don't use the adjacent swiftmodule for frameworks from the public
863+ // Frameworks folder of the SDK.
864+ if (isInSystemFrameworks (modulePath, /* publicFramework*/ true )) {
865+ shouldLoadAdjacentModule = false ;
866+ rebuildInfo.addIgnoredModule (modulePath,
867+ ReasonIgnored::PublicFramework);
868+ } else if (isInResourceHostDir (modulePath)) {
869+ shouldLoadAdjacentModule = false ;
870+ rebuildInfo.addIgnoredModule (modulePath,
871+ ReasonIgnored::CompilerHostModule);
872+ }
798873 }
799874
800875 switch (loadMode) {
@@ -1081,8 +1156,10 @@ class ModuleInterfaceLoaderImpl {
10811156 // If we errored with anything other than 'no such file or directory',
10821157 // fail this load and let the other module loader diagnose it.
10831158 if (!moduleOrErr &&
1084- moduleOrErr.getError () != std::errc::no_such_file_or_directory)
1159+ moduleOrErr.getError () != std::errc::no_such_file_or_directory) {
1160+ rebuildInfo.diagnoseIgnoredModuleInterfaces (ctx, diagnosticLoc);
10851161 return moduleOrErr.getError ();
1162+ }
10861163
10871164 // We discovered a module! Return that module's buffer so we can load it.
10881165 if (moduleOrErr) {
@@ -1105,6 +1182,7 @@ class ModuleInterfaceLoaderImpl {
11051182 }
11061183 }
11071184
1185+
11081186 return std::move (module .moduleBuffer );
11091187 }
11101188 // If building from interface is disabled, return error.
0 commit comments