Casting an enum which does not derive Copy to an integer moves atm:
enum E {
A = 0,
B = 1,
C = 2
}
fn main() {
let e = E::C;
assert_eq!(e as u32, 2);
assert_eq!(e as u32, 2); // error: use of moved value: `e`
}
This matches the behavior of other coercions/casts, specifically unsizing ones (Box<T> -> Box<Trait>).
However, one difference arises between old trans and MIR trans, wrt drops:
enum E {
A = 0,
B = 1,
C = 2
}
impl Drop for E {
fn drop(&mut self) {
println!("drop");
}
}
fn main() {
let e = E::C;
assert_eq!(e as u32, 2);
}
On stable, old trans will run the destructor exactly once. After #35764, MIR trans doesn't run it at all.
The reason is that the move that borrowck knows about causes the drops in MIR to be statically elided, whereas old trans forgot(?) to drop-fill e, resulting in the variable being dropped at end of scope.
Should the drop execute or not? IMO it's good to have uniformity between all moving operations.
Casting an
enumwhich does not deriveCopyto an integer moves atm:This matches the behavior of other coercions/casts, specifically unsizing ones (
Box<T> -> Box<Trait>).However, one difference arises between old trans and MIR trans, wrt drops:
On stable, old trans will run the destructor exactly once. After #35764, MIR trans doesn't run it at all.
The reason is that the move that borrowck knows about causes the drops in MIR to be statically elided, whereas old trans forgot(?) to drop-fill
e, resulting in the variable being dropped at end of scope.Should the drop execute or not? IMO it's good to have uniformity between all moving operations.