Skip to content

[SR-4188] withoutActuallyEscaping doesn't accept an @autoclosure argument #46771

@ole

Description

@ole
Previous ID SR-4188
Radar rdar://problem/30906031
Original Reporter @ole
Type Bug
Status Resolved
Resolution Done
Environment

macOS 10.12.3 (16D32), Xcode 8.2 (8C38) using snapshot 3.1-DEVELOPMENT-SNAPSHOT-2017-03-06-a in a macOS Command Line project (Xcode template)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, TypeChecker
Assignee @ole
Priority Medium

md5: 760a30461350d82b8f45ad66661d395b

Issue Description:

This (contrived) example, adopted from the documentation for withoutActuallyEscaping, compiles and runs as expected:

func allValues(in array: [Int], smallerThan: () -> Int) -> Bool {
    return withoutActuallyEscaping(smallerThan) { escapableF in
        array.lazy.filter { $0 >= escapableF() }.isEmpty
    }
}

let result = allValues(in: [1,2,3], smallerThan: { 10 })
print(result) // true

When I make the function argument an @autoclosure like so:

func allValues(in array: [Int], smallerThan: @autoclosure () -> Int) -> Bool {
    return withoutActuallyEscaping(smallerThan) { escapableF in
        array.lazy.filter { $0 >= escapableF() }.isEmpty
    }
}

let result = allValues(in: [1,2,3], smallerThan: 10)
print(result)

compilation fails on line 2 with this error: "Expression type '(, () throws -> _) throws -> _' is ambiguous without more context".

I tried adding type annotations to get rid of the alleged ambiguity that seemed to confuse the type checker, but I haven't found a way to get rid of the error. After I added full type annotations like this:

    return withoutActuallyEscaping(smallerThan as (() -> Int)) {
        (escapableF: () -> Int) -> Bool in
        array.lazy.filter { $0 >= escapableF() }.isEmpty
    }

the ambiguity error remained and another error appeared on the array.lazy... line: "Closure use of non-escaping parameter 'escapableF' may allow it to escape".

Tested with 3.1-DEVELOPMENT-SNAPSHOT-2017-03-06-a.

Background: the above example is contrived. My actual use case is that I'd like to use withoutActuallyEscaping inside a custom assertion function that should take its arguments as autoclosures.

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselftype checkerArea → compiler: Semantic analysis

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions