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.