mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This generalization enables curried functions with generic parameters coming from the initial declaration to be printed with the archetype's upperbound rather than '_' unresolved type. As an added benefit, T.self and T.Type for generic parameters now get shown as the upperbound of the generic parameter provided
377 lines
9.9 KiB
Swift
377 lines
9.9 KiB
Swift
// RUN: %batch-code-completion
|
|
|
|
struct Point {
|
|
var x: Int
|
|
var y: Int
|
|
}
|
|
|
|
struct Rectangle {
|
|
var topLeft: Point
|
|
var bottomRight: Point
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct Lens<T> {
|
|
var obj: T
|
|
init(_ obj: T) { self.obj = obj }
|
|
|
|
subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
|
|
get { return Lens<U>(obj[keyPath: member]) }
|
|
set { obj[keyPath: member] = newValue.obj }
|
|
}
|
|
}
|
|
|
|
func testMembersPostfix1(r: Lens<Rectangle>) {
|
|
r#^testMembersPostfix1^#
|
|
}
|
|
|
|
// testMembersPostfix1-DAG: Decl[Subscript]/CurrNominal: [{#dynamicMember: WritableKeyPath<Rectangle, U>#}][#Lens<U>#];
|
|
|
|
// testMembersPostfix1-DAG: Decl[InstanceVar]/CurrNominal: .topLeft[#Lens<Point>#];
|
|
// testMembersPostfix1-DAG: Decl[InstanceVar]/CurrNominal: .bottomRight[#Lens<Point>#];
|
|
|
|
func testMembersDot1(r: Lens<Rectangle>) {
|
|
r.#^testMembersDot1^#
|
|
}
|
|
// testMembersDot1-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Lens<Point>#];
|
|
// testMembersDot1-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Lens<Point>#];
|
|
|
|
func testMembersDot2(r: Lens<Rectangle>) {
|
|
r.topLeft.#^testMembersDot2^#
|
|
}
|
|
|
|
// testMembersDot2-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens<Int>#];
|
|
// testMembersDot2-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens<Int>#];
|
|
|
|
@dynamicMemberLookup
|
|
struct MultipleSubscript {
|
|
subscript<U>(dynamicMember member: KeyPath<Point, U>) -> U {
|
|
return Point(x: 1, y: 2)[keyPath: member]
|
|
}
|
|
|
|
subscript<U>(dynamicMember member: KeyPath<Rectangle, U>) -> U {
|
|
return Rectangle(topLeft: Point(x: 0, y: 0), bottomRight: Point(x: 1, y: 1))[keyPath: member]
|
|
}
|
|
}
|
|
|
|
func testMultipleSubscript1(r: MultipleSubscript) {
|
|
r.#^testMultipleSubscript1^#
|
|
}
|
|
|
|
// testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
// testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Point#];
|
|
// testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Point#];
|
|
|
|
@dynamicMemberLookup
|
|
class Base<T> {
|
|
var t: T
|
|
init(_ t: T) { self.t = t }
|
|
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
|
|
return t[keyPath: member]
|
|
}
|
|
}
|
|
|
|
class Inherit1<T>: Base<T> {}
|
|
|
|
func testInherit1(r: Inherit1<Point>) {
|
|
r.#^testInherit1^#
|
|
}
|
|
// testInherit1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testInherit1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
|
|
class Inherit2<T, U>: Base<T> {
|
|
var u: U
|
|
init(_ t: T, _ u: U) { super.init(t); self.u = u }
|
|
subscript<V>(dynamicMember member: KeyPath<U, V>) -> V {
|
|
return u[keyPath: member]
|
|
}
|
|
}
|
|
|
|
func testInherit2(r: Inherit2<Point, Rectangle>) {
|
|
r.#^testInherit2^#
|
|
}
|
|
// testInherit2-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testInherit2-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
// testInherit2-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Point#];
|
|
// testInherit2-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Point#];
|
|
|
|
class Shadow1<T>: Base<T> {
|
|
var x: String = ""
|
|
}
|
|
|
|
func testShadow1(r: Shadow1<Point>) {
|
|
r.#^testShadow1^#
|
|
}
|
|
// testShadow1-NOT: x[#Int#];
|
|
// testShadow1: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
// testShadow1-NOT: x[#Int#];
|
|
// testShadow1: Decl[InstanceVar]/CurrNominal: x[#String#];
|
|
|
|
@dynamicMemberLookup
|
|
protocol P {
|
|
associatedtype T
|
|
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U
|
|
}
|
|
|
|
func testGeneric1<G: P>(r: G) where G.T == Point {
|
|
r.#^testGeneric1^#
|
|
}
|
|
// testGeneric1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testGeneric1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
|
|
|
|
func testGenericUnderconstrained1<G: P>(r: G) {
|
|
r.#^testGenericUnderconstrained1^#
|
|
}
|
|
// testGenericUnderconstrained1-NOT: CurrNominal
|
|
// testGenericUnderconstrained1: Keyword[self]/CurrNominal: self[#P#];
|
|
// testGenericUnderconstrained1-NOT: CurrNominal
|
|
|
|
func testExistential1(r: P) {
|
|
r.#^testExistential1^#
|
|
}
|
|
|
|
// testExistential1-NOT: CurrNominal
|
|
// testExistential1: Keyword[self]/CurrNominal: self[#any P#];
|
|
// testExistential1-NOT: CurrNominal
|
|
|
|
@dynamicMemberLookup
|
|
protocol E {
|
|
subscript<U>(dynamicMember member: KeyPath<Point, U>) -> U
|
|
}
|
|
|
|
func testExistential2(r: E) {
|
|
r.#^testExistential2^#
|
|
}
|
|
// testExistential2-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testExistential2-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
|
|
struct WithP<T>: P {
|
|
var t: T
|
|
init(t: T) { self.t = t }
|
|
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
|
|
return t[keyPath: member]
|
|
}
|
|
}
|
|
|
|
func testProtocolConform1(r: WithP<Point>) {
|
|
r.#^testProtocolConform1^#
|
|
}
|
|
// testProtocolConform1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testProtocolConform1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
|
|
@dynamicMemberLookup
|
|
struct OnSelf {
|
|
subscript<U>(dynamicMember member: KeyPath<Point, U>) -> U {
|
|
return Point(x: 0, y: 1)[keyPath: member]
|
|
}
|
|
|
|
func test() {
|
|
self.#^OnSelf1^#
|
|
}
|
|
}
|
|
// OnSelf1-DAG: Decl[InstanceMethod]/CurrNominal: test()[#Void#];
|
|
// OnSelf1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// OnSelf1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
|
|
protocol HalfRect {
|
|
var topLeft: Point
|
|
}
|
|
|
|
extension Lens where T: HalfRect {
|
|
func testSelfExtension1() {
|
|
self.#^testSelfExtension1^#
|
|
}
|
|
}
|
|
// testSelfExtension1-NOT: bottomRight
|
|
// testSelfExtension1: Decl[InstanceVar]/CurrNominal: topLeft[#Lens<Point>#];
|
|
// testSelfExtension1-NOT: bottomRight
|
|
|
|
struct Invalid1 {
|
|
subscript<U>(dynamicMember member: KeyPath<Rectangle, U>) -> U {
|
|
return Point(x: 0, y: 1)[keyPath: member]
|
|
}
|
|
}
|
|
func testInvalid1(r: Invalid1) {
|
|
r.#^testInvalid1^#
|
|
}
|
|
// testInvalid1-NOT: topLeft
|
|
|
|
@dynamicMemberLookup
|
|
struct Invalid2 {
|
|
subscript<U>(dynamicMember: KeyPath<Rectangle, U>) -> U {
|
|
return Point(x: 0, y: 1)[keyPath: dynamicMember]
|
|
}
|
|
}
|
|
func testInvalid2(r: Invalid2) {
|
|
r.#^testInvalid2^#
|
|
}
|
|
// testInvalid2-NOT: topLeft
|
|
|
|
@dynamicMemberLookup
|
|
struct Invalid3 {
|
|
subscript<U>(dynamicMember member: Rectangle) -> U {
|
|
return Point(x: 0, y: 1)[keyPath: member]
|
|
}
|
|
}
|
|
func testInvalid3(r: Invalid3) {
|
|
r.#^testInvalid3^#
|
|
}
|
|
// testInvalid3-NOT: topLeft
|
|
|
|
struct NotKeyPath<T, U> {}
|
|
|
|
@dynamicMemberLookup
|
|
struct Invalid4 {
|
|
subscript<U>(dynamicMember member: NotKeyPath<Rectangle, U>) -> U {
|
|
return Point(x: 0, y: 1)[keyPath: member]
|
|
}
|
|
}
|
|
func testInvalid4(r: Invalid4) {
|
|
r.#^testInvalid4^#
|
|
}
|
|
// testInvalid4-NOT: topLeft
|
|
|
|
struct Gen1<T> {
|
|
var foo: T
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct GenericRoot<T> {
|
|
subscript<U>(dynamicMember member: KeyPath<Gen1<T>, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func testGenericRoot1(r: GenericRoot<Point>) {
|
|
r.#^testGenericRoot1^#
|
|
}
|
|
// testGenericRoot1: Decl[InstanceVar]/CurrNominal: foo[#Int#];
|
|
|
|
@dynamicMemberLookup
|
|
struct GenericResult<T> {
|
|
subscript<U>(dynamicMember member: KeyPath<T, Gen1<U>>) -> GenericResult<U> {
|
|
fatalError()
|
|
}
|
|
}
|
|
struct BoxedCircle {
|
|
var center: Gen1<Point>
|
|
var radius: Gen1<Int>
|
|
}
|
|
func testGenericResult1(r: GenericResult<BoxedCircle>) {
|
|
r.#^testGenericResult1^#
|
|
}
|
|
// FIXME: the type should be 'GenericResult<Point>'
|
|
// testGenericResult1-DAG: Decl[InstanceVar]/CurrNominal: center[#Gen1<Point>#]; name=center
|
|
// testGenericResult1-DAG: Decl[InstanceVar]/CurrNominal: radius[#Gen1<Int>#]; name=radius
|
|
|
|
class C {
|
|
var someUniqueName: Int = 0
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct AnyObjectRoot {
|
|
subscript<U>(dynamicMember member: KeyPath<AnyObject, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func testAnyObjectRoot1(r: AnyObjectRoot) {
|
|
r.#^testAnyObjectRoot1^#
|
|
}
|
|
// Do not do find via AnyObject dynamic lookup.
|
|
// testAnyObjectRoot1-NOT: someUniqueName
|
|
|
|
func testNested1(r: Lens<Lens<Point>>) {
|
|
r.#^testNested1^#
|
|
// FIXME: The type should be 'Lens<Lens<Int>>'
|
|
// testNested1-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens<Int>#];
|
|
// testNested1-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens<Int>#];
|
|
}
|
|
|
|
func testNested2(r: Lens<Lens<Lens<Point>>>) {
|
|
r.#^testNested2^#
|
|
// FIXME: The type should be 'Lens<Lens<Lens<Int>>>'
|
|
// testNested2-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens<Int>#];
|
|
// testNested2-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens<Int>#];
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct Recurse<T> {
|
|
var obj: T
|
|
init(_ obj: T) { self.obj = obj }
|
|
|
|
subscript<U>(dynamicMember member: KeyPath<Recurse<T>, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func testCycle1(r: Recurse<Point>) {
|
|
r.#^testCycle1^#
|
|
// testCycle1: Begin completions
|
|
// testCycle1-NOT: x[#Int#]
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct CycleA<T> {
|
|
var fromA: Int
|
|
subscript<U>(dynamicMember member: KeyPath<CycleB<T>, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
@dynamicMemberLookup
|
|
struct CycleB<T> {
|
|
var fromB: Int
|
|
subscript<U>(dynamicMember member: KeyPath<CycleC<T>, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
@dynamicMemberLookup
|
|
struct CycleC<T> {
|
|
var fromC: Int
|
|
subscript<U>(dynamicMember member: KeyPath<CycleA<T>, U>) -> Int {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func testCycle2(r: CycleA<Point>) {
|
|
r.#^testCycle2^#
|
|
// testCycle2: Begin completions
|
|
}
|
|
|
|
protocol DynamicLookupProto {
|
|
associatedtype Content
|
|
}
|
|
extension DynamicLookupProto {
|
|
subscript<T>(dynamicMember key: KeyPath<Content, T>) -> T {
|
|
fatalError()
|
|
}
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
struct DynamicLookupConcrete : DynamicLookupProto {
|
|
typealias Content = Point
|
|
}
|
|
|
|
func testSubscriptOnProtocolExtension(dyn: DynamicLookupConcrete) {
|
|
dyn.#^testSubscriptOnProtocolExt^#
|
|
// testSubscriptOnProtocolExt: Keyword[self]/CurrNominal: self[#DynamicLookupConcrete#];
|
|
// testSubscriptOnProtocolExt: Decl[InstanceVar]/CurrNominal: x[#Int#];
|
|
// testSubscriptOnProtocolExt: Decl[InstanceVar]/CurrNominal: y[#Int#];
|
|
}
|
|
|
|
// https://github.com/swiftlang/swift/issues/77035
|
|
@dynamicMemberLookup
|
|
struct HasSendableKeyPath<T> {
|
|
subscript<U>(dynamicMember keyPath: KeyPath<T, U> & Sendable) -> HasSendableKeyPath<U> {
|
|
fatalError()
|
|
}
|
|
}
|
|
|
|
func testSendableKeyPath(_ x: HasSendableKeyPath<Point>) {
|
|
x.#^SENDABLE_KEYPATH_POINT^#
|
|
// SENDABLE_KEYPATH_POINT-DAG: Decl[InstanceVar]/CurrNominal: x[#HasSendableKeyPath<Int>#]; name=x
|
|
// SENDABLE_KEYPATH_POINT-DAG: Decl[InstanceVar]/CurrNominal: y[#HasSendableKeyPath<Int>#]; name=y
|
|
}
|