// RUN: %target-typecheck-verify-swift // Bad containers and ranges struct BadContainer1 { } func bad_containers_1(bc: BadContainer1) { for e in bc { } // expected-error{{type 'BadContainer1' does not conform to protocol 'Sequence'}} } struct BadContainer2 : Sequence { // expected-error{{type 'BadContainer2' does not conform to protocol 'Sequence'}} var generate : Int } func bad_containers_2(bc: BadContainer2) { for e in bc { } } struct BadContainer3 : Sequence { // expected-error{{type 'BadContainer3' does not conform to protocol 'Sequence'}} func makeIterator() { } // expected-note{{inferred type '()' (by matching requirement 'makeIterator()') is invalid: does not conform to 'IteratorProtocol'}} } func bad_containers_3(bc: BadContainer3) { for e in bc { } } struct BadIterator1 {} struct BadContainer4 : Sequence { // expected-error{{type 'BadContainer4' does not conform to protocol 'Sequence'}} typealias Iterator = BadIterator1 // expected-note{{possibly intended match 'BadContainer4.Iterator' (aka 'BadIterator1') does not conform to 'IteratorProtocol'}} func makeIterator() -> BadIterator1 { } } func bad_containers_4(bc: BadContainer4) { for e in bc { } } // Pattern type-checking struct GoodRange : Sequence, IteratorProtocol { typealias Element = Int func next() -> Int? {} typealias Iterator = GoodRange func makeIterator() -> GoodRange { return self } } struct GoodTupleIterator: Sequence, IteratorProtocol { typealias Element = (Int, Float) func next() -> (Int, Float)? {} typealias Iterator = GoodTupleIterator func makeIterator() -> GoodTupleIterator {} } func patterns(gir: GoodRange, gtr: GoodTupleIterator) { var sum : Int var sumf : Float for i : Int in gir { sum = sum + i } for i in gir { sum = sum + i } for f : Float in gir { sum = sum + f } // expected-error{{'Int' is not convertible to 'Float'}} for (i, f) : (Int, Float) in gtr { sum = sum + i } for (i, f) in gtr { sum = sum + i sumf = sumf + f sum = sum + f // expected-error {{binary operator '+' cannot be applied to operands of type 'Int' and 'Float'}} expected-note {{expected an argument list of type '(Int, Int)'}} } for (i, _) : (Int, Float) in gtr { sum = sum + i } for (i, _) : (Int, Int) in gtr { sum = sum + i } // expected-error{{'GoodTupleIterator.Element' (aka '(Int, Float)') is not convertible to '(Int, Int)'}} for (i, f) in gtr {} } func slices(i_s: [Int], ias: [[Int]]) { var sum = 0 for i in i_s { sum = sum + i } for ia in ias { for i in ia { sum = sum + i } } } func discard_binding() { for _ in [0] {} } struct X { var value: T } struct Gen : IteratorProtocol { func next() -> T? { return nil } } struct Seq : Sequence { func makeIterator() -> Gen { return Gen() } } func getIntSeq() -> Seq { return Seq() } func getOvlSeq() -> Seq { return Seq() } // expected-note{{found this candidate}} func getOvlSeq() -> Seq { return Seq() } // expected-note{{found this candidate}} func getOvlSeq() -> Seq> { return Seq() } // expected-note{{found this candidate}} func getGenericSeq() -> Seq { return Seq() } func getXIntSeq() -> Seq> { return Seq() } func getXIntSeqIUO() -> Seq>! { return nil } func testForEachInference() { for i in getIntSeq() { } // Overloaded sequence resolved contextually for i: Int in getOvlSeq() { } for d: Double in getOvlSeq() { } // Overloaded sequence not resolved contextually for v in getOvlSeq() { } // expected-error{{ambiguous use of 'getOvlSeq()'}} // Generic sequence resolved contextually for i: Int in getGenericSeq() { } for d: Double in getGenericSeq() { } // Inference of generic arguments in the element type from the // sequence. for x: X in getXIntSeq() { let z = x.value + 1 } for x: X in getOvlSeq() { let z = x.value + 1 } // Inference with implicitly unwrapped optional for x: X in getXIntSeqIUO() { let z = x.value + 1 } // Range overloading. for i: Int8 in 0..<10 { } for i: UInt in 0...10 { } } func testMatchingPatterns() { // for case parse failure let myArray : [Int?] = [] for case .some(let x) in myArray { _ = x } // for/case/in patterns aren't parsed properly class A {} class B : A {} class C : A {} let array : [A] = [A(), B(), C()] for case (let x as B) in array { _ = x } } // QoI: diagnostic for for-each over an optional sequence isn't great func testOptionalSequence() { let array : [Int]? for x in array { // expected-error {{value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}} } } // Crash with (invalid) for each over an existential func testExistentialSequence(s: Sequence) { // expected-error {{protocol 'Sequence' can only be used as a generic constraint because it has Self or associated type requirements}} for x in s { // expected-error {{using 'Sequence' as a concrete type conforming to protocol 'Sequence' is not supported}} _ = x } } // Conditional conformance to Sequence and IteratorProtocol. protocol P { } struct RepeatedSequence { var value: T var count: Int } struct RepeatedIterator { var value: T var count: Int } extension RepeatedIterator: IteratorProtocol where T: P { typealias Element = T mutating func next() -> T? { if count == 0 { return nil } count = count - 1 return value } } extension RepeatedSequence: Sequence where T: P { typealias Element = T typealias Iterator = RepeatedIterator typealias SubSequence = AnySequence func makeIterator() -> RepeatedIterator { return Iterator(value: value, count: count) } } extension Int : P { } func testRepeated(ri: RepeatedSequence) { for x in ri { _ = x } }