// RUN: %target-swift-frontend -typecheck -verify %S/Inputs/keypath.swift -primary-file %s struct S { let i: Int init() { let _: WritableKeyPath = \.i // no error for Swift 3/4 S()[keyPath: \.i] = 1 // expected-error@-1 {{cannot assign through subscript: function call returns immutable value}} } } func test() { let _: WritableKeyPath = \.i // no error for Swift 3/4 C()[keyPath: \.i] = 1 // warning on write with literal keypath // expected-warning@-1 {{forming a writable keypath to property}} let _ = C()[keyPath: \.i] // no warning for a read } // SR-7339 class Some { // expected-note {{'V' declared as parameter to type 'Some'}} init(keyPath: KeyPath Void)?>) { } } class Demo { var here: (() -> Void)? } let some = Some(keyPath: \Demo.here) // expected-error@-1 {{cannot convert value of type 'KeyPath Void)?>' to expected argument type 'KeyPath Void)?>'}} // expected-note@-2 {{arguments to generic parameter 'Value' ('(() -> Void)?' and '((V) -> Void)?') are expected to be equal}} // expected-error@-3 {{generic parameter 'V' could not be inferred}} // expected-note@-4 {{explicitly specify the generic arguments to fix this issue}} // SE-0249 func testFunc() { let _: (S) -> Int = \.i _ = ([S]()).map(\.i) _ = \S.init // expected-error {{key path cannot refer to initializer 'init()'}} _ = ([S]()).map(\.init) // expected-error {{key path cannot refer to initializer 'init()'}} let kp = \S.i let _: KeyPath = kp // works, because type defaults to KeyPath nominal let f = \S.i let _: (S) -> Int = f // expected-error {{cannot convert value of type 'KeyPath' to specified type '(S) -> Int'}} } // SR-11234 public extension Array { func sorted>(by keyPath: K) -> Array { let sortedA = self.sorted(by: { $0[keyPath: keyPath] < $1[keyPath: keyPath] }) return sortedA } var i: Int { 0 } } func takesVariadicFnWithGenericRet(_ fn: (S...) -> T) {} // rdar://problem/59445486 func testVariadicKeypathAsFunc() { // These are okay, the base type of the KeyPath is inferred to be [S]. let _: (S...) -> Int = \.i let _: (S...) -> Int = \Array.i takesVariadicFnWithGenericRet(\.i) takesVariadicFnWithGenericRet(\Array.i) // These are not okay, the KeyPath should have a base that matches the // internal parameter type of the function, i.e [S]. let _: (S...) -> Int = \S.i // expected-error {{key path value type 'S' cannot be converted to contextual type '[S]'}} takesVariadicFnWithGenericRet(\S.i) // expected-error {{key path value type 'S' cannot be converted to contextual type '[S]'}} } // rdar://problem/54322807 struct X { init(foo: KeyPath) { } init(foo: KeyPath) { } } struct Wibble { var boolProperty = false } struct Bar { var optWibble: Wibble? = nil } class Foo { var optBar: Bar? = nil } func testFoo(_: T) { let _: X = .init(foo: \.optBar!.optWibble?.boolProperty) } // rdar://problem/56131416 enum Rdar56131416 { struct Pass {} static func f(_ value: T, _ prop: KeyPath) -> Pass { fatalError() } struct Fail {} static func f(_ value: T, _ transform: (T) -> U) -> Fail { fatalError() } static func takesCorrectType(_: Pass) {} } func rdar56131416() { // This call should not be ambiguous. let result = Rdar56131416.f(1, \.magnitude) // no-error // This type should be selected correctly. Rdar56131416.takesCorrectType(result) } func test_mismatch_with_contextual_optional_result() { struct A { init(_ data: T, keyPath: KeyPath) {} } struct B { var arr: [Int] = [] } let _ = A(B(), keyPath: \.arr) // expected-error@-1 {{key path value type '[Int]' cannot be converted to contextual type '[Int]?'}} }