// RUN: %target-swift-frontend -enable-experimental-feature KeyPathWithMethodMembers -typecheck -parse-as-library %s -verify // REQUIRES: swift_feature_KeyPathWithMethodMembers struct Sub: Hashable { static func ==(_: Sub, _: Sub) -> Bool { return true } func hash(into hasher: inout Hasher) {} } struct OptSub: Hashable { static func ==(_: OptSub, _: OptSub) -> Bool { return true } func hash(into hasher: inout Hasher) {} } struct NonHashableSub {} struct Prop { subscript(sub: Sub) -> A { get { return A() } set { } } subscript(optSub: OptSub) -> A? { get { return A() } set { } } subscript(nonHashableSub: NonHashableSub) -> A { get { return A() } set { } } subscript(a: Sub, b: Sub) -> A { get { return A() } set { } } subscript(a: Sub, b: NonHashableSub) -> A { get { return A() } set { } } var nonMutatingProperty: B { get { fatalError() } nonmutating set { fatalError() } } } struct A: Hashable { init() { fatalError() } var property: Prop var optProperty: Prop? let optLetProperty: Prop? subscript(sub: Sub) -> A { get { return self } set { } } func foo(_ b: NonHashableSub) {} static func foo(_ b: Sub) {} static func ==(_: A, _: A) -> Bool { fatalError() } func hash(into hasher: inout Hasher) { fatalError() } } struct B {} struct C { // expected-note 4 {{'T' declared as parameter to type 'C'}} var value: T subscript() -> T { get { return value } } subscript(sub: Sub) -> T { get { return value } set { } } subscript(sub: U) -> U { get { return sub } set { } } subscript(noHashableConstraint sub: X) -> X { get { return sub } set { } } } struct Unavailable { @available(*, unavailable) var unavailableProperty: Int { 0 } // expected-note@-1 {{'unavailableProperty' has been explicitly marked unavailable here}} @available(*, unavailable) subscript(x: Sub) -> Int { get { } set { } } // expected-note@-1 {{'subscript(_:)' has been explicitly marked unavailable here}} } struct Deprecated { @available(*, deprecated) var deprecatedProperty: Int @available(*, deprecated) subscript(x: Sub) -> Int { get { } set { } } } @available(*, deprecated) func getDeprecatedSub() -> Sub { return Sub() } extension Array where Element == A { var property: Prop { fatalError() } } protocol P { var member: String { get } } extension B : P { var member : String { return "Member Value" } } struct Exactly {} func expect(_ x: inout T, toHaveType _: Exactly.Type) {} func testKeyPath(sub: Sub, optSub: OptSub, nonHashableSub: NonHashableSub, x: Int) { var a = \A.property expect(&a, toHaveType: Exactly>.self) var b = \A.[sub] expect(&b, toHaveType: Exactly>.self) var c = \A.[sub].property expect(&c, toHaveType: Exactly>.self) var d = \A.optProperty? expect(&d, toHaveType: Exactly>.self) var e = \A.optProperty?[sub] expect(&e, toHaveType: Exactly>.self) var f = \A.optProperty! expect(&f, toHaveType: Exactly>.self) var g = \A.property[optSub]?.optProperty![sub] expect(&g, toHaveType: Exactly>.self) var h = \[A].property expect(&h, toHaveType: Exactly>.self) var i = \[A].property.nonMutatingProperty expect(&i, toHaveType: Exactly>.self) var j = \[A].[x] expect(&j, toHaveType: Exactly>.self) var k = \[A: B].[A()] expect(&k, toHaveType: Exactly>.self) var l = \C.value expect(&l, toHaveType: Exactly, A>>.self) var hashableCapture = \A.Type.foo(Sub()) expect(&hashableCapture, toHaveType: Exactly>.self) // expected-error@+1 {{method argument of type 'NonHashableSub' in a key path must be Hashable}} _ = \A.foo(NonHashableSub()) // expected-error@+1{{generic parameter 'T' could not be inferred}} _ = \C.value // expected-error@+1{{}} _ = \(() -> ()).noMember let _: (A) -> Prop = \.property let _: (A) -> Prop? = \.property let _: PartialKeyPath = \.property let _: KeyPath = \.property let _: WritableKeyPath = \.property let _: ReferenceWritableKeyPath = \.property //expected-error@-1 {{cannot convert key path type 'WritableKeyPath' to contextual type 'ReferenceWritableKeyPath'}} let _: (A) -> A? = \.[sub] let _: (A) -> A = \.[sub] let _: PartialKeyPath = \.[sub] let _: KeyPath = \.[sub] let _: WritableKeyPath = \.[sub] let _: ReferenceWritableKeyPath = \.[sub] //expected-error@-1 {{cannot convert key path type 'WritableKeyPath' to contextual type 'ReferenceWritableKeyPath'}} let _: (A) -> Prop?? = \.optProperty? let _: (A) -> Prop? = \.optProperty? let _: PartialKeyPath = \.optProperty? let _: KeyPath = \.optProperty? // expected-error@+1{{cannot convert}} let _: WritableKeyPath = \.optProperty? // expected-error@+1{{cannot convert}} let _: ReferenceWritableKeyPath = \.optProperty? let _: (A) -> A?? = \.optProperty?[sub] let _: (A) -> A? = \.optProperty?[sub] let _: PartialKeyPath = \.optProperty?[sub] let _: KeyPath = \.optProperty?[sub] // expected-error@+1{{cannot convert}} let _: WritableKeyPath = \.optProperty?[sub] // expected-error@+1{{cannot convert}} let _: ReferenceWritableKeyPath = \.optProperty?[sub] let _: KeyPath = \.optProperty! let _: KeyPath = \.optLetProperty! let _: KeyPath = \.property[optSub]?.optProperty! let _: KeyPath = \.property[optSub]?.optProperty![sub] let _: (C) -> A? = \.value let _: (C) -> A = \.value let _: PartialKeyPath> = \.value let _: KeyPath, A> = \.value let _: WritableKeyPath, A> = \.value let _: ReferenceWritableKeyPath, A> = \.value // expected-error@-1 {{cannot convert key path type 'WritableKeyPath, A>' to contextual type 'ReferenceWritableKeyPath, A>'}} let _: (C) -> A? = \C.value let _: (C) -> A = \C.value let _: PartialKeyPath> = \C.value let _: KeyPath, A> = \C.value let _: WritableKeyPath, A> = \C.value // expected-error@+1{{cannot convert}} let _: ReferenceWritableKeyPath, A> = \C.value let _: (Prop) -> B? = \.nonMutatingProperty let _: (Prop) -> B = \.nonMutatingProperty let _: PartialKeyPath = \.nonMutatingProperty let _: KeyPath = \.nonMutatingProperty let _: WritableKeyPath = \.nonMutatingProperty let _: ReferenceWritableKeyPath = \.nonMutatingProperty var m = [\A.property, \A.[sub], \A.optProperty!] expect(&m, toHaveType: Exactly<[PartialKeyPath]>.self) // \.optProperty returns an optional of Prop and `\.[sub]` returns `A`, all this unifies into `[PartialKeyPath]` var n = [\A.property, \.optProperty, \.[sub], \.optProperty!] expect(&n, toHaveType: Exactly<[PartialKeyPath]>.self) let _: [PartialKeyPath] = [\.property, \.optProperty, \.[sub], \.optProperty!] var o = [\A.property, \C.value] expect(&o, toHaveType: Exactly<[AnyKeyPath]>.self) let _: AnyKeyPath = \A.property let _: AnyKeyPath = \C.value let _: AnyKeyPath = \.property // expected-error {{'AnyKeyPath' does not provide enough context for root type to be inferred; consider explicitly specifying a root type}} {{24-24=<#Root#>}} let _: AnyKeyPath = \C.value // expected-error{{generic parameter 'T' could not be inferred}} let _: AnyKeyPath = \.value // expected-error {{'AnyKeyPath' does not provide enough context for root type to be inferred; consider explicitly specifying a root type}} {{24-24=<#Root#>}} let _ = \Prop.[nonHashableSub] // expected-error{{subscript index of type 'NonHashableSub' in a key path must be Hashable}} let _ = \Prop.[sub, sub] let _ = \Prop.[sub, nonHashableSub] // expected-error{{subscript index of type 'NonHashableSub' in a key path must be Hashable}} let _ = \C.[] let _ = \C.[sub] let _ = \C.[noHashableConstraint: sub] let _ = \C.[noHashableConstraint: nonHashableSub] // expected-error{{subscript index of type 'NonHashableSub' in a key path must be Hashable}} let _ = \Unavailable.unavailableProperty // expected-error {{'unavailableProperty' is unavailable}} let _ = \Unavailable.[sub] // expected-error {{'subscript(_:)' is unavailable}} let _ = \Deprecated.deprecatedProperty // expected-warning {{'deprecatedProperty' is deprecated}} let _ = \Deprecated.[sub] // expected-warning {{'subscript(_:)' is deprecated}} let _ = \A.[getDeprecatedSub()] // expected-warning {{'getDeprecatedSub()' is deprecated}} } func testKeyPathInGenericContext(hashable: H, anything: X) { let _ = \C.[hashable] let _ = \C.[noHashableConstraint: hashable] let _ = \C.[noHashableConstraint: anything] // expected-error{{subscript index of type 'X' in a key path must be Hashable}} } func testDisembodiedStringInterpolation(x: Int) { \(x) // expected-error{{string interpolation can only appear inside a string literal}} \(x, radix: 16) // expected-error{{string interpolation can only appear inside a string literal}} } func testNoComponents() { let _: KeyPath = \A // expected-error{{must have at least one component}} let _: KeyPath = \C // expected-error{{must have at least one component}} // expected-error@-1 {{generic parameter 'T' could not be inferred}} let _: KeyPath = \A // expected-error{{must have at least one component}} // expected-error@-1 {{generic parameter 'T' could not be inferred}} _ = \A // expected-error {{key path must have at least one component}} } struct TupleStruct { var unlabeled: (Int, String) var labeled: (foo: Int, bar: String) } typealias UnlabeledGenericTuple = (T, U) typealias LabeledGenericTuple = (a: T, b: U) func tupleComponent(_: T, _: U) { let _ = \(Int, String).0 let _ = \(Int, String).1 let _ = \TupleStruct.unlabeled.0 let _ = \TupleStruct.unlabeled.1 let _ = \(foo: Int, bar: String).0 let _ = \(foo: Int, bar: String).1 let _ = \(foo: Int, bar: String).foo let _ = \(foo: Int, bar: String).bar let _ = \TupleStruct.labeled.0 let _ = \TupleStruct.labeled.1 let _ = \TupleStruct.labeled.foo let _ = \TupleStruct.labeled.bar let _ = \(T, U).0 let _ = \(T, U).1 let _ = \UnlabeledGenericTuple.0 let _ = \UnlabeledGenericTuple.1 let _ = \(a: T, b: U).0 let _ = \(a: T, b: U).1 let _ = \(a: T, b: U).a let _ = \(a: T, b: U).b let _ = \LabeledGenericTuple.0 let _ = \LabeledGenericTuple.1 let _ = \LabeledGenericTuple.a let _ = \LabeledGenericTuple.b } func tuple_el_0() -> KeyPath<(T, U), T> { return \.0 } func tuple_el_1() -> KeyPath<(T, U), U> { return \.1 } func tupleGeneric(_ v: (T, U)) { _ = (1, "hello")[keyPath: tuple_el_0()] _ = (1, "hello")[keyPath: tuple_el_1()] _ = v[keyPath: tuple_el_0()] _ = v[keyPath: tuple_el_1()] _ = ("tuple", "too", "big")[keyPath: tuple_el_1()] // expected-note@-12 {{}} // expected-error@-2 {{generic parameter 'T' could not be inferred}} // expected-error@-3 {{generic parameter 'U' could not be inferred}} } struct Z { } func testKeyPathSubscript(readonly: Z, writable: inout Z, kp: KeyPath, wkp: WritableKeyPath, rkp: ReferenceWritableKeyPath) { var sink: Int sink = readonly[keyPath: kp] sink = writable[keyPath: kp] sink = readonly[keyPath: wkp] sink = writable[keyPath: wkp] sink = readonly[keyPath: rkp] sink = writable[keyPath: rkp] readonly[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} writable[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} readonly[keyPath: wkp] = sink // expected-error{{cannot assign through subscript: 'readonly' is a 'let' constant}} writable[keyPath: wkp] = sink readonly[keyPath: rkp] = sink writable[keyPath: rkp] = sink let pkp: PartialKeyPath = rkp var anySink1 = readonly[keyPath: pkp] expect(&anySink1, toHaveType: Exactly.self) var anySink2 = writable[keyPath: pkp] expect(&anySink2, toHaveType: Exactly.self) readonly[keyPath: pkp] = anySink1 // expected-error{{cannot assign through subscript: 'pkp' is a read-only key path}} writable[keyPath: pkp] = anySink2 // expected-error{{cannot assign through subscript: 'pkp' is a read-only key path}} let akp: AnyKeyPath = pkp var anyqSink1 = readonly[keyPath: akp] expect(&anyqSink1, toHaveType: Exactly.self) var anyqSink2 = writable[keyPath: akp] expect(&anyqSink2, toHaveType: Exactly.self) readonly[keyPath: akp] = anyqSink1 // expected-error{{cannot assign through subscript: 'readonly' is a 'let' constant}} writable[keyPath: akp] = anyqSink2 // expected-error{{cannot assign through subscript: 'writable' is immutable}} } struct ZwithSubscript { subscript(keyPath kp: KeyPath) -> Int { return 0 } subscript(keyPath kp: WritableKeyPath) -> Int { return 0 } subscript(keyPath kp: ReferenceWritableKeyPath) -> Int { return 0 } subscript(keyPath kp: PartialKeyPath) -> Any { return 0 } } struct NotZ {} func testKeyPathSubscript(readonly: ZwithSubscript, writable: inout ZwithSubscript, wrongType: inout NotZ, kp: KeyPath, wkp: WritableKeyPath, rkp: ReferenceWritableKeyPath) { var sink: Int sink = readonly[keyPath: kp] sink = writable[keyPath: kp] sink = readonly[keyPath: wkp] sink = writable[keyPath: wkp] sink = readonly[keyPath: rkp] sink = writable[keyPath: rkp] readonly[keyPath: kp] = sink // expected-error {{cannot assign through subscript: subscript is get-only}} writable[keyPath: kp] = sink // expected-error {{cannot assign through subscript: subscript is get-only}} readonly[keyPath: wkp] = sink // expected-error {{cannot assign through subscript: subscript is get-only}} // FIXME: silently falls back to keypath application, which seems inconsistent writable[keyPath: wkp] = sink // FIXME: silently falls back to keypath application, which seems inconsistent readonly[keyPath: rkp] = sink // FIXME: silently falls back to keypath application, which seems inconsistent writable[keyPath: rkp] = sink let pkp: PartialKeyPath = rkp var anySink1 = readonly[keyPath: pkp] expect(&anySink1, toHaveType: Exactly.self) var anySink2 = writable[keyPath: pkp] expect(&anySink2, toHaveType: Exactly.self) readonly[keyPath: pkp] = anySink1 // expected-error{{cannot assign through subscript: subscript is get-only}} writable[keyPath: pkp] = anySink2 // expected-error{{cannot assign through subscript: subscript is get-only}} let akp: AnyKeyPath = pkp var anyqSink1 = readonly[keyPath: akp] expect(&anyqSink1, toHaveType: Exactly.self) var anyqSink2 = writable[keyPath: akp] expect(&anyqSink2, toHaveType: Exactly.self) // FIXME: silently falls back to keypath application, which seems inconsistent readonly[keyPath: akp] = anyqSink1 // expected-error{{cannot assign through subscript: 'readonly' is a 'let' constant}} // FIXME: silently falls back to keypath application, which seems inconsistent writable[keyPath: akp] = anyqSink2 // expected-error{{cannot assign through subscript: 'writable' is immutable}} _ = wrongType[keyPath: kp] // expected-error{{cannot be applied}} _ = wrongType[keyPath: wkp] // expected-error{{cannot be applied}} _ = wrongType[keyPath: rkp] // expected-error{{cannot be applied}} _ = wrongType[keyPath: pkp] // expected-error{{cannot be applied}} _ = wrongType[keyPath: akp] } func testKeyPathSubscriptMetatype(readonly: Z.Type, writable: inout Z.Type, kp: KeyPath, wkp: WritableKeyPath, rkp: ReferenceWritableKeyPath) { var sink: Int sink = readonly[keyPath: kp] sink = writable[keyPath: kp] sink = readonly[keyPath: wkp] sink = writable[keyPath: wkp] sink = readonly[keyPath: rkp] sink = writable[keyPath: rkp] readonly[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} writable[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} readonly[keyPath: wkp] = sink // expected-error{{cannot assign through subscript: 'readonly' is a 'let' constant}} writable[keyPath: wkp] = sink readonly[keyPath: rkp] = sink writable[keyPath: rkp] = sink } func testKeyPathSubscriptTuple(readonly: (Z,Z), writable: inout (Z,Z), kp: KeyPath<(Z,Z), Int>, wkp: WritableKeyPath<(Z,Z), Int>, rkp: ReferenceWritableKeyPath<(Z,Z), Int>) { var sink: Int sink = readonly[keyPath: kp] sink = writable[keyPath: kp] sink = readonly[keyPath: wkp] sink = writable[keyPath: wkp] sink = readonly[keyPath: rkp] sink = writable[keyPath: rkp] readonly[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} writable[keyPath: kp] = sink // expected-error{{cannot assign through subscript: 'kp' is a read-only key path}} readonly[keyPath: wkp] = sink // expected-error{{cannot assign through subscript: 'readonly' is a 'let' constant}} writable[keyPath: wkp] = sink readonly[keyPath: rkp] = sink writable[keyPath: rkp] = sink } func testKeyPathSubscriptLValue(base: Z, kp: inout KeyPath) { _ = base[keyPath: kp] } func testKeyPathSubscriptExistentialBase(concreteBase: inout B, existentialBase: inout P, kp: KeyPath, wkp: WritableKeyPath, rkp: ReferenceWritableKeyPath, pkp: PartialKeyPath

, s: String) { _ = concreteBase[keyPath: kp] _ = concreteBase[keyPath: wkp] _ = concreteBase[keyPath: rkp] _ = concreteBase[keyPath: pkp] concreteBase[keyPath: kp] = s // expected-error {{cannot assign through subscript: 'kp' is a read-only key path}} concreteBase[keyPath: wkp] = s // expected-error {{key path with root type 'any P' cannot be applied to a base of type 'B'}} concreteBase[keyPath: rkp] = s concreteBase[keyPath: pkp] = s // expected-error {{cannot assign through subscript: 'pkp' is a read-only key path}} _ = existentialBase[keyPath: kp] _ = existentialBase[keyPath: wkp] _ = existentialBase[keyPath: rkp] _ = existentialBase[keyPath: pkp] existentialBase[keyPath: kp] = s // expected-error {{cannot assign through subscript: 'kp' is a read-only key path}} existentialBase[keyPath: wkp] = s existentialBase[keyPath: rkp] = s existentialBase[keyPath: pkp] = s // expected-error {{cannot assign through subscript: 'pkp' is a read-only key path}} } struct AA { subscript(x: Int) -> Int { return x } subscript(labeled x: Int) -> Int { return x } var c: CC? = CC() } class CC { var i = 0 } func testKeyPathOptional() { _ = \AA.c?.i _ = \AA.c!.i _ = \AA.c?.i.hashValue // https://github.com/apple/swift/issues/48750 let path: KeyPath! = \CC.i let cc = CC() _ = cc[keyPath: path] } func testLiteralInAnyContext() { let _: AnyKeyPath = \A.property let _: AnyObject = \A.property let _: Any = \A.property let _: Any? = \A.property } func testMoreGeneralContext(_: KeyPath, with: T.Type) {} func testLiteralInMoreGeneralContext() { testMoreGeneralContext(\.property, with: A.self) } func testLabeledSubscript() { let _: KeyPath = \AA.[labeled: 0] let _: KeyPath = \.[labeled: 0] let k = \AA.[labeled: 0] // TODO: These ought to work without errors. let _ = \AA.[keyPath: k] // expected-error@-1 {{cannot convert value of type 'KeyPath' to expected argument type 'Int'}} // expected-error@-2 {{extraneous argument label 'keyPath:' in call}} let _ = \AA.[keyPath: \AA.[labeled: 0]] // expected-error {{extraneous argument label 'keyPath:' in call}} // expected-error@-1 {{cannot convert value of type 'KeyPath' to expected argument type 'Int'}} } func testInvalidKeyPathComponents() { let _ = \.{return 0} // expected-error* {{}} } struct W { static let h = 50 } class X { class var a: Int { return 1 } static var b = 20 let c = true static subscript(d: Int) -> String { "\(d)" } var e: W.Type? { return W.self } } class Y : X { subscript(f: Int) -> W.Type { W.self } static subscript(g: Int) -> W.Type { W.self } } func testStaticKeyPathComponent() { _ = \X.a // expected-error{{static member 'a' cannot be used on instance of type 'X'}} _ = \X.Type.a _ = \X.b // expected-error{{static member 'b' cannot be used on instance of type 'X'}} _ = \X.Type.b _ = \X.c _ = \X.Type.c // expected-error{{instance member 'c' cannot be used on type 'X'}} _ = \X.[42] // expected-error{{static member 'subscript(_:)' cannot be used on instance of type 'X'}} _ = \X.Type.[42] let _: KeyPath = \.e?.h let _: PartialKeyPath = \.e?.h let _: AnyKeyPath = \X.e?.h let _ : KeyPath = \Y.[40] let _ : KeyPath = \Y.Type.[70] } class Bass: Hashable { static func ==(_: Bass, _: Bass) -> Bool { return false } func hash(into hasher: inout Hasher) {} } class Treble: Bass { } struct BassSubscript { subscript(_: Bass) -> Int { fatalError() } subscript(_: @autoclosure () -> String) -> Int { fatalError() } } func testImplicitConversionInSubscriptIndex() { _ = \BassSubscript.[Treble()] _ = \BassSubscript.["hello"] // expected-error{{must be Hashable}} } // Crash in diagnostics + https://github.com/apple/swift/issues/53839 struct UnambiguousSubscript { subscript(sub: Sub) -> Int { get { } set { } } subscript(y y: Sub) -> Int { get { } set { } } } func useUnambiguousSubscript(_ sub: Sub) { let _: PartialKeyPath = \.[sub] } struct BothUnavailableSubscript { @available(*, unavailable) subscript(sub: Sub) -> Int { get { } set { } } // expected-note {{'subscript(_:)' has been explicitly marked unavailable here}} @available(*, unavailable) subscript(y y: Sub) -> Int { get { } set { } } } func useBothUnavailableSubscript(_ sub: Sub) { let _: PartialKeyPath = \.[sub] // expected-error@-1 {{'subscript(_:)' is unavailable}} } // https://github.com/apple/swift/issues/48661 func f_48661() { class B {} class A { var b: B? = nil } class C { var a: A? func myFunc() { let _ = \C.a?.b } } } // https://github.com/apple/swift/issues/49293 func f_49293() { struct ABC { let value: Int func value(adding i: Int) -> Int { return value + i } } let abc = ABC(value: 0) func get(for kp: KeyPath) -> T { return abc[keyPath: kp] } _ = get(for: \.value) } // https://github.com/apple/swift/issues/49928 func f_49928() { _ = ""[keyPath: \.count] _ = ""[keyPath: \String.count] let arr1 = [1] _ = arr1[keyPath: \.[0]] _ = arr1[keyPath: \[Int].[0]] let dic1 = [1:"s"] _ = dic1[keyPath: \.[1]] _ = dic1[keyPath: \[Int: String].[1]] var arr2 = [1] arr2[keyPath: \.[0]] = 2 arr2[keyPath: \[Int].[0]] = 2 var dic2 = [1:"s"] dic2[keyPath: \.[1]] = "" dic2[keyPath: \[Int: String].[1]] = "" _ = [""][keyPath: \.[0]] _ = [""][keyPath: \[String].[0]] _ = ["": ""][keyPath: \.["foo"]] _ = ["": ""][keyPath: \[String: String].["foo"]] class A { var a: String = "" } _ = A()[keyPath: \.a] _ = A()[keyPath: \A.a] A()[keyPath: \.a] = "" A()[keyPath: \A.a] = "" } struct VisibilityTesting { private(set) var x: Int fileprivate(set) var y: Int let z: Int // Key path exprs should not get special dispensation to write to lets // in init contexts init() { var xRef = \VisibilityTesting.x var yRef = \VisibilityTesting.y var zRef = \VisibilityTesting.z expect(&xRef, toHaveType: Exactly>.self) expect(&yRef, toHaveType: Exactly>.self) // Allow WritableKeyPath for Swift 3/4 only. expect(&zRef, toHaveType: Exactly>.self) } func inPrivateContext() { var xRef = \VisibilityTesting.x var yRef = \VisibilityTesting.y var zRef = \VisibilityTesting.z expect(&xRef, toHaveType: Exactly>.self) expect(&yRef, toHaveType: Exactly>.self) expect(&zRef, toHaveType: Exactly>.self) } } struct VisibilityTesting2 { func inFilePrivateContext() { var xRef = \VisibilityTesting.x var yRef = \VisibilityTesting.y var zRef = \VisibilityTesting.z // Allow WritableKeyPath for Swift 3/4 only. expect(&xRef, toHaveType: Exactly>.self) expect(&yRef, toHaveType: Exactly>.self) expect(&zRef, toHaveType: Exactly>.self) } } protocol PP {} class Base : PP { var i: Int = 0 } class Derived : Base {} func testSubtypeKeypathClass(_ keyPath: ReferenceWritableKeyPath) { testSubtypeKeypathClass(\Derived.i) } func testSubtypeKeypathProtocol(_ keyPath: ReferenceWritableKeyPath) { testSubtypeKeypathProtocol(\Base.i) // expected-error@-1 {{cannot convert value of type 'ReferenceWritableKeyPath' to expected argument type 'ReferenceWritableKeyPath'}} // expected-note@-2 {{arguments to generic parameter 'Root' ('Base' and 'any PP') are expected to be equal}} } // rdar://problem/32057712 struct Container { let base: Base? = Base() } var rdar32057712 = \Container.base?.i var identity1 = \Container.self var identity2: WritableKeyPath = \Container.self var identity3: WritableKeyPath = \Container.self var identity4: WritableKeyPath = \.self var identity5: KeyPath = \Container.self var identity6: KeyPath = \Container.self var identity7: KeyPath = \.self var identity8: PartialKeyPath = \Container.self var identity9: PartialKeyPath = \Container.self var identity10: PartialKeyPath = \.self var identity11: AnyKeyPath = \Container.self var identity12: (Container) -> Container = \Container.self var identity13: (Container) -> Container = \.self var identity14: (Container) -> Container? = \Container.self var identity15: (Container) -> Container? = \.self var interleavedIdentityComponents = \Container.self.base.self?.self.i.self protocol P_With_Static_Members { static var x: Int { get } static var arr: [Int] { get } } func test_keypath_with_static_members(_ p: P_With_Static_Members) { let _ = p[keyPath: \.x] // expected-error@-1 {{static member 'x' cannot be used on instance of type 'any P_With_Static_Members'}} let _: KeyPath = \.x // expected-error@-1 {{static member 'x' cannot be used on instance of type 'any P_With_Static_Members'}} let _ = \P_With_Static_Members.arr.count // expected-error@-1 {{static member 'arr' cannot be used on instance of type 'any P_With_Static_Members'}} let _ = p[keyPath: \.arr.count] // expected-error@-1 {{static member 'arr' cannot be used on instance of type 'any P_With_Static_Members'}} struct S { static var foo: String = "Hello" var bar: Bar } struct Bar { static var baz: Int = 42 } func foo(_ s: S) { let _ = \S.Type.foo let _ = s[keyPath: \.foo] // expected-error@-1 {{static member 'foo' cannot be used on instance of type 'S'}} let _: KeyPath = \.foo // expected-error@-1 {{static member 'foo' cannot be used on instance of type 'S'}} let _ = \S.foo // expected-error@-1 {{static member 'foo' cannot be used on instance of type 'S'}} let _ = \S.bar.baz // expected-error@-1 {{static member 'baz' cannot be used on instance of type 'Bar'}} let _ = s[keyPath: \.bar.baz] // expected-error@-1 {{static member 'baz' cannot be used on instance of type 'Bar'}} } } func test_keypath_with_mutating_getter() { struct S { var foo: Int { mutating get { return 42 } } subscript(_: Int) -> [Int] { mutating get { return [] } } } _ = \S.foo // expected-error@-1 {{key path cannot refer to 'foo', which has a mutating getter}} let _: KeyPath = \.foo // expected-error@-1 {{key path cannot refer to 'foo', which has a mutating getter}} _ = \S.[0] // expected-error@-1 {{key path cannot refer to 'subscript(_:)', which has a mutating getter}} _ = \S.[0].count // expected-error@-1 {{key path cannot refer to 'subscript(_:)', which has a mutating getter}} func test_via_subscript(_ s: S) { _ = s[keyPath: \.foo] // expected-error@-1 {{key path cannot refer to 'foo', which has a mutating getter}} _ = s[keyPath: \.[0].count] // expected-error@-1 {{key path cannot refer to 'subscript(_:)', which has a mutating getter}} } } func test_keypath_with_method_refs() { enum ValidationError: Error { case invalidYear } struct S { static let millenium = 3 var year = 2024 init() {} init(val value: Int = 2024) { year = value } var add: (Int, Int) -> Int { return { $0 + $1 } } func add(this: Int) -> Int { this + this} func add(that: Int) -> Int { that + that } static func subtract(_ val: Int) -> Int { return millenium - val } nonisolated func nonisolatedNextYear() -> Int { return year + 1 } consuming func consume() { print(year) } func validateYear() throws { if year < 0 { throw ValidationError.invalidYear } } func doubleValue(_ value: inout Int) { value *= 2 } mutating func updateYear(to newYear: Int) { self.year = newYear } func calculateFutureYear(after seconds: UInt64) async -> Int { try? await Task.sleep(nanoseconds: seconds) return year + 10 } func validateAndCalculateFutureYear(after seconds: UInt64) async throws -> Int { try validateYear() try await Task.sleep(nanoseconds: seconds) return year + 10 } subscript(index: Int) -> Int { return year + index } } let _: KeyPath Int> = \.add let _: KeyPath Int> = \.add() // expected-error@-1 {{cannot assign value of type 'KeyPath' to type 'KeyPath Int>'}} // expected-note@-2 {{arguments to generic parameter 'Value' ('Int' and '(Int, Int) -> Int') are expected to be equal}} let _: KeyPath = \.add() // expected-error {{type of expression is ambiguous without a type annotation}} let _: KeyPath Int> = \.add(this:) let _: KeyPath = \.add(that: 1) let _: KeyPath Int> = \.subtract // expected-error {{static member 'subtract' cannot be used on instance of type 'S'}} let _ = \S.Type.subtract(1) let _: KeyPath Int> = \S.nonisolatedNextYear let _: KeyPath = \S.nonisolatedNextYear() do { try S()[keyPath: \S.validateYear]() // expected-error {{cannot form key path to instance method with 'throws' or 'async'}} } catch { print("Validation failed: \(error)") } var value = 2025 let _ = \S.doubleValue(&value) // expected-error {{cannot pass an inout argument to a keypath method}} let _: KeyPath = \S.updateYear(to: 2025) // expected-error {{key path cannot refer to mutating method 'updateYear(to:)}} let _: KeyPath = \S.calculateFutureYear(after: 5) // expected-error {{cannot form key path to instance method with 'throws' or 'async'}} let _: KeyPath = \S.validateAndCalculateFutureYear(after: 5) // expected-error {{cannot form key path to instance method with 'throws' or 'async'}} let _: KeyPath S> = \.init // expected-error {{static member 'init()' cannot be used on instance of type 'S'}} let _: KeyPath S> = \.init(val:) // expected-error {{static member 'init(val:)' cannot be used on instance of type 'S'}} let _: KeyPath = \.init(val: 2025) // expected-error {{static member 'init(val:)' cannot be used on instance of type 'S'}} let _: KeyPath S> = \S.Type.init let _: KeyPath S> = \S.Type.init(val:) let _: KeyPath = \S.Type.init(val: 2025) let _: KeyPath = \.init(val:2025).year let _ = \S.Type.init(val: 2025).nonisolatedNextYear() let _ = \S.Type.init()[0] let _ = \S.Type.init(val: 2025).nonisolatedNextYear().signum() let _ = \S.Type.init(val: 2025).nonisolatedNextYear().description let _: KeyPath = \S.consume() let _: AnyKeyPath = \S.add(this:) let _: PartialKeyPath = \S.add class E: Hashable { static func == (lhs: E, rhs: E) -> Bool { return lhs === rhs } func hash(into hasher: inout Hasher) { hasher.combine(ObjectIdentifier(self)) } private var storedClosure: (() -> Void)? func saveClosure(_ closure: @escaping () -> Void) { storedClosure = closure } } class NonhashableE {} struct BaseType { func foo(_ e: E) {} func foo(_ e: NonhashableE) {} } let hashableInstance = E() let nonhashableInstance = NonhashableE() let _ = \BaseType.foo(hashableInstance) let _ = \BaseType.foo(nonhashableInstance) // expected-error {{method argument of type 'NonhashableE' in a key path must be Hashable}} struct A { func foo() -> B { return B() } static func faz() -> B { return B() } } struct B { var bar: Int = 42 func baz() -> Int { return 42 } subscript(index: Int) -> Int { return index } } let _: KeyPath = \.foo.bar // expected-error {{type of expression is ambiguous without a type annotation}} let _: KeyPath = \.faz.bar // expected-error {{static member 'faz()' cannot be used on instance of type 'A'}} let _ = \A.foo.bar // expected-error {{type of expression is ambiguous without a type annotation}} let _ = \A.Type.faz.bar // expected-error {{type of expression is ambiguous without a type annotation}} let _: KeyPath = \.foo().bar let _: KeyPath = \.faz().bar let _ = \A.foo().bar let _ = \A.Type.faz().bar let _: KeyPath = \.faz().bar let _: KeyPath = \.foo().baz() let _: KeyPath = \.foo().baz() let _: KeyPath = \A.Type.faz()[0] } // https://github.com/apple/swift/issues/54961 protocol Zonk { func wargle() } typealias Blatz = (gloop: String, zoop: Zonk?) func f_54961(fleep: [Blatz]) { let _ = fleep.compactMap(\.zoop?.wargle) } // https://github.com/apple/swift/issues/52867 // Argument type 'KeyPath' does not conform to expected type 'Any' func test_keypath_in_any_context() { func foo(_: Any) {} foo(\String.count) // Ok } protocol PWithTypeAlias { typealias Key = WritableKeyPath static var fooKey: Key? { get } static var barKey: Key! { get } static var fazKey: Key?? { get } static var bazKey: Key?! { get } } func test_keypath_inference_with_optionals() { final class S : PWithTypeAlias { static var fooKey: Key? { return \.foo } static var barKey: Key! { return \.foo } static var fazKey: Key?? { return \.foo } static var bazKey: Key?! { return \.foo } var foo: Int? = nil } } // https://github.com/apple/swift/issues/53967 func f_53967() { struct S1 { subscript(x x: Int) -> Int { x } } _ = \S1.[5] // expected-error {{missing argument label 'x:' in call}} {{12-12=x: }} struct S2 { subscript(x x: Int) -> Int { x } // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(x:)')}} subscript(y y: Int) -> Int { y } // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(y:)')}} } _ = \S2.[5] // expected-error {{no exact matches in call to subscript}} struct S3 { subscript(x x: Int, y y: Int) -> Int { x } } _ = \S3.[y: 5, x: 5] // expected-error {{argument 'x' must precede argument 'y'}} struct S4 { subscript(x: (Int, Int)) -> Int { x.0 } } _ = \S4.[1, 4] // expected-error {{subscript expects a single parameter of type '(Int, Int)'}} {{12-12=(}} {{16-16=)}} // expected-error@-1 {{subscript index of type '(Int, Int)' in a key path must be Hashable}} } // https://github.com/apple/swift/issues/54718 // Ban keypaths with contextual root and without a leading dot. struct S_54718 { let property: [Int] = [] let kp1: KeyPath = \property.count // expected-error {{a Swift key path with contextual root must begin with a leading dot}}{{37-37=.}} let kp2: KeyPath = \.property.count // Ok let kp3: KeyPath = \S_54718.property.count // Ok func foo1(_: KeyPath = \property.count) {} // expected-error {{a Swift key path with contextual root must begin with a leading dot}}{{41-41=.}} func foo2(_: KeyPath = \.property.count) {} // Ok func foo3(_: KeyPath = \S_54718.property.count) {} // Ok func foo4(_: KeyPath) {} func useFoo4() { foo4(\property.count) // expected-error {{a Swift key path with contextual root must begin with a leading dot}}{{11-11=.}} foo4(\.property.count) // Ok foo4(\S_54718.property.count) // Ok } } func testKeyPathHole() { _ = \.x // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{8-8=<#Root#>}} _ = \.x.y // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{8-8=<#Root#>}} let _ : AnyKeyPath = \.x // expected-error@-1 {{'AnyKeyPath' does not provide enough context for root type to be inferred; consider explicitly specifying a root type}} {{25-25=<#Root#>}} let _ : AnyKeyPath = \.x.y // expected-error@-1 {{'AnyKeyPath' does not provide enough context for root type to be inferred; consider explicitly specifying a root type}} {{25-25=<#Root#>}} func f(_ i: Int) {} f(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{6-6=<#Root#>}} // expected-error@-1 {{cannot convert value of type 'KeyPath' to expected argument type 'Int'}} f(\.x.y) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{6-6=<#Root#>}} // expected-error@-1 {{cannot convert value of type 'KeyPath' to expected argument type 'Int'}} func provideValueButNotRoot(_ fn: (T) -> String) {} // expected-note 2 {{in call to function 'provideValueButNotRoot'}} provideValueButNotRoot(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} // expected-error@-1 {{generic parameter 'T' could not be inferred}} provideValueButNotRoot(\.x.y) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} // expected-error@-1 {{generic parameter 'T' could not be inferred}} provideValueButNotRoot(\String.foo) // expected-error {{value of type 'String' has no member 'foo'}} func provideKPValueButNotRoot(_ kp: KeyPath) {} provideKPValueButNotRoot(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} provideKPValueButNotRoot(\.x.y) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} provideKPValueButNotRoot(\String.foo) // expected-error@-1 {{value of type 'String' has no member 'foo'}} } func testMissingMember() { let _: KeyPath = \.foo // expected-error {{value of type 'String' has no member 'foo'}} let _: KeyPath = \.foo.bar // expected-error {{value of type 'String' has no member 'foo'}} let _: PartialKeyPath = \.foo // expected-error {{value of type 'String' has no member 'foo'}} let _: PartialKeyPath = \.foo.bar // expected-error {{value of type 'String' has no member 'foo'}} _ = \String.x.y // expected-error {{value of type 'String' has no member 'x'}} } // https://github.com/apple/swift/issues/48258 func testMemberAccessOnOptionalKeyPathComponent() { struct S1a { var b: S1b var b_opt: S1b? } struct S1b { var m: Int var c: S1c? } struct S1c { var d: Int } _ = \S1a.b_opt.m // expected-error@-1 {{value of optional type 'S1b?' must be unwrapped to refer to member 'm' of wrapped base type 'S1b'}} // expected-note@-2 {{chain the optional using '?' to access member 'm' only for non-'nil' base values}} {{17-17=?}} // expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{17-17=!}} // FIXME(diagnostics): Ideally there should be two errors here - one for `b_opt` and one for `c` but since there is // no contextual type it means that both `!` and `?` could work to reference `.d` and that creates ambiguity which // is not possible to diagnose at the moment. _ = \S1a.b_opt.c.d // expected-error@-1 {{value of optional type 'S1b?' must be unwrapped to refer to member 'c' of wrapped base type 'S1b'}} // expected-note@-2 {{chain the optional using '?' to access member 'c' only for non-'nil' base values}} {{17-17=?}} let _: KeyPath = \S1a.b_opt.c.d // expected-error@-1 {{value of optional type 'S1b?' must be unwrapped to refer to member 'c' of wrapped base type 'S1b'}} // expected-note@-2 {{chain the optional using '?' to access member 'c' only for non-'nil' base values}} {{40-40=?}} // expected-error@-3 {{value of optional type 'S1c?' must be unwrapped to refer to member 'd' of wrapped base type 'S1c'}} // expected-note@-4 {{chain the optional using '?' to access member 'd' only for non-'nil' base values}} {{42-42=?}} // expected-note@-5 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{42-42=!}} _ = \S1a.b_opt?.c.d // expected-error@-1 {{value of optional type 'S1c?' must be unwrapped to refer to member 'd' of wrapped base type 'S1c'}} // expected-note@-2 {{chain the optional using '?' to access member 'd' only for non-'nil' base values}} {{20-20=?}} _ = \S1a.b.c.d // expected-error@-1 {{value of optional type 'S1c?' must be unwrapped to refer to member 'd' of wrapped base type 'S1c'}} // expected-note@-2 {{chain the optional using '?' to access member 'd' only for non-'nil' base values}} {{15-15=?}} // expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{15-15=!}} struct S2 { subscript(_ x: Int) -> String? { get {} } } struct S3 { struct Nested { var foo = "" } } \String?.count // expected-error@-1 {{value of optional type 'String?' must be unwrapped to refer to member 'count' of wrapped base type 'String'}} // expected-note@-2 {{use unwrapped type 'String' as key path root}} {{4-11=String}} \Optional.count // expected-error@-1 {{value of optional type 'Optional' must be unwrapped to refer to member 'count' of wrapped base type 'String'}} // expected-note@-2 {{use unwrapped type 'String' as key path root}} {{4-20=String}} \S2.[5].count // expected-error@-1 {{value of optional type 'String?' must be unwrapped to refer to member 'count' of wrapped base type 'String'}} // expected-note@-2 {{chain the optional using '?' to access member 'count' only for non-'nil' base values}}{{10-10=?}} // expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{10-10=!}} \S3.Nested?.foo.count // expected-error@-1 {{value of optional type 'S3.Nested?' must be unwrapped to refer to member 'foo' of wrapped base type 'S3.Nested'}} // expected-note@-2 {{use unwrapped type 'S3.Nested' as key path root}}{{4-14=S3.Nested}} \(Int, Int)?.0 // expected-error@-1 {{value of optional type '(Int, Int)?' must be unwrapped to refer to member '0' of wrapped base type '(Int, Int)'}} // expected-note@-2 {{use unwrapped type '(Int, Int)' as key path root}}{{4-15=(Int, Int)}} func kp(_: KeyPath) {} kp(\.count) // expected-error {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'count' of unwrapped type 'String'}} let _ : KeyPath = \.count // expected-error {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'count' of unwrapped type 'String'}} let _ : KeyPath = \.utf8.count // expected-error@-1 {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'utf8' of unwrapped type 'String'}} } func testSyntaxErrors() { _ = \. ; // expected-error{{expected member name following '.'}} _ = \.a ; _ = \[a ; _ = \[a]; _ = \? ; _ = \! ; _ = \. ; // expected-error{{expected member name following '.'}} _ = \.a ; _ = \[a ; _ = \[a,; _ = \[a:; _ = \[a]; _ = \.a?; _ = \.a!; _ = \A ; _ = \A, ; _ = \A< ; _ = \A. ; // expected-error{{expected member name following '.'}} _ = \A.a ; _ = \A[a ; _ = \A[a]; _ = \A? ; _ = \A! ; _ = \A. ; // expected-error{{expected member name following '.'}} _ = \A.a ; _ = \A[a ; _ = \A[a,; _ = \A[a:; _ = \A[a]; _ = \A.a?; _ = \A.a!; } // https://github.com/apple/swift/issues/56996 func f_56996() { _ = \Int.byteSwapped.signum() _ = \Int.byteSwapped.init() // expected-error {{static member 'init()' cannot be used on instance of type 'Int'}} _ = \Int // expected-error {{key path must have at least one component}} _ = \Int? // expected-error {{key path must have at least one component}} _ = \Int. // expected-error {{invalid component of Swift key path}} // expected-error@-1 {{expected member name following '.'}} } // https://github.com/apple/swift/issues/55805 // Key-path missing optional crashes compiler: Inactive constraints left over? func f_55805() { let _: KeyPath = \.utf8.count // expected-error@-1 {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'utf8' of unwrapped type 'String'}} // expected-error@-2 {{cannot assign value of type 'KeyPath' to type 'KeyPath'}} // expected-note@-3 {{arguments to generic parameter 'Value' ('Int' and 'Int?') are expected to be equal}} } // rdar://74711236 - crash due to incorrect member access in key path func rdar74711236() { struct S { var arr: [V] = [] } struct V : Equatable { } enum Type { case store } struct Context { func supported() -> [Type] { return [] } } func test(context: Context?) { var s = S() s.arr = { if let type = context?.store { // expected-error {{value of type 'Context' has no member 'store'}} // `isSupported` should be an invalid declaration to trigger a crash in `map(\.option)` let isSupported = context!.supported().contains(type) return (isSupported ? [type] : []).map(\.option) } return [] }() } } extension String { var filterOut : (Self) throws -> Bool { { $0.contains("a") } } } func test_kp_as_function_mismatch() { let a : [String] = [ "asd", "bcd", "def" ] let _ : (String) -> Bool = \.filterOut // expected-error{{key path value type '(String) throws -> Bool' cannot be converted to contextual type 'Bool'}} _ = a.filter(\.filterOut) // expected-error{{key path value type '(String) throws -> Bool' cannot be converted to contextual type 'Bool'}} let _ : (String) -> Bool = \String.filterOut // expected-error{{key path value type '(String) throws -> Bool' cannot be converted to contextual type 'Bool'}} _ = a.filter(\String.filterOut) // expected-error{{key path value type '(String) throws -> Bool' cannot be converted to contextual type 'Bool'}} } func test_partial_keypath_inference() { // rdar://problem/34144827 struct S { var i: Int = 0 } enum E { case A(pkp: PartialKeyPath) } _ = E.A(pkp: \.i) // Ok // rdar://problem/36472188 class ThePath { var isWinding:Bool? } func walk(aPath: T, forKey: PartialKeyPath) {} func walkThePath(aPath: ThePath, forKey: PartialKeyPath) {} func test(path: ThePath) { walkThePath(aPath: path, forKey: \.isWinding) // Ok walk(aPath: path, forKey: \.isWinding) // Ok } } // https://github.com/apple/swift/issues/56854 func f_56854() { struct S1 {} struct S2 {} func reproduceA() -> [(S1, S2)] { [ (true, .init(), S2.init()) // expected-error {{cannot infer contextual base in reference to member 'init'}} ] .filter(\.0) // expected-error {{value of type 'Any' has no member '0'}} // expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} .prefix(3) .map { ($0.1, $0.2) } // expected-error {{value of type 'Any' has no member '1'}} expected-error{{value of type 'Any' has no member '2'}} // expected-note@-1 2 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} } func reproduceB() -> [(S1, S2)] { [ (true, S1.init(), .init()) // expected-error {{cannot infer contextual base in reference to member 'init'}} ] .filter(\.0) // expected-error {{value of type 'Any' has no member '0'}} // expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} .prefix(3) .map { ($0.1, $0.2) } // expected-error {{value of type 'Any' has no member '1'}} expected-error{{value of type 'Any' has no member '2'}} // expected-note@-1 2 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} } func reproduceC() -> [(S1, S2)] { [ (true, .init(), .init()) // expected-error 2 {{cannot infer contextual base in reference to member 'init'}} ] .filter(\.0) // expected-error {{value of type 'Any' has no member '0'}} // expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} .prefix(3) .map { ($0.1, $0.2) } // expected-error {{value of type 'Any' has no member '1'}} expected-error{{value of type 'Any' has no member '2'}} // expected-note@-1 2 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}} } } // rdar://93103421 - Key path type inference doesn't work when the context is an existential type with a key-path superclass extension KeyPath : P { var member: String { "" } } func test_keypath_inference_from_existentials() { struct A : P { var member: String { "a" } var other: T { fatalError() } } func test(_: any P & KeyPath, U>, _: T) { } let _: any P & KeyPath, String> = \.member // Ok let _: (any P & KeyPath, String>) = \.member // Ok test(\.other, 42) // Ok test(\.member, "") // Ok } // rdar://116376651 - key path type is bound before context is fully resolved. func keypath_to_func_conversion_as_arg_to_overloaded_func() { struct Data { var value: Int = 42 } func test(_: S, _: (S.Element) -> Int) {} func test(_: C, _: (C.Element) -> Int) {} func test(arr: [Data]) { test(arr, \Data.value) // Ok } } // https://github.com/apple/swift/issues/55436 func test_keypath_coercion_to_function() { struct User { let email: String } let users = [User]() let fn = \User.email as (User) -> String // Ok _ = users.map(fn) // Ok } func test_keypath_application_with_composition(v: String, kp: any KeyPath & PP) { _ = v[keyPath: kp] // Ok } func test_leading_dot_key_path_without_context() { func test(_: AnyKeyPath?) {} test(\.utf8) // expected-error@-1 {{cannot infer key path type from context; consider explicitly specifying a root type}} } func keypath_function_transitive_conversions() { class Base { var derived: Derived { Derived() } var base: Base { Base() } var int: Int { 0 } } class Derived: Base { override var derived: Derived { Derived() } override var base: Base { Base() } } struct S { var base: Base { Base() } var derived: Derived { Derived() } } let _: (Base) -> Base = \Base.base let _: (Base) -> Base = \Derived.base let _: (Base) -> Base? = \Base?.self let _: (Base) -> Base? = \Base?.self?.base // FIXME: This error text is bogus due to KeyPath base covariance. let _: (Base?) -> Base = \Base.base // expected-error {{value of optional type 'Base?' must be unwrapped to refer to member 'base' of wrapped base type 'Base'}} expected-note {{use unwrapped type 'Base' as key path root}} {{29-33=Base}} let _: (Base) -> Base = \.base let _: (Base) -> Base = \Base.derived let _: (Base) -> Base = \.derived let _: (Base) -> Int = \Base.int let _: (Derived) -> Base = \Base.base let _: (Derived) -> Base = \Derived.base let _: (Derived) -> Base = \.base let _: (Derived) -> Int = \Base.int let _: (Derived) -> Int = \Derived.int let _: (Derived) -> Int = \.int let _: (Base) async throws -> Int = \.int let _: (Derived) -> Base = \Base.derived let _: (S) -> Base = \.derived let _: (S) -> Derived = \.base // expected-error {{key path value type 'Base' cannot be converted to contextual type 'Derived'}} } func testMinimalKeypaths(_ arr: [Int?]) { // These keypaths don't have any components that need 'resolving'. We still // should not eagerly turn them into keypaths; they should get converted to // functions instead let _: [Int] = arr.compactMap(\.self) let _: [Int] = arr.compactMap(\.?) let _: [Int] = arr.map(\.!) } func testKeyPathInout() { let _: (inout String) -> Int = \.count let _: (inout String) -> Int = \String.count let _: (inout String) -> Int? = \.count func takesInout(_: (inout String) -> Int) {} func takesInoutOpt(_: (inout String) -> Int?) {} takesInout(\.count) takesInout(\String.count) takesInoutOpt(\.count) takesInoutOpt(\String.count) }