Rust: use of partially moved values

rust

Solution

In Rust 0.8, `assert_eq!` is defined as

macro_rules! assert_eq (
    ($given:expr , $expected:expr) => (
        {
            let given_val = $given;
            let expected_val = $expected;
            // check both directions of equality....
            if !((given_val == expected_val) && (expected_val == given_val)) {
                fail!(\"assertion failed: `(left == right) && (right == \
                left)` (left: `%?`, right: `%?`)\", given_val, expected_val);
            }
        }
    )
)

Note here that it moves both arguments into local let-bindings `given_val` and `expected_val`. This is what is causing your error.

In current master, this has been fixed. `assert_eq!` now takes references to the arguments:

macro_rules! assert_eq (
    ($given:expr , $expected:expr) => (
        {
            let given_val = &($given);
            let expected_val = &($expected);
            // check both directions of equality....
            if !((*given_val == *expected_val) &&
                 (*expected_val == *given_val)) {
                fail!("assertion failed: `(left == right) && (right == left)` \
                       (left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
            }
        }
    )
)

This means that it no longer moves its arguments, which fixes your error.

If you need to stick with rust 0.8, you can change this to using `assert!()` instead and do the comparison directly, which will avoid the move. But my recommendation is to upgrade to latest master.

Problem

In Rust 0.8: ``` struct TwoStr { one: ~str, two: ~str, } #[test] fn test_contents() { let strs = TwoStr { one: ~"pillar", two: ~"post", }; assert_eq!(strs.one, ~"pillar"); assert_eq!(strs.two, ~"post"); } ``` The code won't even compile. The `rust test` thinks there's an error in the second `assert_eq`: error: use of partially moved value: `strs` It is somewhat counter-intuitive. I mean, whatever effects the first `assert_eq` may have, it should be well out of the scope when the execution reaches the second `assert_eq`. Unless of course, it does some spawn behind the scene. Does it? If not, why this mysterious error? Hopefully there's no fundamental flaws in my understanding of Rust pointers.

Original source