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

Cannot move out of destructured fixed length vectors in let and match #16418

Closed
brendanzab opened this issue Aug 11, 2014 · 6 comments
Closed
Labels
A-borrow-checker Area: The borrow checker C-feature-request Category: A feature request, i.e: not implemented / a PR.

Comments

@brendanzab
Copy link
Member

struct Vector3<S>(S, S, S);

// passes type checking
fn into_vec3_arg<S>([x, y, z]: [S, ..3]) -> Vector3<S> {
    Vector3(x, y, z)
}

fn into_vec3_let<S>(v: [S, ..3]) -> Vector3<S> {
    let [x, y, z] = v; // error: use of moved value: `v[..]`
    Vector3(x, y, z)
}

fn into_vec3_match<S>(v: [S, ..3]) -> Vector3<S> {
    match v {
        // error: use of moved value: `v[..]`
        [x, y, z] => Vector3(x, y, z),
    }
}

http://is.gd/bc1U2v

Note that it is impossible to work around this using transmute, because:

struct Vector3<S>(S, S, S);

fn into_vec3_transmute<S>(v: [S, ..3]) -> Vector3<S> {
    // error: cannot transmute from a type that contains type parameters
    unsafe { mem::transmute(v) }
}

http://is.gd/BeSWOs

@brendanzab brendanzab changed the title Cannot move out of destructures fixed length vectors in let and match Cannot move out of destructures of fixed length vectors in let and match Aug 11, 2014
brendanzab added a commit to rustgd/cgmath that referenced this issue Aug 11, 2014
Closes #111

`FixedArray::from_fixed` cannot yet be implemented due to  rust-lang/rust#16418
@brendanzab brendanzab changed the title Cannot move out of destructures of fixed length vectors in let and match Cannot move out of destructured fixed length vectors in let and match Aug 11, 2014
@milibopp
Copy link
Contributor

I am unsure whether it is a good idea, but another workaround involving transmutation to a box is possible and appears to work. (I have a suspicion though that this somehow messes up the memory.)

EDIT: ok, it is a bad idea, see below

struct Vec2<S>(S, S);

fn from_array<S>(arr: [S, ..2]) -> Vec2<S> {
    *unsafe { mem::transmute::<&[S, ..2], Box<Vec2<S>>>(&arr) }
}

@huonw
Copy link
Member

huonw commented Nov 22, 2014

That is incorrect and it can corrupt memory/crash the app/anything; it results in calling free on some random pointer into the stack, which is undefined behaviour.

It is more reliable to do:

struct Vec2<S>(S, S);
fn from_array(arr: [S, .. 2]) -> Vec<S> {
    unsafe {
        let x = Vec2(ptr::read(&arr[0]), ptr::read(&arr[1]));
        // stop the destructor running on the values in the array, i.e. transfer ownership:
        mem::forget(arr); 
        x
    }
}

@huonw
Copy link
Member

huonw commented Nov 22, 2014

Function arguments working differently suggests to me that there could be some memory safety bugs that are not caught (not with moving out of fixed length arrays directly, but possibly something similar).

@steveklabnik steveklabnik added the A-borrow-checker Area: The borrow checker label Jan 29, 2015
@steveklabnik
Copy link
Member

@Mark-Simulacrum Mark-Simulacrum added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 21, 2017
@matthewjasper
Copy link
Contributor

matthewjasper commented Jan 7, 2018

Fixed in MIR borrowck (and so NLL) cc #23121
Dupe of #26736

@Mark-Simulacrum
Copy link
Member

Yep, closing as duplicate of #26736.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-feature-request Category: A feature request, i.e: not implemented / a PR.
Projects
None yet
Development

No branches or pull requests

6 participants