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-8398] Mutating external variable from closure in recursive function #50924
Comments
It looks like each call to
@slavapestov, @jckarter, any idea how the captures are getting messed up? |
Comment by Tim (JIRA) @belkadan I think you posted the wrong snippet as it does not contain a computed property (but I can confirm that having a computed property `cache` that forwards to a property `_cache` fixes it). |
Hm, for some reason we're creating an entirely new box for `cache` in the autoclosure for the right-hand side of ??: // implicit closure #​1 in recursive #​1 (_:) in fibonacci(_:)
sil private [transparent] @$S3bar9fibonacciyS2iF9recursiveL_yS2iFSiyKXKfu_ : $@convention(thin) (Int, @guaranteed { var Dictionary<Int, Int> }, @inout_aliasable Dictionary<Int, Int>) -> (Int, @error Error) {
// %0 // users: %13, %4
// %1 // user: %5
// %2 // users: %13, %10, %7
bb0(%0 : $Int, %1 : ${ var Dictionary<Int, Int> }, %2 : $*Dictionary<Int, Int>):
debug_value undef : $Error, var, name "$error", argno 1 // id: %3
debug_value %0 : $Int, let, name "m", argno 2 // id: %4
%5 = project_box %1 : ${ var Dictionary<Int, Int> }, 0 // user: %6
debug_value_addr %5 : $*Dictionary<Int, Int>, var, name "cache", argno 3 // id: %6
debug_value_addr %2 : $*Dictionary<Int, Int>, var, name "cache", argno 4 // id: %7
%8 = alloc_box ${ var Dictionary<Int, Int> } // users: %15, %14, %11, %9
%9 = project_box %8 : ${ var Dictionary<Int, Int> }, 0 // user: %10
copy_addr %2 to [initialization] %9 : $*Dictionary<Int, Int> // id: %10 |
@swift-ci create |
Ah, I suppose it's not a property, but |
Comment by Tim (JIRA) @belkadan For what it's worth, your code snippet doesn't fix the problem in the 7/30 master snapshot (but it does in whatever Swift version Xcode 10 beta 5 ships with). |
Huh, interesting. Well, either way we need to track down the real problem. |
Computing the transitive capture list of the closure it needs `cache` for itself and for its calls to `recursive()` but with different capture flags so it ends up in the lowered capture info twice. Making `cache` a computed property keeps it from being direct, so the capture flags match, avoiding the problem. |
The fix is merged into master, so newer snapshots ought to have this fix. I'm going to try to bring it into the 4.2 branch as well: #18701 |
Environment
Xcode 10.0 beta 4, Swift Development Snapshot 7/23
Additional Detail from JIRA
md5: 33fd4ca0d4dc41aab00e903e672e8e53
Issue Description:
The text was updated successfully, but these errors were encountered: