New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-3520] Generic function taking closure with inout parameter can result in a variety of compiler errors or EXC_BAD_ACCESS #46108
Comments
I think we fixed the EXC_BAD_ACCESS on master. The various errors are still murky due to the compiler being reluctant to infer |
A handful of discussion about this from yesterday: https://twitter.com/slava_pestov/status/816196484244783104 |
@jtbandes In this example:
The problem is related to the way
^ At this point we know there are no possible solutions in this constraint system, so we go into
This attempt didn't give us anything expect that argument signature is now Now we continue trying to type-check argument independently from function but using
At this point argument type-check fails and it starts trying to diagnose argument problem itself (nested into other diagnostic), which means creating separate `FailureDiagnosis` instance and walking the tree
At this point we see that |
Looking into this further it looks like the cause of assert is related to the fact that diagnostics can't figure out () vs. Int closure return, and because no errors are diagnosed everything falls through to the verifier and fails there. |
Do you know about how member lookup works during constraint solving? I tried fixing this original issue by passing struct X2 {
func g() -> Float { return 0 }
}
func f0<T, U>(_ t: T, _ f: (inout T) -> U) { }
f0(X2(), {$0.g()}) In the resulting constraint system there are two alternatives for I noticed that during I also get an interesting error for this case: func sr3520<T>(_ item: T, _ update: (inout T) -> Void) {
var x = item
update(&x)
}
sr3520(i) { $0 += 3 } // error: passing value of type 'Int' to an inout parameter requires explicit '&'
^
& |
The bad error message I mentioned at https://twitter.com/jtbandes/status/816196817461256194 is due to the failure diagnosis process like you mentioned above. However I believe it should be solvable in one go (the issues mentioned in my previous comment are what currently prevents it from solving on its first attempt). That's as far as I got this evening... |
@jtbandes Parameters can't bind to lvalue, but they can be marked as I think this is only related to diagnostics because it's about how arguments are type-checked by |
Why is unresolvedtype a problem when typechecking the closure body and how would typechecking without the contextual type fix it? I think the contextual type needs to be correct to properly typecheck the body, otherwise any mutating operations on |
@jtbandes Having unresolved type in the parameter is not the biggest problem actually for type-checking closure because it mostly uses (in this case) the return type which is Int, the bigger problem is that the body itself can't be properly type-checked without involving top closure expression itself (with parameters) if body involves anonymous parameters because all of the such parameters are going to be turned into UnresolvedType while solving for they would lack "bind param" constraint which is left at the top level. I think I have an idea how to solve this in the diagnostics and I also have similar ticket (https://bugs.swift.org/browse/SR-3493), going to try it out tonight and report back... |
Fixed on master with this merge: c04c6c9 Please confirm with a build that has this fix in it and close the issue if you agree the issue is fixed. |
Comment by David Friberg (JIRA) Related: will this also fix the compiler crash described in the special case covered in SR-3450, where the |
dfrib (JIRA User) Unfortunately no, that has to do with limitation of SILGen which can't yet generate code for such case... |
I suspect there is some related regression in Swift 4 bundled with Xcode 9 beta 4. This sample performs well in Xcode 8.3.2: func mut<T, U>(_ some: T, _ body: (inout T) -> U) -> U {
var _some = some
return body(&_some)
}
let a = 1
mut(a) { $0 += 1; print($0) } But fails in Xcode 9 beta 4 with "error: left side of mutating operator isn't mutable: '$0' is immutable". Will work with explicit signature: mut(a) { (b: inout Int) in b += 1; print(b) } |
Raman, can you file that as a separate bug? Since it's a regression we might be able to get some more information about it. |
Jordan, I've filed a separate ticket for this issue, see SR-5628. |
Attachment: Download
Environment
OS X 10.11.6
Xcode 8.2.1 (8C1002)
Additional Detail from JIRA
md5: d07e7fa883571bf6529bbcdab6d6e651
is duplicated by:
relates to:
Issue Description:
There are several related bug reports, but the following example may possibly help toward a fix. The lines which provoke errors all have appended comments. Lines without comments are free of problems.
The text was updated successfully, but these errors were encountered: