diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 87d0f177c7200..9e2f754b4546d 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4326,11 +4326,15 @@ namespace { Impl.SwiftContext.AllocateCopy(retType.getAsString())), decl->getLocation()); } - } else { - Impl.SwiftContext.evaluator.cacheOutput( - LifetimeDependenceInfoRequest{result}, - Impl.SwiftContext.AllocateCopy(lifetimeDependencies)); } + // Cache the dependencies even if we did not infer any. This prevents + // Swift from trying to infer lifetimes using pure-Swift's means, i.e. + // LifetimeDependenceInfoRequest, which would prematurely populate the + // protocol conformance table for the imported C++ type, causing subtle + // issues with conformances to overlay types, such as CxxOptional. + Impl.SwiftContext.evaluator.cacheOutput( + LifetimeDependenceInfoRequest{result}, + Impl.SwiftContext.AllocateCopy(lifetimeDependencies)); for (auto [idx, param] : llvm::enumerate(decl->parameters())) { if (isEscapable(param->getType())) diff --git a/test/Interop/Cxx/stdlib/use-std-optional.swift b/test/Interop/Cxx/stdlib/use-std-optional.swift index ba4b78d56dbb2..581305b232250 100644 --- a/test/Interop/Cxx/stdlib/use-std-optional.swift +++ b/test/Interop/Cxx/stdlib/use-std-optional.swift @@ -1,9 +1,11 @@ // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-5.9) // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-6) // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift) +// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature AddressableParameters) // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift -Xcc -std=c++20) // // REQUIRES: executable_test +// REQUIRES: swift_feature_AddressableParameters import StdlibUnittest import StdOptional @@ -58,10 +60,18 @@ StdOptionalTestSuite.test("std::optional init(_:Wrapped)") { // FIXME: making these variables immutable triggers a miscompile on Linux // (https://github.com/swiftlang/swift/issues/82765) - var optBoolT = StdOptionalBool(true) - var optBoolF = StdOptionalBool(false) + var optBoolTMutable = StdOptionalBool(true) + var optBoolFMutable = StdOptionalBool(false) + expectTrue(optBoolTMutable.pointee) + expectFalse(optBoolFMutable.pointee) + + // If AddressableParameters are enabled, this issue does not happen. +#if hasFeature(AddressableParameters) + let optBoolT = StdOptionalBool(true) + let optBoolF = StdOptionalBool(false) expectTrue(optBoolT.pointee) expectFalse(optBoolF.pointee) +#endif let optString = StdOptionalString(std.string("abc")) expectEqual(std.string("abc"), optString.pointee)