Closed
Description
Previous ID | SR-12033 |
Radar | rdar://problem/72801670 |
Original Reporter | @ktoso |
Type | Bug |
Status | Resolved |
Resolution | Duplicate |
Environment
Swift: 5.2-DEVELOPMENT-SNAPSHOT-2020-01-13-a
Additional Detail from JIRA
Votes | 0 |
Component/s | Compiler |
Labels | Bug |
Assignee | @LucianoPAlmeida |
Priority | Medium |
md5: 400b29754adbf7f534b6f2d46fb3b6f2
duplicates:
- 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.
struct Thing<T> {
public static func capture(_ thunk: () -> T) -> Thing<T> {
.init() // does not matter how implemented
}
public static func captureA(_ thunk: @autoclosure () -> T) -> Thing<T> {
.init() // does not matter how implemented
}
public static func captureE(_ thunk: @escaping () -> T) -> Thing<T> {
.init() // does not matter how implemented
}
public static func captureAE(_ thunk: @autoclosure @escaping () -> T) -> Thing<T> {
.init() // does not matter how implemented
}
}
struct Ok {
public static func captureGenericFuncA<T>(_ thunk: @autoclosure () -> T) -> Thing<T> {
.init()
}
func compiles() {
var number = 1
let t = Thing<Int>.capture {
number
} // ok, just a sanity check
let t2 = Thing<Int>.captureE {
number
} // ok, just a sanity check
let t3 = Thing<Int>.captureA(number) // ok
let t4 = Self.captureGenericFuncA(number) // ok
let t5 = Self.captureGenericFuncA { number } // ok, works fine, so why not the `e` ones below:
}
}
struct Bad {
func doesNotCompile() {
var number = 1
let e = Thing<Int>.captureA { // equivalent to `t5` above
number
}
// cannot convert value of type '@lvalue Int' to closure result type 'Int'
// }
// ^
let e2 = Thing<Int>.captureAE {
number
}
// cannot convert value of type '@lvalue Int' to closure result type 'Int'
// }
// ^
}
}
Or is there something I'm missing here?