Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stdlib/public/core/KeyPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,7 @@ internal struct RawKeyPathComponent {
switch value {
case .struct(let offset):
var base2 = base
defer { _fixLifetime(base2) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried this issue might be lurking elsewhere too. Could we instead put the _fixLifetime in the implementation of withUnsafeBytes to ensure all uses have the pointee's lifetime extended to cover the closure?

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
Expand Down
23 changes: 23 additions & 0 deletions validation-test/SILOptimizer/rdar133969821.swift
Original file line number Diff line number Diff line change
@@ -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<T: AnyObject> {
weak var rawValue: T? = nil
}
typealias Tuple = (instanceIdentifier: C, object: Weak<C>)
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]) { }