-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move
Copy
values
#3670
Comments
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. |
macro_rules! unlet {
($a:ident) => {
#[allow(unused_variables)]
let $a: (/* this variable has been disabled in this scope */);
}
} let a = 42;
x.a = a;
unlet!(a); // <-- new
double(&mut x.a);
dbg!(a); // error[E0381]: used binding `a` isn't initialized or you could just use {
let a = 42;
x.a = a;
} // <-- restrict scope of `a`
double(&mut x.a);
dbg!(a); // error[E0425]: cannot find value `a` in this scope |
Yes, this 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. |
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 #[repr(transparent)]
#[derive(Debug)]
struct NoCopy<T>(T);
impl<T> NoCopy<T> {
pub fn new(inner: T) -> Self {
Self(inner)
}
pub fn into_inner(self) -> T {
self.0
}
} let a = NoCopy::new(42); // <-- wrap the type into NoCopy
x.a = a.into_inner(); // <-- consume the NoCopy
double(&mut x.a);
dbg!(a); // error[E0382]: use of moved value: `a` You could further enhance the safety by making the API accept specialized And even if this RFC is implemented, as @Diggsey said in the 2nd paragraph of their comment, if you forget to annotate a |
Note that there's also this RFC which attempts to solve a similar no-move problem: #3518 |
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:The parenthesis are for avoiding the ambiguity with move closures.
Example:
Alternatives:
unlet a;
a.move
let a = 42 in { ... };
The text was updated successfully, but these errors were encountered: