Illegal move, but I drop on the next line

⚓ rust    📅 2025-07-02    👤 surdeus    👁️ 2      

surdeus

Hey guys, I have this situation where I have optional structs that include other optional structs. And I am trying to move and Option to a new place, but accidentally, I introduce sharing of a reference and the compiler complains:

line: some_bar.string = Some(*string);

cannot move out of `*string` which is behind a shared reference
move occurs because `*string` has type `String`, which does not implement the `Copy` trait
consider cloning the value if the performance cost is acceptable: `.clone()`

But - on the next line I do a drop of the value that the reference string points to:

some_bar.baz = None;

Full code:

struct Foo {
    bar: Option<Bar>
}

struct Bar {
    baz: Option<Baz>,
    string: Option<String>,
}

struct Baz {
    string: Option<String>,
}

fn example(foo: Foo) {
    let mut foo = Foo { bar: None };
    match foo.bar {
        None => (),
        Some(ref mut some_bar) => {
            match some_bar.baz.as_mut() {
                None => (),
                Some(some_baz) => {
                    match &some_baz.string {
                        None => (),
                        Some(string) => {
                            some_bar.string = Some(*string);
                            some_bar.baz = None;
                        }
                    }
                }
            }
        }
    }
}

Can you please explain to me, why am I wrong? I hoped that the compiler would see that I am dropping the container which contains the value referenced in string and thus would allow me to do the move...

1 post - 1 participant

Read full topic

🏷️ rust_feed