You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
del.rs|22 col 18 error| cannot borrow `(**prev)#1` as mutable more than once at a time
del.rs|21 col 23 n| second borrow of `(**prev)#1` as mutable occurs here
What is going on? The problem has to do with the order of arguments to the outer replace. Consider this alternate version, which has a flipped replace function:
Operationally, all of these code fragments do the same thing, since only one of the two arguments has side-effects; but of course, to the borrow-checker, a borrow counts as a side-effect.
Since borrows commute, one way to fix this is "sink" big borrows as late as possible (in analogy to how you sink memory dereferences to reduce register pressure). I don't actually know if this works or is a good idea.
If you squint, fixing Issue #6268 might resolve this issue as well. My interpretation goes something like this: the big borrow starts off as the secondary aliasing loan, permitting the inner replace, before it becomes a proper primary loan.
This is a dup of #6268 as the OP suggested might be the case. It has nothing to do with receivers, but receivers are not the heart of the issue, the issue is the hierarchical lifetime structure around function/method calls, and its inability to capture the fact that the pointers passed as argument will not be used until during the call itself.
Here is a piece of code that borrow-checks:
Here is a rewritten variant of
pop
, where the let has been substituted in, which does not borrow-check:failing with:
What is going on? The problem has to do with the order of arguments to the outer replace. Consider this alternate version, which has a flipped replace function:
This borrow-checks fine. The key is that the borrow-checker is interpreting the original (failing) code as something like this:
whereas the succeeding code is more like:
Operationally, all of these code fragments do the same thing, since only one of the two arguments has side-effects; but of course, to the borrow-checker, a borrow counts as a side-effect.
Since borrows commute, one way to fix this is "sink" big borrows as late as possible (in analogy to how you sink memory dereferences to reduce register pressure). I don't actually know if this works or is a good idea.
If you squint, fixing Issue #6268 might resolve this issue as well. My interpretation goes something like this: the big borrow starts off as the secondary aliasing loan, permitting the inner replace, before it becomes a proper primary loan.
CC @nikomatsakis
The text was updated successfully, but these errors were encountered: