Skip to content

Commit d9d26ee

Browse files
committed
Add support for classes in _createOffsetBasedKeyPath
1 parent 60d82c7 commit d9d26ee

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

stdlib/public/core/KeyPath.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,7 +3912,7 @@ public func _createOffsetBasedKeyPath(
39123912
// The buffer header is 32 bits, but components must start on a word
39133913
// boundary.
39143914
let kpBufferSize = MemoryLayout<Int>.size + MemoryLayout<Int32>.size
3915-
return kpTy._create(capacityInBytes: kpBufferSize) {
3915+
let kp = kpTy._create(capacityInBytes: kpBufferSize) {
39163916
var builder = KeyPathBuffer.Builder($0)
39173917
let header = KeyPathBuffer.Header(
39183918
size: kpBufferSize - MemoryLayout<Int>.size,
@@ -3923,7 +3923,7 @@ public func _createOffsetBasedKeyPath(
39233923
builder.pushHeader(header)
39243924

39253925
let componentHeader = RawKeyPathComponent.Header(
3926-
stored: .struct,
3926+
stored: _MetadataKind(root) == .struct ? .struct : .class,
39273927
mutable: false,
39283928
inlineOffset: UInt32(offset)
39293929
)
@@ -3935,6 +3935,12 @@ public func _createOffsetBasedKeyPath(
39353935

39363936
component.clone(into: &builder.buffer, endOfReferencePrefix: false)
39373937
}
3938+
3939+
if _MetadataKind(root) == .struct {
3940+
kp.assignOffsetToStorage(offset: offset)
3941+
}
3942+
3943+
return kp
39383944
}
39393945

39403946
@_spi(ObservableRerootKeyPath)

test/stdlib/KeyPath.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,16 @@ struct Dog {
10731073
var age: Int
10741074
}
10751075

1076+
class Cat {
1077+
var name: String
1078+
var age: Int
1079+
1080+
init(name: String, age: Int) {
1081+
self.name = name
1082+
self.age = age
1083+
}
1084+
}
1085+
10761086
if #available(SwiftStdlib 5.9, *) {
10771087
keyPath.test("_createOffsetBasedKeyPath") {
10781088
let dogAgeKp = _createOffsetBasedKeyPath(
@@ -1086,6 +1096,18 @@ if #available(SwiftStdlib 5.9, *) {
10861096
let sparky = Dog(name: "Sparky", age: 7)
10871097

10881098
expectEqual(sparky[keyPath: dogAgeKp!], 7)
1099+
1100+
let catNameKp = _createOffsetBasedKeyPath(
1101+
root: Cat.self,
1102+
value: String.self,
1103+
offset: 16
1104+
) as? KeyPath<Cat, String>
1105+
1106+
expectNotNil(catNameKp)
1107+
1108+
let chloe = Cat(name: "Chloe", age: 4)
1109+
1110+
expectEqual(chloe[keyPath: catNameKp!], "Chloe")
10891111
}
10901112
}
10911113

0 commit comments

Comments
 (0)