diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift index fb95d3b503da3..92052ebe2395d 100644 --- a/stdlib/public/core/KeyPath.swift +++ b/stdlib/public/core/KeyPath.swift @@ -1710,6 +1710,7 @@ internal struct RawKeyPathComponent { switch value { case .struct(let offset): var base2 = base + defer { _fixLifetime(base2) } return .continue(withUnsafeBytes(of: &base2) { let p = $0.baseAddress.unsafelyUnwrapped.advanced(by: offset) // The contents of the struct should be well-typed, so we can assume diff --git a/validation-test/SILOptimizer/rdar133969821.swift b/validation-test/SILOptimizer/rdar133969821.swift new file mode 100644 index 0000000000000..02a423ebf34e2 --- /dev/null +++ b/validation-test/SILOptimizer/rdar133969821.swift @@ -0,0 +1,23 @@ +// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking) | %FileCheck %s + +// REQUIRES: executable_test +// REQUIRES: concurrency +// REQUIRES: concurrency_runtime +// UNSUPPORTED: back_deployment_runtime + +class C { + init() {} +} +struct Weak { + weak var rawValue: T? = nil +} +typealias Tuple = (instanceIdentifier: C, object: Weak) +let object = C() +let tuple: Tuple = (instanceIdentifier: .init(), object: .init(rawValue: object)) +let closureResult = [tuple].map { $0.object.rawValue }.first +let keypathResult = [tuple].map(\.object.rawValue).first +print("Closure result: \(String(describing: closureResult))") +// CHECK: Closure result: Optional(Optional(main.C)) +print("Keypath result: \(String(describing: keypathResult))") +// CHECK: Keypath result: Optional(Optional(main.C)) +withExtendedLifetime([object]) { }