blob: a6a9236c5369f0c408eaff010c3f864f7e157a53 [file] [log] [blame]
// RUN: %target-typecheck-verify-swift
// Tests for typealias inside protocols
protocol Bad {
associatedtype X<T> // expected-error {{associated types may not have a generic parameter list}}
typealias Y<T> // expected-error {{expected '=' in type alias declaration}}
}
protocol Col {
associatedtype Elem
typealias E = Elem?
var elem: Elem { get }
}
protocol CB {
associatedtype C : Col
// Self at top level
typealias S = Self
func cloneDefinitely() -> S
// Self in bound generic position
typealias OS = Self?
func cloneMaybe() -> OS
// Associated type of archetype
typealias E = C.Elem
func setIt(_ element: E)
// Typealias of archetype
typealias EE = C.E
func setItSometimes(_ element: EE)
// Associated type in bound generic position
typealias OE = C.Elem?
func setItMaybe(_ element: OE)
// Complex type expression
typealias FE = (C) -> (C.Elem) -> Self
func teleport(_ fn: FE)
}
// Generic signature requirement involving protocol typealias
func go1<T : CB, U : Col>(_ col: U, builder: T) where U.Elem == T.E { // OK
builder.setIt(col.elem)
}
func go2<T : CB, U : Col>(_ col: U, builder: T) where U.Elem == T.C.Elem { // OK
builder.setIt(col.elem)
}
// Test for same type requirement with typealias == concrete
func go3<T : CB>(_ builder: T) where T.E == Int {
builder.setIt(1)
}
// Test for conformance to protocol with associatedtype and another with
// typealias with same name
protocol MyIterator {
associatedtype Elem
func next() -> Elem?
}
protocol MySeq {
associatedtype I : MyIterator
typealias Elem = Self.I.Elem
func makeIterator() -> I
func getIndex(_ i: Int) -> Elem
func first() -> Elem
}
extension MySeq where Self : MyIterator {
func makeIterator() -> Self {
return self
}
}
func plusOne<S: MySeq>(_ s: S, i: Int) -> Int where S.Elem == Int {
return s.getIndex(i) + 1
}
struct OneIntSeq: MySeq, MyIterator {
let e : Float
func next() -> Float? {
return e
}
func getIndex(_ i: Int) -> Float {
return e
}
}
protocol MyIntIterator {
typealias Elem = Int
}
struct MyIntSeq : MyIterator, MyIntIterator {
func next() -> Elem? {
return 0
}
}
protocol MyIntIterator2 {}
extension MyIntIterator2 {
typealias Elem = Int
}
struct MyIntSeq2 : MyIterator, MyIntIterator2 {
func next() -> Elem? {
return 0
}
}
// test for conformance correctness using typealias in extension
extension MySeq {
func first() -> Elem {
return getIndex(0)
}
}
// Specific diagnosis for trying to use complex typealiases in generic constraints
protocol P1 {
associatedtype A
typealias F = (A) -> ()
}
protocol P2 {
associatedtype B
}
func go3<T : P1, U : P2>(_ x: T) -> U where T.F == U.B {
}
// Specific diagnosis for things that look like Swift 2.x typealiases
protocol P3 {
typealias T // expected-error {{type alias is missing an assigned type; use 'associatedtype' to define an associated type requirement}}
typealias U : P2 // expected-error {{type alias is missing an assigned type; use 'associatedtype' to define an associated type requirement}}
}
// Test for not crashing on recursive aliases
protocol Circular {
typealias Y = Self.Y // expected-error {{type alias 'Y' is not a member type of 'Self'}}
typealias Y2 = Y2 // expected-error {{type alias 'Y2' references itself}}
// expected-note@-1 {{type declared here}}
typealias Y3 = Y4 // expected-note {{type declared here}}
typealias Y4 = Y3 // expected-error {{type alias 'Y3' references itself}}
}
// Qualified and unqualified references to protocol typealiases from concrete type
protocol P5 {
associatedtype A
typealias X = Self
typealias T1 = Int
typealias T2 = A
var a: T2 { get }
}
protocol P6 {
typealias A = Int
typealias B = Self
}
struct T5 : P5 {
// This is OK -- the typealias is fully concrete
var a: P5.T1 // OK
// Invalid -- cannot represent associated type of existential
var v2: P5.T2 // expected-error {{type alias 'T2' can only be used with a concrete type or generic parameter base}}
var v3: P5.X // expected-error {{type alias 'X' can only be used with a concrete type or generic parameter base}}
// Unqualified reference to typealias from a protocol conformance
var v4: T1 // OK
var v5: T2 // OK
// Qualified reference
var v6: T5.T1 // OK
var v7: T5.T2 // OK
var v8 = P6.A.self
var v9 = P6.B.self // expected-error {{type alias 'B' can only be used with a concrete type or generic parameter base}}
}
// Unqualified lookup finds typealiases in protocol extensions, though
protocol P7 {
associatedtype A
}
extension P7 {
typealias Y = A
}
struct S7 : P7 {
typealias A = Int
func inTypeContext(y: Y) { }
func inExpressionContext() {
_ = Y.self
_ = T5.T1.self
_ = T5.T2.self
}
}
protocol P8 {
associatedtype B
@available(*, unavailable, renamed: "B")
typealias A = B // expected-note{{'A' has been explicitly marked unavailable here}}
}
func testP8<T: P8>(_: T) where T.A == Int { } // expected-error{{'A' has been renamed to 'B'}}{{34-35=B}}