// RUN: %target-typecheck-verify-swift protocol P1 { associatedtype AssocType } protocol P2 : P1 { } protocol P3 { } struct X { struct Inner { } struct NonGenericInner { } } extension Int : P1 { typealias AssocType = Int } extension Double : P2 { typealias AssocType = Double } extension X { let x = 0 // expected-error@-1 {{extensions must not contain stored properties}} static let x = 0 func f() -> Int {} class C {} } typealias GGG = X extension GGG { } // okay through a typealias // Lvalue check when the archetypes are not the same. struct LValueCheck { let x = 0 } extension LValueCheck { init(newY: Int) { x = 42 } } // Member type references into another extension. struct MemberTypeCheckA { } protocol MemberTypeProto { associatedtype AssocType func foo(_ a: AssocType) init(_ assoc: MemberTypeCheckA) } struct MemberTypeCheckB : MemberTypeProto { func foo(_ a: T) {} typealias Element = T var t1: T } extension MemberTypeCheckB { typealias Underlying = MemberTypeCheckA } extension MemberTypeCheckB { init(_ x: Underlying) { } } extension MemberTypeCheckB { var t2: Element { return t1 } } // rdar://problem/19795284 extension Array { var pairs: [(Element, Element)] { get { return [] } } } // rdar://problem/21001937 struct GenericOverloads { var t: T var u: U init(t: T, u: U) { self.t = t; self.u = u } func foo() { } var prop: Int { return 0 } subscript (i: Int) -> Int { return i } } extension GenericOverloads where T : P1, U : P2 { init(t: T, u: U) { self.t = t; self.u = u } func foo() { } var prop: Int { return 1 } subscript (i: Int) -> Int { return i } } extension Array where Element : Hashable { // expected-note {{where 'Element' = 'T'}} var worseHashEver: Int { var result = 0 for elt in self { result = (result << 1) ^ elt.hashValue } return result } } func notHashableArray(_ x: [T]) { x.worseHashEver // expected-error{{property 'worseHashEver' requires that 'T' conform to 'Hashable'}} } func hashableArray(_ x: [T]) { // expected-warning @+1 {{unused}} x.worseHashEver // okay } func intArray(_ x: [Int]) { // expected-warning @+1 {{unused}} x.worseHashEver } class GenericClass { } extension GenericClass where T : Equatable { // expected-note {{where 'T' = 'T'}} func foo(_ x: T, y: T) -> Bool { return x == y } } func genericClassEquatable(_ gc: GenericClass, x: T, y: T) { _ = gc.foo(x, y: y) } func genericClassNotEquatable(_ gc: GenericClass, x: T, y: T) { gc.foo(x, y: y) // expected-error{{referencing instance method 'foo(_:y:)' on 'GenericClass' requires that 'T' conform to 'Equatable'}} } extension Array where Element == String { } extension GenericClass : P3 where T : P3 { } extension GenericClass where Self : P3 { } // expected-error@-1{{covariant 'Self' or 'Self?' can only appear as the type of a property, subscript or method result; did you mean 'GenericClass'?}} {{30-34=GenericClass}} protocol P4 { associatedtype T init(_: T) } protocol P5 { } struct S4: P4 { init(_: Q) { } } extension S4 where T : P5 {} struct S5 { init(_: Q) { } } extension S5 : P4 {} // rdar://problem/21607421 public typealias Array2 = Array extension Array2 where QQQ : VVV {} // expected-error@-1 {{cannot find type 'QQQ' in scope}} // expected-error@-2 {{cannot find type 'VVV' in scope}} // https://github.com/apple/swift/issues/51512 func foo() { extension Array where Element : P1 { // expected-error@-1 {{declaration is only valid at file scope}} func foo() -> Element.AssocType {} } } // Deeply nested protocol P6 { associatedtype Assoc1 associatedtype Assoc2 } struct A { struct B { struct C { } } } extension A.B.C where T == V, X == Z.Assoc2 { func f() { } } // Extensions of nested non-generics within generics. extension A.B { struct D { } } extension A.B.D { func g() { } } // rdar://problem/43955962 struct OldGeneric {} typealias NewGeneric = OldGeneric extension NewGeneric { static func oldMember() -> OldGeneric { return OldGeneric() } static func newMember() -> NewGeneric { return NewGeneric() } } extension (NewGeneric) { static func oldMember2() -> OldGeneric { return OldGeneric() } static func newMember2() -> NewGeneric { return NewGeneric() } } protocol P7 {} extension Float: P7 {} protocol Q1 { associatedtype X func foo(_ x: X) } struct S7: Q1 { func foo(_ x: T) {} } // Make sure we reject these extensions. extension S7 {} // expected-error {{type 'Int' does not conform to protocol 'P7'}} extension [S7] {} // expected-error {{type 'Int' does not conform to protocol 'P7'}} extension Array> {} // expected-error {{type 'Int' does not conform to protocol 'P7'}} extension S7? {} // expected-error {{type 'Int' does not conform to protocol 'P7'}} extension S7.X {} // expected-error {{type 'Int' does not conform to protocol 'P7'}} extension S7.X {} // expected-error {{extension of type 'S7.X' (aka 'Float') must be declared as an extension of 'Float'}} // expected-note@-1 {{did you mean to extend 'Float' instead?}} extension S7 {} // expected-error {{cannot find type 'T' in scope}}