Skip to content
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

Clarified move semantics in "the details" section. #31565

Merged
merged 6 commits into from
Feb 18, 2016
Merged

Clarified move semantics in "the details" section. #31565

merged 6 commits into from
Feb 18, 2016

Conversation

sandeep-datta
Copy link
Contributor

See title and diff for more information.

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@steveklabnik
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Feb 11, 2016

📌 Commit a6fedc8 has been approved by steveklabnik

@steveklabnik
Copy link
Member

@bors: rollup

@sandeep-datta
Copy link
Contributor Author

@steveklabnik any idea why the CI builds are failing? The build seems to pass on my machine.


```rust
v2.truncate(2);
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing the travis failure:


---- Move_semantics_5 stdout ----
    <anon>:2:5: 2:7 error: unresolved name `v2` [E0425]
<anon>:2     v2.truncate(2);
             ^~

You should change this to

    ```rust
    # let v = vec![1, 2, 3];
    # let v2 = v;
    v2.truncate(2);
    ```

@steveklabnik
Copy link
Member

@bors: r-

@steveklabnik
Copy link
Member

It's gotta be mut for truncate() to work

@sandeep-datta
Copy link
Contributor Author

@steveklabnik

Okay so I changed the code to...

fn main() {
    let v = vec![1, 2, 3];
    let mut v2 = v;
    v2.truncate(2);
    println!("{:?}", v2);
}

And it worked.

But now I wonder if we have to switch to a mutable binding to actually inflict any damage then why does rust object to using older immutable bindings (when you do not have a mutable binding in the fray)? Is this simply to make book keeping easier for the compiler?

@steveklabnik
Copy link
Member

I'm not sure what you mean, but I think I do, so let me try:

Each triple-backtick block is its own little universe. There's no shared context between them. So there is no 'older immutable binding' lying around.

Does that make sense? maybe I'm still confused 😄

regardless, @bors: r+ rollup

@bors
Copy link
Contributor

bors commented Feb 17, 2016

📌 Commit 1536195 has been approved by steveklabnik

steveklabnik added a commit to steveklabnik/rust that referenced this pull request Feb 17, 2016
See title and diff for more information.
bors added a commit that referenced this pull request Feb 18, 2016
@bors bors merged commit 1536195 into rust-lang:master Feb 18, 2016
@sandeep-datta
Copy link
Contributor Author

Each triple-backtick block is its own little universe.

I guessed as much from your suggested fix.

But this isn't what I was asking. I wanted to know why does the compiler object to reusing a binding once it has been "moved"? Considering the fact that a "move" really is only a bitwise copy and if everything remains immutable then what problem are we trying to avoid by disallowing post-move access to a binding?

In other words why does the following not work even when v and v2 are immutable? What could possibly go wrong?

fn main() {
    let v = vec![1, 2, 3];
    let v2 = v;
    println!("{:?}", v);
}

@pnkfelix
Copy link
Member

@sandeep-datta :

after moving the vector into v2, v2 now has ownership.

The vector thus could later be moved elsewhere (perhaps into a binding that is declared as mut, which would re enable mutation) and perhaps dropped entirely.

Example:

fn main() {
    let v = vec![1, 2, 3];
    let v2 = v;
    {   let v3 = v2; drop(v3); } // explicit drop for clarity, 
        // but even without it v3 would be dropped at end of this inner scope
    println!("{:?}", v);
}

@KalitaAlexey
Copy link
Contributor

@sandeep-datta Consider UnsafeCell instead of Vec. It is externally immutable, but internally mutable. It may lead to errors.

@sandeep-datta
Copy link
Contributor Author

@pnkfelix @KalitaAlexey thanks! I will update the documentation to demonstrate this problem using UnsafeCell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants