Hi Guys,
I noticed a strange behaviour in the complier. It seems like the compiler is not able to infer the return type if the closure contains multiple lines of code.
Heres my class and methods looks like,
public class SnapshotWorkItem<V> where V: UIResponder {
let content: () -> V
private(set) var visible: (V -> Void)?
public init(_ content: @escaping () -> V) {
self.content = content
}
public func onVisible(_ visible: @escaping (V) -> Void) -> Self {
self.visible = visible
return self
}
}
// Snapshot base class
extension BaseTestCase {
func snapshot<C>(_ item: () -> SnapshotWorkItem<C>) where C: UIResponder {
// create snapshot
}
}
I am using the above in my unite test like below,
func testDetailsView() {
snapshot {
SnapshotWorkItem {
let view = DetailedAnnouncementView(frame: frame)
view.configure(model)
return view
}.onVisible { view in
🛑 // ERROR: Value of type 'UIResponder' has no member 'announcementScrollView'
print(view.announcementScrollView.frame)
}
}
}
The above code throws a compiler error on .onVisible { }, as it is not able to infer the return type.
However, the compiler seems to be happy if I use implicit return in the first closer, something like this,
func testDetailsView() {
snapshot {
SnapshotWorkItem {
DetailedAnnouncementView(frame: frame)
}.onVisible { view in
✅ // Works fine
print(view.announcementScrollView.frame)
}
}
}
It looks like the compiler is not able to infer the return type from multiline closures. I don't know if i am doing something wrong, can some please help with this . Thanks in advance.
Hi Xiaodi Wu,
Thanks for the response. Good to know that I am not doing something wrong. I might go with "chaining helper method" approach which I mentioned in my second comment.
Also it is good to know that, "giving the closure an explicit signature" works too.
There is also some information in this older discussion: Streamlining closures, e.g. from Jordan Rose:
Swift's type inference is currently statement-oriented, so there's no easy way to do this inference. This is at least partly a compilation-time concern: Swift's type system allows many more possible conversions than, say, Haskell or OCaml, so solving the types for an entire multi-statement function is not a trivial problem, possibly not a tractable problem.