Skip to content

Commit 665a6c9

Browse files
authored
Merge pull request #66932 from Azoy/keypath-offset-spi-59
[5.9] [stdlib] Add support for classes in _createOffsetBasedKeyPath
2 parents b13d8f6 + a6d03c5 commit 665a6c9

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

stdlib/public/core/KeyPath.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3893,6 +3893,8 @@ internal func _instantiateKeyPathBuffer(
38933893
return offset
38943894
}
38953895

3896+
#if SWIFT_ENABLE_REFLECTION
3897+
38963898
@available(SwiftStdlib 5.9, *)
38973899
public func _createOffsetBasedKeyPath(
38983900
root: Any.Type,
@@ -3912,7 +3914,7 @@ public func _createOffsetBasedKeyPath(
39123914
// The buffer header is 32 bits, but components must start on a word
39133915
// boundary.
39143916
let kpBufferSize = MemoryLayout<Int>.size + MemoryLayout<Int32>.size
3915-
return kpTy._create(capacityInBytes: kpBufferSize) {
3917+
let kp = kpTy._create(capacityInBytes: kpBufferSize) {
39163918
var builder = KeyPathBuffer.Builder($0)
39173919
let header = KeyPathBuffer.Header(
39183920
size: kpBufferSize - MemoryLayout<Int>.size,
@@ -3923,7 +3925,7 @@ public func _createOffsetBasedKeyPath(
39233925
builder.pushHeader(header)
39243926

39253927
let componentHeader = RawKeyPathComponent.Header(
3926-
stored: .struct,
3928+
stored: _MetadataKind(root) == .struct ? .struct : .class,
39273929
mutable: false,
39283930
inlineOffset: UInt32(offset)
39293931
)
@@ -3935,9 +3937,13 @@ public func _createOffsetBasedKeyPath(
39353937

39363938
component.clone(into: &builder.buffer, endOfReferencePrefix: false)
39373939
}
3938-
}
39393940

3940-
#if SWIFT_ENABLE_REFLECTION
3941+
if _MetadataKind(root) == .struct {
3942+
kp.assignOffsetToStorage(offset: offset)
3943+
}
3944+
3945+
return kp
3946+
}
39413947

39423948
@_silgen_name("swift_keyPath_copySymbolName")
39433949
fileprivate func keyPath_copySymbolName(

test/stdlib/KeyPath.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,16 @@ struct Dog {
10701070
var age: Int
10711071
}
10721072

1073+
class Cat {
1074+
var name: String
1075+
var age: Int
1076+
1077+
init(name: String, age: Int) {
1078+
self.name = name
1079+
self.age = age
1080+
}
1081+
}
1082+
10731083
if #available(SwiftStdlib 5.9, *) {
10741084
keyPath.test("_createOffsetBasedKeyPath") {
10751085
let dogAgeKp = _createOffsetBasedKeyPath(
@@ -1083,6 +1093,18 @@ if #available(SwiftStdlib 5.9, *) {
10831093
let sparky = Dog(name: "Sparky", age: 7)
10841094

10851095
expectEqual(sparky[keyPath: dogAgeKp!], 7)
1096+
1097+
let catNameKp = _createOffsetBasedKeyPath(
1098+
root: Cat.self,
1099+
value: String.self,
1100+
offset: 16
1101+
) as? KeyPath<Cat, String>
1102+
1103+
expectNotNil(catNameKp)
1104+
1105+
let chloe = Cat(name: "Chloe", age: 4)
1106+
1107+
expectEqual(chloe[keyPath: catNameKp!], "Chloe")
10861108
}
10871109
}
10881110

0 commit comments

Comments
 (0)