diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 4d4429a5b691c..9f5d9572aaf78 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -4004,8 +4004,27 @@ bool IsNonUserModuleRequest::evaluate(Evaluator &evaluator, ModuleDecl *mod) con auto sdkOrPlatform = searchPathOpts.getSDKPlatformPath(FS).value_or(sdkPath); StringRef runtimePath = searchPathOpts.RuntimeResourcePath; - return (!runtimePath.empty() && pathStartsWith(runtimePath, modulePath)) || - (!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, modulePath)); + if (!runtimePath.empty() && pathStartsWith(runtimePath, modulePath)) { + return true; + } + if (!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, modulePath)) { + return true; + } + + // `getSDKPlatformPath` returns a real path but the module might have path + // inside a symlink pointing to that real path. To catch this case, also check + // whether the module's real path is inside the SDK's real path. + llvm::SmallString<128> moduleRealPath; + if (FS->getRealPath(modulePath, moduleRealPath)) { + modulePath = moduleRealPath; + } + if (!runtimePath.empty() && pathStartsWith(runtimePath, moduleRealPath)) { + return true; + } + if (!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, moduleRealPath)) { + return true; + } + return false; } version::Version ModuleDecl::getLanguageVersionBuiltWith() const { diff --git a/validation-test/IDE/complete_sdk_is_symlink.swift b/validation-test/IDE/complete_sdk_is_symlink.swift new file mode 100644 index 0000000000000..b9ee2981875e9 --- /dev/null +++ b/validation-test/IDE/complete_sdk_is_symlink.swift @@ -0,0 +1,10 @@ +// UNSUPPORTED: OS=windows-msvc + +// RUN: %empty-directory(%t) +// RUN: ln -s %sdk %t/sdk +// RUN: ln -s %test-resource-dir %t/test_resource_dir + +// RUN: %batch-code-completion -sdk %t/sdk -resource-dir %t/test_resource_dir + +#^COMPLETE^# +// COMPLETE: Decl[FreeFunction]/OtherModule[Swift]/IsSystem: print