mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
`KeyPath` types now have conformance requirements placed on their `Root` and `Value` types which need to be checked even when there is a key path to function conversion involved, otherwise the solver would be accepting invalid code. Note that without function conversion the requirements come from a type opened during assignment - https://github.com/swiftlang/swift/pull/80081/files. Resolves: https://github.com/swiftlang/swift/issues/84150
84 lines
2.5 KiB
Swift
84 lines
2.5 KiB
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
public protocol P: ~Copyable {
|
|
var protocolProp: String { get }
|
|
}
|
|
|
|
public struct NC: ~Copyable {
|
|
var data: [Int] = []
|
|
var next: Box<NC>? = nil
|
|
}
|
|
|
|
public struct M<T: ~Copyable & P>: ~Copyable {
|
|
var nc: NC
|
|
var string: String
|
|
let ncg: T
|
|
init(_ t: consuming T) {
|
|
self.string = ""
|
|
self.nc = NC()
|
|
self.ncg = t
|
|
}
|
|
}
|
|
|
|
public class Box<Wrapped: ~Copyable> {
|
|
var wrapped: Wrapped
|
|
init(_ t: consuming Wrapped) { self.wrapped = t }
|
|
func with<T: ~Copyable>(_ op: (borrowing Wrapped)->T) -> T { op(wrapped) }
|
|
}
|
|
|
|
class A {
|
|
var b: B
|
|
init(_ b: consuming B) { self.b = b }
|
|
}
|
|
struct B: ~Copyable {
|
|
var c: C
|
|
}
|
|
struct C {
|
|
var d: Int
|
|
}
|
|
|
|
// rdar://109287447
|
|
public func testKeypath<V: ~Copyable>(m: consuming M<V>) {
|
|
_ = m[keyPath: \.nc]
|
|
// expected-error@-1 {{key path cannot refer to noncopyable type 'M<V>'}}
|
|
// expected-error@-2 {{key path cannot refer to noncopyable type 'NC'}}
|
|
_ = m[keyPath: \.nc.data]
|
|
// expected-error@-1 {{key path cannot refer to noncopyable type 'M<V>'}}
|
|
_ = m[keyPath: \.ncg]
|
|
// expected-error@-1 {{key path cannot refer to noncopyable type 'M<V>'}}
|
|
// expected-error@-2 {{key path cannot refer to noncopyable type 'V'}}
|
|
_ = m[keyPath: \.ncg.protocolProp]
|
|
// expected-error@-1 {{key path cannot refer to noncopyable type 'M<V>'}}
|
|
_ = m[keyPath: \.string]
|
|
// expected-error@-1 {{key path cannot refer to noncopyable type 'M<V>'}}
|
|
|
|
let b = Box(NC())
|
|
_ = b.with(\.data) // expected-error {{key path cannot refer to noncopyable type 'NC'}}
|
|
_ = b.with(\.next) // expected-error {{key path cannot refer to noncopyable type 'NC'}}
|
|
_ = b.with(\.next?.wrapped) // expected-error 2 {{key path cannot refer to noncopyable type 'NC'}}
|
|
_ = b.with(\.next!.wrapped.data) // expected-error {{key path cannot refer to noncopyable type 'NC'}}
|
|
}
|
|
|
|
// rdar://109162739
|
|
func testKeypath2(_ someA: A) -> Int {
|
|
let kp: KeyPath<A, Int> = \A.b.c.d // expected-error {{key path cannot refer to noncopyable type 'B'}}
|
|
return someA[keyPath: kp]
|
|
}
|
|
func testAsFunc(_ someA: A) -> Int {
|
|
let fn: (A) -> Int = \A.b.c.d // expected-error {{key path cannot refer to noncopyable type 'B'}}
|
|
return fn(someA)
|
|
}
|
|
|
|
// https://github.com/swiftlang/swift/issues/84150
|
|
func testKeyPathToFunctionConversion() {
|
|
struct HasID: ~Copyable {
|
|
let id: Int
|
|
}
|
|
|
|
func map(_ operation: (consuming HasID) -> Int) {}
|
|
|
|
map(\.id) // expected-error {{key path cannot refer to noncopyable type 'HasID'}}
|
|
|
|
let _: (consuming HasID) -> Int = \.id // expected-error {{key path cannot refer to noncopyable type 'HasID'}}
|
|
}
|