Skip to content

Assigning a linearly typed value to _ does trigger use of moved value errors on subsequent usages #15151

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

Closed
brendanzab opened this issue Jun 24, 2014 · 10 comments
Labels
A-type-system Area: Type system

Comments

@brendanzab
Copy link
Member

This code fails to compile:

fn main() {
    let x = vec![1i, 2, 3];
    let _x = x;
    println!("{}", x);
}

Error:

<anon>:4:20: 4:21 error: use of moved value: `x`
<anon>:4     println!("{}", x);
                            ^
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
<anon>:4:5: 4:23 note: expansion site
<anon>:3:9: 3:11 note: `x` moved here because it has type `collections::vec::Vec<int>`, which is moved by default (use `ref` to override)
<anon>:3     let _x = x;
                 ^~

Where as this compiles with no error:

fn main() {
    let x = vec![1i, 2, 3];
    let _ = x;
    println!("{}", x);
}

Output:

[1, 2, 3]
@schmee
Copy link
Contributor

schmee commented Jun 24, 2014

Related to #10488?

@brendanzab
Copy link
Member Author

Yeah this might be a duplicate.

@pnkfelix
Copy link
Member

@bjz I think this is by design, at least given the discussion on Issue #10488.

It was only quite recently in PR #14882 that we actually landed the new semantics for _.

@brendanzab
Copy link
Member Author

@pnkfelix So to clarify, why is this not the same as calling fn drop<T>(_: T) {} drop(x)? I had a very uncomfortable moment today when demoing move semantics and not getting a compile time error when I was expecting one.

@brendanzab
Copy link
Member Author

I would at least expect _-prefixed variables to behave the same... but then that's a slippery slope...

@pnkfelix
Copy link
Member

@bjz There is a pretty thorough discussion on #10488 about the design space here. There is an explicit note about why it makes some sense to not treat _ the same as _x here: #10488 (comment)

@pnkfelix
Copy link
Member

One quick way to summarize the motivations here is to point out that under the old system: let _ = ... was treated completely differently from let (_, _) = .... Part of the goal here was to make the treatment of _ consistent both as the whole pattern and as a sub-pattern.

@brendanzab
Copy link
Member Author

Ok, that makes sense! Thanks! This might need some documentation in an FAQ or something. Closing.

@brendanzab
Copy link
Member Author

@pnkfelix What is the semantics of let (_x, _y) = ... though?

@pnkfelix
Copy link
Member

@bjz In the semantics that I believe was settled upon in #10488, let (_x, _y) = foo; moves both components of the tuple. let (_x, _) = foo; moves just the first component of the tuple, and the second component is still available later in the control flow. Likewise let (_, _y) = foo; moves just the second component of the tuple. let (_, _) = foo; moves nothing and is synonymous with both let _ = foo; and also foo; on its own.

(I thought we were going to try to put in a lint to detect let _ = ... since under the new regime it is just noise. Update: Oh, I see, #11122 was closed not because it was completed, but due to inactivity)

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 17, 2023
… r=lnicola

Update dependencies for editor/code

This updates dependencies except ``@types/node`.`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

3 participants