You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy values have special copy semantics, when they're moved away, the old place still have valid value alive. A lot of times this is not people want. For example, it's very easy to typo and wrongly use some temporary values after they have been sent away with assignment.
If possible, i'd propose a move expression:
`move` `(` expr `)`
The parenthesis are for avoiding the ambiguity with move closures.
Example:
let a = 42;
x.a = move(a);double(&mut x.a);dbg!(a);// compile error
Alternatives:
unlet a;
a.move
let a = 42 in { ... };
Reacted by kennytm, konsumlamm, ptrca, SOFe (Jonathan Chan Kwan Yin), Stanislav Alekseev and Mitsuki Kagamin
For example, it's very easy to typo and wrongly use some temporary values after they have been sent away with assignment.
I've never seen this be a problem, since by definition the old value is still valid? Do you have an example of where this can cause a problem?
Assuming there's an example where this is a problem, why would someone remember to use the "move" modifier, if they forgot not to use the moved value? Typically these problems are solved in the type definition rather than the use-site, since it avoids this problem, but this solution already exists - you can just not implement Copy for types which you want to be moved.
Reacted by kennytm, uwoneko, SOFe (Jonathan Chan Kwan Yin), lolbinarycat and Mark Yan
I'm still a little curious why @Diggsey has never seen this be a problem. When writing algorithms, and there's more than one pointers or indices or something lightweight but copyable. I feel this is so common. Sorry I don't have code to share at the moment though. These types cannot be defined as non-copyable but this invalidation only happens within specific portion of algorithm.
These types cannot be defined as non-copyable but this invalidation only happens within specific portion of algorithm.
Sorry but this speaks more about the API design of the code than the Rust language. It is trivial to wrap the Copy type in a non-Copy structure such as
let a = NoCopy::new(42);// <-- wrap the type into NoCopy
x.a = a.into_inner();// <-- consume the NoCopydouble(&mut x.a);dbg!(a);// error[E0382]: use of moved value: `a`
You could further enhance the safety by making the API accept specialized NoCopy-styled wrapper types only, and also making their new() and into_inner() private to the low-level modules.
And even if this RFC is implemented, as @Diggsey said in the 2nd paragraph of their comment, if you forget to annotate a move(a) the compiler will never be able to notice because copying is still valid, so this RFC offered no safety guard against misuse. Meanwhile if the variable a itself is declared NoCopy<i32> instead (i.e. "solved in the type definition rather than the use-site"), Rust can easily statically prevent double-use.
Reacted by Jake Goulding, Angel Pineda and uwoneko
Activity
Diggsey commentedon Jul 9, 2024
I've never seen this be a problem, since by definition the old value is still valid? Do you have an example of where this can cause a problem?
Assuming there's an example where this is a problem, why would someone remember to use the "move" modifier, if they forgot not to use the moved value? Typically these problems are solved in the type definition rather than the use-site, since it avoids this problem, but this solution already exists - you can just not implement Copy for types which you want to be moved.
kennytm commentedon Jul 9, 2024
or you could just use
{ … }to impose the normal scoping rule...crlf0710 commentedon Jul 9, 2024
Yes, this
unletmacro is good enough.I'm still a little curious why @Diggsey has never seen this be a problem. When writing algorithms, and there's more than one pointers or indices or something lightweight but copyable. I feel this is so common. Sorry I don't have code to share at the moment though. These types cannot be defined as non-copyable but this invalidation only happens within specific portion of algorithm.
kennytm commentedon Jul 10, 2024
Sorry but this speaks more about the API design of the code than the Rust language. It is trivial to wrap the Copy type in a non-Copy structure such as
You could further enhance the safety by making the API accept specialized
NoCopy-styled wrapper types only, and also making theirnew()andinto_inner()private to the low-level modules.And even if this RFC is implemented, as @Diggsey said in the 2nd paragraph of their comment, if you forget to annotate a
move(a)the compiler will never be able to notice because copying is still valid, so this RFC offered no safety guard against misuse. Meanwhile if the variableaitself is declaredNoCopy<i32>instead (i.e. "solved in the type definition rather than the use-site"), Rust can easily statically prevent double-use.clarfonthey commentedon Aug 3, 2024
Note that there's also this RFC which attempts to solve a similar no-move problem: #3518