You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SR-8625 Swift should warn if a closures is passed to an argument that is an autoclosure
Issue Description:
I bumped into a somewhat confusing compile error recently.
Reproducer below.
The general issue seems to come up when using a closure which is an @autoclosure parameter defined within a generic type.
Most notably it's a bit surprising that t5 works fine, so when the function itself has the generic, but the e examples all fail to compile, though they seem equivalent on what they're achieving.
structThing<T>{publicstaticfunc capture(_ thunk:()->T)->Thing<T>{.init()// does not matter how implemented}publicstaticfunc captureA(_ thunk:@autoclosure()->T)->Thing<T>{.init()// does not matter how implemented}publicstaticfunc captureE(_ thunk:@escaping()->T)->Thing<T>{.init()// does not matter how implemented}publicstaticfunc captureAE(_ thunk:@autoclosure@escaping()->T)->Thing<T>{.init()// does not matter how implemented}}
structOk{publicstaticfunc captureGenericFuncA<T>(_ thunk:@autoclosure()->T)->Thing<T>{.init()}func compiles(){varnumber=1lett=Thing<Int>.capture{
number
}// ok, just a sanity checklett2=Thing<Int>.captureE{
number
}// ok, just a sanity checklett3= Thing<Int>.captureA(number)// oklett4=Self.captureGenericFuncA(number)// oklett5=Self.captureGenericFuncA{ number }// ok, works fine, so why not the `e` ones below:}}
structBad{func doesNotCompile(){varnumber=1lete=Thing<Int>.captureA{// equivalent to `t5` above
number
}// cannot convert value of type '@lvalue Int' to closure result type 'Int'// }// ^lete2=Thing<Int>.captureAE{
number
}// cannot convert value of type '@lvalue Int' to closure result type 'Int'// }// ^}}
Or is there something I'm missing here?
The text was updated successfully, but these errors were encountered:
This is just a solver bug related to binding ordering. I think both cases here should report the same diagnostic, just like `captureA` now does:
error: trailing closure passed to parameter of type 'Int' that does not accept a closure
let e = Thing<Int>.captureA { // equivalent to `t5` above
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: 'captureA' declared here
public static func captureA(_ thunk: @autoclosure () -> T) -> Thing<T> {
^
The problem is that there are two bindings for the non-generic case - `Int` (`T` of `Thing` gets inferred early) and default `() -> $T` but in generic case there is only one - `() -> $T` since parameter is not yet resolved. The fix here would be to prevent inferring `() -> $T` for autoclosure arguments.
luciano (JIRA User) Do you want to take a look at this one?
Environment
Swift: 5.2-DEVELOPMENT-SNAPSHOT-2020-01-13-a
Additional Detail from JIRA
md5: 400b29754adbf7f534b6f2d46fb3b6f2
duplicates:
Issue Description:
I bumped into a somewhat confusing compile error recently.
Reproducer below.
The general issue seems to come up when using a closure which is an @autoclosure parameter defined within a generic type.
Most notably it's a bit surprising that
t5
works fine, so when the function itself has the generic, but thee
examples all fail to compile, though they seem equivalent on what they're achieving.Or is there something I'm missing here?
The text was updated successfully, but these errors were encountered: