Skip to content

Commit 5295bdc

Browse files
committed
[TypeChecker] NFC: Add tests for keypath dynamic member lookup
1 parent 7e07644 commit 5295bdc

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
2+
3+
struct Point {
4+
let x: Int
5+
var y: Int
6+
}
7+
8+
struct Rectangle {
9+
var topLeft, bottomRight: Point
10+
}
11+
12+
@dynamicMemberLookup
13+
struct Lens<T> {
14+
var obj: T
15+
16+
init(_ obj: T) {
17+
self.obj = obj
18+
}
19+
20+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> Lens<U> {
21+
get { return Lens<U>(obj[keyPath: member]) }
22+
}
23+
24+
subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
25+
get { return Lens<U>(obj[keyPath: member]) }
26+
set { obj[keyPath: member] = newValue.obj }
27+
}
28+
29+
// Used to make sure that keypath and string based lookup are
30+
// property disambiguated.
31+
subscript(dynamicMember member: String) -> Lens<Int> {
32+
return Lens<Int>(42)
33+
}
34+
}
35+
36+
var topLeft = Point(x: 0, y: 0)
37+
var bottomRight = Point(x: 10, y: 10)
38+
39+
var lens = Lens(Rectangle(topLeft: topLeft,
40+
bottomRight: bottomRight))
41+
42+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup4LensV0B6MemberACyqd__Gs15WritableKeyPathCyxqd__G_tcluig
43+
// CHECK-NEXT: apply %45<Rectangle, Point>({{.*}})
44+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup4LensV0B6MemberACyqd__Gs7KeyPathCyxqd__G_tcluig
45+
// CHECK-NEXT: apply %54<Point, Int>({{.*}})
46+
_ = lens.topLeft.x
47+
48+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup4LensV0B6MemberACyqd__Gs15WritableKeyPathCyxqd__G_tcluig
49+
// CHECK-NEXT: apply %69<Rectangle, Point>({{.*}})
50+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup4LensV0B6MemberACyqd__Gs15WritableKeyPathCyxqd__G_tcluig
51+
// CHECK-NEXT: apply %76<Point, Int>({{.*}})
52+
_ = lens.topLeft.y
53+
54+
lens.topLeft = Lens(Point(x: 1, y: 2)) // Ok
55+
lens.bottomRight.y = Lens(12) // Ok

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,42 @@ class C {
397397
}
398398
_ = \C.[dynamicMember: "hi"]
399399
_ = \C.testLookup
400+
401+
/* KeyPath based dynamic lookup */
402+
403+
struct Point {
404+
var x: Int
405+
let y: Int
406+
}
407+
408+
struct Rectangle {
409+
var topLeft, bottomRight: Point
410+
}
411+
412+
@dynamicMemberLookup
413+
struct Lens<T> {
414+
var obj: T
415+
416+
init(_ obj: T) {
417+
self.obj = obj
418+
}
419+
420+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> Lens<U> {
421+
get { return Lens<U>(obj[keyPath: member]) }
422+
}
423+
424+
subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
425+
get { return Lens<U>(obj[keyPath: member]) }
426+
set { obj[keyPath: member] = newValue.obj }
427+
}
428+
}
429+
430+
var topLeft = Point(x: 0, y: 0)
431+
var bottomRight = Point(x: 10, y: 10)
432+
433+
var lens = Lens(Rectangle(topLeft: topLeft,
434+
bottomRight: bottomRight))
435+
436+
lens.topLeft = Lens(Point(x: 1, y: 2)) // Ok
437+
lens.bottomRight.x = Lens(11) // Ok
438+
lens.bottomRight.y = Lens(12) // expected-error {{cannot assign through dynamic lookup property: 'lens' is immutable}}

0 commit comments

Comments
 (0)