Reputation: 13942
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.
Upvotes: 3
Views: 1377
Reputation: 185671
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.
Upvotes: 6
Reputation: 3541
It works on Git master. It must be a bug that was fixed after 0.8 was cut. In general, the released versions are not constrained to be particularly stable before release - they're essentially just snapshots.
The definition of the assert_eq!
macro, in libsyntax, takes references to the arguments, so the arguments should not be moved and you can use them after you call the macro.
If you do find another bug, try to compile master if you can, or just make a new issue.
Upvotes: 3