Open jepers opened 3 years ago
Thanks for the minimal examples, I see the same behavior on main
. The third one triggers an assertion with main
.
Assertion failed: (!NodePtr->isKnownSentinel()), function operator*, file ilist_iterator.h, line 138.
<snip>
8 swift-frontend 0x000000010f5a3c5d fixupClosureLifetimes(swift::SILFunction&,
bool&, bool&) + 9741
9 swift-frontend 0x000000010f5a15db (anonymous namespace)::ClosureLifetimeFixup::run() + 43
func test(_ a: () -> Void) {
let x = a
x()
}
This should be invalid. In 5.0.3, it's correctly diagnosed:
./main.swift:6:13: error: non-escaping parameter 'callback' may only be called
let x = callback
^
./main.swift:5:11: note: parameter 'callback' is implicitly non-escaping
func test(_ callback: () -> Void) {
^
@escaping
@swift-ci create
@rintaro This is expected behavior: `let x = a` assigns a non-escaping closure to a local variable, which gets the same type as the argument: a non-escaping closure. Here, the 5.0.3 compiler was too restrictive.
The problem with `let x: () -> Void = a` is that the explicitly specified type means: an escaping closure. Therefore in this case an error is issued. Though I don't know if it's possible to explicitly specify non-escaping closure types for local variables. And yes, this is confusing.
Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 37ce43a6293a5b7db0413eb7094bf10fIssue Description:
As discussed here:
https://forums.swift.org/t/an-odd-error-escaping-closure-captures-mutating-self/50118/10
this compiles:
while this doesn't (only added the type of x explicitly):
And this crashes the compiler (default toolchain of Xcode 12.5):
As noted here, the above example compiles and runs if the parameter type is annotated with `@escaping` (even though it is not actually escaping).