Type of a for loop element isn't captured

Hello,

I don't know if it's a bug or the behavior is expected, but why the type of an element isn't captured using for-in loop compared to ForEach

I am expecting that stuff inside the for-in loop to be of type Stuff instead of Any.

2 Likes

The problem seems to be that the inferred type of the iterator is wrong:

let iterator1 = collection.makeIterator() // inferred as `any IteratorProtocol`, not `any IteratorProtocol<Stuff>`
let iterator2: any IteratorProtocol<Stuff> = collection.makeIterator() // error

and the for-in loop uses the iterator rather than the collection itself.

1 Like

Definitely a compiler bug! This is on my list of things to investigate. Would you mind filing a GitHub issue? Thank you!

11 Likes

Yep, seems like a compiler issue
this was the blog I was following to get some details:

I tried like below and wondering at least it should return Struct/Protocol type

protocol TestProtocol {}

struct TestType: TestProtocol {
  let name: String

  static func run(value: Self) {
    print(value.name)
  }
}

let array: any Collection<TestProtocol> = [TestType(name: "one"), TestType(name: "two")]

for value in array {
  TestType.run(value: value)
}

and got the same error

/main.swift:51:23: error: cannot convert value of type 'Any' to expected argument type 'TestType'
  TestType.run(value: value)
                      ^
                            as! TestType

Seems like from compiling end they missed reflecting the current type i.e. returning the default Any type.

I opened a bug on the GitHub repo, you can check it here.

cc @hborla

1 Like