Klaas
Klaas

Reputation: 22763

Swift 4 custom generic struct with optional array behaves strange?

I'm migrating a larger codebase to Swift 4. It includes a custom type that implements a matrix. In Swift 3.1 everything works well and as expected.

I was able to reduce the problem to two small code blocks. The first one defines the struct:

struct Matrix<Element> {
    var array:[Element?] = []

    mutating func setup(repeatedValue:Element) {
        let fooTemp = Array<Element?>(repeating: repeatedValue, count: 10)
        self.array = fooTemp
    }
}

The problem itself comes when I add the Sequence implementation:

extension Matrix: Sequence {
    typealias Iterator = AnyIterator<Element?>

    func makeIterator() -> Iterator {
        return AnyIterator(array.makeIterator())
    }
}

As soon as the Sequence implementation is part of the code, I get a compiler error in the line self.array = fooTemp:

Cannot assign value of type '[Element??]' to type '[_?]'

I know, that I can fix this issue by using let fooTemp = Array<Element> in the code. The type inference does not respect this and make fooTemp an Array<Element?>.

What's going on here? Compiler shenanigans?

The issue occurs in Swift 3.2 as well.

Upvotes: 2

Views: 135

Answers (1)

Martin R
Martin R

Reputation: 539685

The Sequence protocol defines

/// A type that provides the sequence's iteration interface and
/// encapsulates its iteration state.
associatedtype Element where Self.Element == Self.Iterator.Element

and that causes a conflict, since your Self.Iterator.Element is Element?. Choosing a different name for your generic placeholder solves the problem.

Upvotes: 2

Related Questions