Why is creating an Array inside an Array extension inferring the Element of the extension rather then the init?

I just noticed that this sample code doesn't compile.

extension [Int] {
    func something() {
        let array: [String] = Array(repeating: "1", count: 1) 
    }
}

specifically, when I do Array(repeating: "1", count: 1) it infers that it's an Array<Int> instead of Array<String> and its fails to compile.

To solve this we need to specifically write Array<String>(repeating: "1", count: 1)

I just got curious. Why is this happening? I would assume the inference would happen based on the type we're adding in the init, instead of the extension Element type.

1 Like

For some reason this does compile:

extension [Int] {
    func something() {
        let array: [String] = .init(repeating: "1", count: 1)
    }
}

I have the feeling that this behaviour has already been reported in this forum, but I haven't found the thread yet.

1 Like

Here’s a thread on the topic from 2019: Using the bare name of a generic type within itself

The general opinion seems to be, “We originally thought it was a good idea, but it turned out not to be and we’d like to remove it.”

I don’t know if addressing this issue made it onto the list for Swift 6, but personally I hope so.

7 Likes

No such change has been approved for any upcoming release, and such source-breaking changes are not in scope anymore for Swift 6.

1 Like

This is shorter anyway:

let array = [String](repeating: "1", count: 1)

so not a big deal.

This might be a contender for “most absurd workaround”, but the following line completely eliminates the issue:

typealias Array = Swift.Array

You can put that at the top level, or in an extension of Array, or within the local function scope, and it’ll work wherever it’s visible.

2 Likes

Huh, indeed. And using it in place also works:

    ...
    let array = Swift.Array(repeating: "1", count: 1) // ✅
2 Likes