-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Description
This arose from #2584. This code snippet from trans::base::trans_assign_op
illustrates the problem:
ret move_val(bcx, DROP_EXISTING, lhs_res.val,
// FIXME: should kind be owned?
{bcx: bcx, val: target, kind: owned},
dty);
bcx
has type block
, which is now a newtype-like enum whose LHS is an @ of a class. The bug is exposed by the fact that block
doesn't get treated as immediate even though its representation is a box, but that's not the main bug. The main problem is that there's an implicit move because of the second use of bcx
as a field in the record literal: it's a last use, implying that bcx
gets zeroed at that point. Normally, borrowck would flag a move of something that has a reference to it (the reference gets brought about by the first instance of bcx
, as the first argument to move_val
). But since the implicit moves due to last-use information aren't visible to borrowck, the code happily compiles, runs, and then segfaults when move_val
dereferences its first argument.
@nikomatsakis and I discussed this a bit on IRC and there's not a clear solution (though there is an obvious workaround for #2584). Perhaps the answer is to just remove last-use analysis.
Activity
nikomatsakis commentedon Jun 16, 2012
Here is a targeted test case:
nikomatsakis commentedon Jun 16, 2012
I see two possible solutions. One is to have borrowck remove the entries from last_use. This sounds both complex and a bit fragile. The other is to remove last_use and ask users to manually annotate moves.
It is a bit unclear to me what will be the impact of removing last_use on usability. On the one hand, it's a nice way to avoid excess use of the unary move operator. On the other hand, it's a common source of confusion ("why am I getting a copy warning here but not there? oh, I see, that's a last-use"). Also, when you add borrowck into the equation, it's one more thing that users have to think about ("it's not a last use because there is an existing alias in scope"). On the other hand, people will probably end up understanding the idea of "alias in scope" anyway.
Add test for #2633. Xfailed.
catamorphism commentedon Jun 16, 2012
A standalone test case for this is under run-pass/issue-2633.rs (currently xfailed).
nikomatsakis commentedon Jun 16, 2012
Another example making use of by-value:
pcwalton commentedon Jun 16, 2012
I'm in favor of getting rid of the last use analysis. Programmers should not have to run a liveness pass in their heads to figure out where the moves are.
A possibility here is to re-purpose the last use analysis into a fixit for the no-implicit-copies warning. That is, you might get warnings like so if liveness detects that the variable in question is dead:
catamorphism commentedon Jun 16, 2012
I like the idea of using last-use as a source of data for improving error messages, but not for guiding code generation at all.
Make move_val take its first argument by copy
nikomatsakis commentedon Jun 17, 2012
I think I like @pcwalton's idea as well. However, that seems like a decision that should be brought up at the Tuesday meeting. For the very short term, it's probably easy enough to have borrowck remove unsafe entries from the last_use table. I'm not thrilled about the idea because we tend to make tables that are built-up by a pass and then read-only thereafter, which seems like reasonable practice.
Issue #2633: remove last_use entries that are subject to a loan
Undo workaround for #2633 since it is fixed.
catamorphism commentedon Jun 20, 2012
At the meeting today, we agreed to adopt @pcwalton 's idea to make last-use solely a hint source for error messages.
7 remaining items
nikomatsakis commentedon Sep 18, 2012
Deferring to 0.5
catamorphism commentedon Sep 19, 2012
I have a patch for this (at least, removing any code that looks at the results of last-use, and making all moves explicit), but sadly it's a huge performance hit. Apparently there is a difference between how explicit moves are compiled, and how implicit (last-use) moves are compiled: even if I change the code so that trans still pays attention to the results of last-use, but the kind checker requires explicit moves on last uses, performance still gets much worse (for example, the typechecking pass takes 18s in stage 1, as opposed to 5s in stage 0).
So I'm not checking anything in yet :-(
graydon commentedon Sep 19, 2012
Can you push to a private branch? I'm happy to
perf diff
it to find the culprit.catamorphism commentedon Oct 8, 2012
@graydon Oops, sorry, missed your comment. I will push to my fork once I get a chance to rebase it.
catamorphism commentedon Oct 13, 2012
c6780fb closes this. I opened #3755 to cover the remaining part (about hints in error messages).
Rollup merge of rust-lang#82793 - JohnTitor:move-ui-tests, r=petroche…
Rollup merge of rust-lang#82793 - JohnTitor:move-ui-tests, r=petroche…
Rollup merge of rust-lang#82793 - JohnTitor:move-ui-tests, r=petroche…
Add support to array-based SIMD (rust-lang#2633)
Fix SIMD field access (rust-lang#2660)