swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.66k stars 10.38k forks source link

[SR-6725] @autoclosure causes ambiguity warnings that can be fixed by wrapping in identity function #49274

Open weissi opened 6 years ago

weissi commented 6 years ago
Previous ID SR-6725
Radar rdar://problem/36376946
Original Reporter @weissi
Type Bug

Attachment: Download

Environment $ /Library/Developer/Toolchains/swift-4.1-DEVELOPMENT-SNAPSHOT-2017-12-30-a.xctoolchain/usr/bin/swiftc --version Apple Swift version 4.1-dev (LLVM 0fcc19c0d8, Clang 1696f82ad2, Swift 691139445e) Target: x86_64-apple-darwin17.4.0
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, TypeChecker | |Assignee | None | |Priority | Medium | md5: 7b0d8a53ec125efb1af7dad400438ba5

Issue Description:

The following code

public func pretendsEscaping(_ body: @escaping () -> Int) -> Int {
    return body()
}

func foo(_ value: @autoclosure () -> Int) -> Int {
    return withoutActuallyEscaping(value) { (value: @escaping () -> Int) -> Int in
        return pretendsEscaping(value)
    }
}

print(foo(42))

should just print 42 but unfortunately it doesn't compile:

$ /Library/Developer/Toolchains/swift-4.1-DEVELOPMENT-SNAPSHOT-2017-12-30-a.xctoolchain/usr/bin/swiftc test.swift 
test.swift:6:12: error: expression type '(_, (_) throws -> _) throws -> _' is ambiguous without more context
    return withoutActuallyEscaping(value) { (value: @escaping () -> Int) -> Int in
           ^~~~~~~~~~~~~~~~~~~~~~~

Adding more type annotations also doesn't seem to help.

However, just wrapping the @autoclosure value value in the identity function id makes it compile. That's surprising 🙂

public func pretendsEscaping(_ body: @escaping () -> Int) -> Int {
    return body()
}

func foo(_ value: @autoclosure () -> Int) -> Int {
    func id<T>(_ value: T) -> T {
        return value
    }
    return withoutActuallyEscaping(id(value)) { (value: @escaping () -> Int) -> Int in
        return pretendsEscaping(value)
    }
}

print(foo(42))

compiler is the latest 4.1 snapshot but the same problem exists in 4.0 (and 3.1).

belkadan commented 6 years ago

@swift-ci create