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

Iterative mutable slicing doesn't work #18902

Closed
mahkoh opened this issue Nov 12, 2014 · 8 comments
Closed

Iterative mutable slicing doesn't work #18902

mahkoh opened this issue Nov 12, 2014 · 8 comments
Labels
A-borrow-checker Area: The borrow checker

Comments

@mahkoh
Copy link
Contributor

mahkoh commented Nov 12, 2014

    {
        let mut bytes = bytes.as_mut_slice();
        for s in i.iter() {
            std::slice::bytes::copy_memory(bytes, s.as_bytes());
            bytes[s.len()] = 0;
            bytes = bytes.slice_from_mut(s.len() + 1);
        }
    }

Where the outer bytes is a vector. This code is safe and the only alternative seems to be working with raw pointers.

@Gankra
Copy link
Contributor

Gankra commented Nov 12, 2014

This appears to just be the classic borrowck mutable loop wrangling issue. The following works:

fn main() {
    let i = vec!["hello", "there", "yo"];
    let mut bytes = Vec::from_elem(1000, 0);
    {
        // We need to make the temp variable so that borrowck "gets" what we're doing.
        let mut temp = bytes.as_mut_slice();
        for s in i.iter() {
            let bytes = temp;
            std::slice::bytes::copy_memory(bytes, s.as_bytes());
            bytes[s.len()] = 0;
            temp = bytes.slice_from_mut(s.len() + 1);
        }
    }
}

playpen

@steveklabnik
Copy link
Member

Closing as 'not a bug', then.

@mahkoh
Copy link
Contributor Author

mahkoh commented Jan 27, 2015

How is it not a bug?

@Gankra
Copy link
Contributor

Gankra commented Jan 27, 2015

Depends on how you interpret the lack of non-lexical borrow-checking, I guess.

@mahkoh
Copy link
Contributor Author

mahkoh commented Jan 27, 2015

I don't see what it has to do with non-lexical borrow checking. Normally you can't work around that by introducing even more variables.

@Gankra Gankra reopened this Jan 27, 2015
@Gankra
Copy link
Contributor

Gankra commented Jan 27, 2015

Re-opening. At best, it's total butts that you need to do this.

Unclear if non-lexical scopes could actually fix this.

@inrustwetrust
Copy link
Contributor

I don't think this one is related to the lexical scope of borrows. I believe it's due to how the borrow checker handles mutable borrows that are made through an already borrowed reference. This appears to place a mutable borrow restriction on the reference itself, not just the owned value.

For example:

struct Foo { val: i32 }

fn main() {
    let mut owned_foo = Foo { val: 0 };
    let mut owned_foo2 = Foo { val: 1 };

    let mut foo_ref = &mut owned_foo;

    //This makes a mutable borrow not only of
    //`owned_foo`, but also of `foo_ref` *itself*...
    let val_ref = &mut foo_ref.val;

    //...so we can't repoint foo_ref to something
    //else here, even though it would be safe (the
    //memory val_ref points to is still backed by
    //owned_foo)
    foo_ref = &mut owned_foo2;
}

The above code result in "cannot assign to foo_ref because it is borrowed" on the last line.
Interestingly, the same issue does not appear if the mutable borrows are changed to non-mutable ones.

@mahkoh mahkoh closed this as completed Apr 11, 2015
@rust-lang rust-lang locked and limited conversation to collaborators Apr 11, 2015
@nikomatsakis
Copy link
Contributor

fwiw, this is a dup of #10520 I believe

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-borrow-checker Area: The borrow checker
Projects
None yet
Development

No branches or pull requests

5 participants