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

|&mut:| wants (Copy) upvar to be mutable when it shouldn't #16749

Closed
japaric opened this issue Aug 25, 2014 · 2 comments
Closed

|&mut:| wants (Copy) upvar to be mutable when it shouldn't #16749

japaric opened this issue Aug 25, 2014 · 2 comments
Labels
A-closures Area: Closures (`|…| { … }`)

Comments

@japaric
Copy link
Member

japaric commented Aug 25, 2014

STR

#![feature(overloaded_calls, unboxed_closures)]

use std::mem;

fn main() {
    // error: cannot assign to immutable captured outer variable in a proc
    //let n = 0u8;
    let mut n = 0u8;

    let mut f = |&mut:| {
        n += 1;
        println!("f.n = {}", n);
    };

    println!("Closure size: {}", mem::size_of_val(&f));
    f();
    f();
    f();
    println!("n = {}", n);
}

Output

Closure size: 1
f.n = 1
f.n = 2
f.n = 3
n = 0

Correct me if I'm wrong, but I think n shouldn't need to be mutable, because f captures (by value) a copy of n, and modifies its copy of n on each call. Whereas, the outer n remains unchanged.

cc @pcwalton

@aturon aturon mentioned this issue Oct 16, 2014
47 tasks
@bkoropoff
Copy link
Contributor

A proc has the same behavior, so this isn't a difference with unboxed closures in particular. It strikes me as intentional since rust defaults to immutability, and the only place where you can specify that you want mutability is on the original binding. You can always write something like this instead:

let x = 0u;
...
let mut x_copy = x;
let f = move |&mut:| x_copy = 42;

@nikomatsakis
Copy link
Contributor

The closure in the original example is capturing by reference, not by value as the description implies. In any case I added a test covering all the tests and will close this issue -- everything seems to be behaving reasonably. The one thing that surprised me is that you can mutate a variable declared as let from within a FnMut closure; it makes sense when you consider the desugaring. This seems to be the case that @japaric was initially attempting to test, and it indeed works as he predicted. I am not sure yet if this is a bug though.

@steveklabnik steveklabnik added the A-closures Area: Closures (`|…| { … }`) label Jan 29, 2015
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 17, 2024
…eykril

internal: Some method resolution cleanups
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`)
Projects
None yet
Development

No branches or pull requests

4 participants