mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: Lowering for key paths with indices.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -Xfrontend -enable-sil-ownership -Xfrontend -enable-experimental-keypath-components -o %t/a.out
|
||||
// RUN: %target-build-swift %s -Xfrontend -enable-sil-ownership -Xfrontend -enable-experimental-keypath-components -g -o %t/a.out
|
||||
// RUN: %target-run %t/a.out
|
||||
// REQUIRES: executable_test
|
||||
|
||||
@@ -546,41 +546,72 @@ keyPath.test("IUO and key paths") {
|
||||
expectEqual(kp1.hashValue, kp2.hashValue)
|
||||
}
|
||||
|
||||
struct Subscripts<T: Hashable> {
|
||||
var value: Int
|
||||
subscript() -> Int {
|
||||
get {
|
||||
return value
|
||||
}
|
||||
set {
|
||||
value = newValue
|
||||
}
|
||||
struct SubscriptResult<T: Hashable, U: Hashable> {
|
||||
var canary = LifetimeTracked(3333)
|
||||
var left: T
|
||||
var right: U
|
||||
|
||||
init(left: T, right: U) {
|
||||
self.left = left
|
||||
self.right = right
|
||||
}
|
||||
|
||||
subscript(left: T) -> Bool {
|
||||
return self.left == left
|
||||
}
|
||||
subscript(right: U) -> Bool {
|
||||
return self.right == right
|
||||
}
|
||||
}
|
||||
|
||||
struct Subscripts<T: Hashable> {
|
||||
var canary = LifetimeTracked(4444)
|
||||
|
||||
subscript<U: Hashable>(x: T, y: U) -> SubscriptResult<T, U> {
|
||||
return SubscriptResult(left: x, right: y)
|
||||
}
|
||||
|
||||
subscript(x: Int, y: Int) -> Int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
subscript<U: Hashable>(x: T, y: U) -> (T, U) {
|
||||
return (x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func fullGenericContext<T: Hashable, U: Hashable>(x: T, y: U) -> KeyPath<Subscripts<T>, (T, U)>) {
|
||||
struct KeyA: Hashable {
|
||||
var canary = LifetimeTracked(1111)
|
||||
var value: String
|
||||
|
||||
init(value: String) { self.value = value }
|
||||
|
||||
static func ==(a: KeyA, b: KeyA) -> Bool { return a.value == b.value }
|
||||
var hashValue: Int { return value.hashValue }
|
||||
}
|
||||
struct KeyB: Hashable {
|
||||
var canary = LifetimeTracked(2222)
|
||||
|
||||
var value: Int
|
||||
|
||||
init(value: Int) { self.value = value }
|
||||
|
||||
static func ==(a: KeyB, b: KeyB) -> Bool { return a.value == b.value }
|
||||
var hashValue: Int { return value.hashValue }
|
||||
}
|
||||
|
||||
func fullGenericContext<T: Hashable, U: Hashable>(x: T, y: U) -> KeyPath<Subscripts<T>, SubscriptResult<T, U>> {
|
||||
return \Subscripts<T>.[x, y]
|
||||
}
|
||||
|
||||
func halfGenericContext<U: Hashable>(x: String, y: U) -> KeyPath<Subscripts<String>, (String, U)> {
|
||||
return \Subscripts<String>.[x, y]
|
||||
func halfGenericContext<U: Hashable>(x: KeyA, y: U) -> KeyPath<Subscripts<KeyA>, SubscriptResult<KeyA, U>> {
|
||||
return \Subscripts<KeyA>.[x, y]
|
||||
}
|
||||
|
||||
func nonGenericContext(x: String, y: Int) -> KeyPath<Subscripts<String>, (String, Int)> {
|
||||
return \Subscripts<String>.[x, y]
|
||||
func nonGenericContext(x: KeyA, y: KeyB) -> KeyPath<Subscripts<KeyA>, SubscriptResult<KeyA, KeyB>> {
|
||||
return \Subscripts<KeyA>.[x, y]
|
||||
}
|
||||
|
||||
keyPath.test("subscripts") {
|
||||
let a = fullGenericContext("hey", 1738)
|
||||
let b = halfGenericContext("hey", 1738)
|
||||
let c = nonGenericContext("hey", 1738)
|
||||
let a = fullGenericContext(x: KeyA(value: "hey"), y: KeyB(value: 1738))
|
||||
let b = halfGenericContext(x: KeyA(value: "hey"), y: KeyB(value: 1738))
|
||||
let c = nonGenericContext(x: KeyA(value: "hey"), y: KeyB(value: 1738))
|
||||
|
||||
expectEqual(a, b)
|
||||
expectEqual(a, c)
|
||||
@@ -594,8 +625,46 @@ keyPath.test("subscripts") {
|
||||
expectEqual(b.hashValue, c.hashValue)
|
||||
expectEqual(c.hashValue, a.hashValue)
|
||||
expectEqual(c.hashValue, b.hashValue)
|
||||
}
|
||||
|
||||
let base = Subscripts<KeyA>()
|
||||
|
||||
let kp2 = \SubscriptResult<KeyA, KeyB>.[KeyA(value: "hey")]
|
||||
|
||||
for kp in [a, b, c] {
|
||||
let projected = base[keyPath: kp]
|
||||
expectEqual(projected.left.value, "hey")
|
||||
expectEqual(projected.right.value, 1738)
|
||||
|
||||
expectEqual(projected[keyPath: kp2], true)
|
||||
|
||||
let kp12 =
|
||||
\Subscripts<KeyA>.[KeyA(value: "hey"), KeyB(value: 1738)][KeyA(value: "hey")]
|
||||
|
||||
let kp12a = kp.appending(path: kp2)
|
||||
|
||||
expectEqual(kp12, kp12a)
|
||||
expectEqual(kp12a, kp12)
|
||||
expectEqual(kp12.hashValue, kp12a.hashValue)
|
||||
}
|
||||
|
||||
let ints = \Subscripts<KeyA>.[17, 38]
|
||||
let ints2 = \Subscripts<KeyA>.[17, 38]
|
||||
let ints3 = \Subscripts<KeyA>.[38, 17]
|
||||
expectEqual(base[keyPath: ints], 17 + 38)
|
||||
|
||||
expectEqual(ints, ints2)
|
||||
expectEqual(ints2, ints)
|
||||
expectNotEqual(ints, ints3)
|
||||
expectNotEqual(ints2, ints3)
|
||||
expectNotEqual(ints3, ints)
|
||||
expectNotEqual(ints3, ints2)
|
||||
|
||||
expectEqual(ints.hashValue, ints2.hashValue)
|
||||
|
||||
let ints_be = ints.appending(path: \Int.bigEndian)
|
||||
|
||||
expectEqual(base[keyPath: ints_be], (17 + 38).bigEndian)
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user