#Moving out of shared reference (E0507)

11 messages · Page 1 of 1 (latest)

trim oracle
#
enum Foo {
    Alpha(i32),
    Beta
}

struct Container {
    value: Foo,
}

fn main() {
    let mut cont = Some(Container { value: Foo::Alpha(10) });

    let mut a = 0;
    if let Some(mut c) = &cont {
        match &mut c.value {
            Foo::Alpha(i) => *i += a,
            Foo::Beta => a = 5,
        }
    }

    if let Some(c) = cont {
        match c.value {
            Foo::Alpha(i) => println!("{i}"),
            Foo::Beta => ()
        }
    }
}

In this example, I don't understand why cont loses ownership of the container in the first part. I make a mutable reference to it, then I don't read cont again until the reference is out of scope, at which point it is supposed to return to cont.

#

My actual code was too verbose to explain so I remade a simpler version of the problem to try to fix it

hazy laurel
#

the error the compiler produces on this code is a little confusing

#

but the fundamental problem is that if you want to modify the value you must not have any &, only &mut

#

do this instead in the first if let

    if let Some(c) = &mut cont {
#

also you could choose to combine the if lets and the matches:

#

oh, hm, that's a little more verbose than I thought due to the Container; never mind

trim oracle
#

I see, thanks

#

Out of curiosity, what is the way to combine them if there wasn't a struct?

hazy laurel
#

like

match &mut cont {
    Some(Foo::Alpha(i)) => { ...
    Some(Foo::Beta) => { ...
    None => {}
}
#

you can still do that with the struct present, it just gets lengthy such that the if let is nicer