Why can't I pass Option<&mut T> like I can &mut T

⚓ Rust    📅 2026-05-22    👤 surdeus    👁️ 2      

surdeus

In the first module here (no_opt), I can pass ctx to various helpers without any ceremony. In the second module (with_opt) I make that ctx optional. Now, it won't compile. I understand the error message, in a way, but I'm also confused by the difference here.

In the first case, I have a pointer. In the second, all I've done is say this pointer can also be null (0x0), so I feel like the code shouldn't have to change much. Is this because the first case is doing some transparent "reborrow" for me, which then stops with the addition of Option<...>?

How to say what I mean in with_opt with minimal syntactic clutter?

(playground)

struct Ctx { }
struct Stuff { a: A, b: B }
struct A {}
struct B {} 

mod no_opt {
    use super::*;
    pub fn make_stuff(ctx: &mut Ctx) -> Stuff {
        let a = make_a(ctx);
        let b = make_b(ctx);
        Stuff { a, b }
    }
    fn make_a(_ctx: &mut Ctx) -> A { A {} }
    fn make_b(_ctx: &mut Ctx) -> B { B {} }
}

mod with_opt {
    use super::*;
    pub fn make_stuff(ctx: Option<&mut Ctx>) -> Stuff {
        let a = make_a(ctx);
        let b = make_b(ctx);
        Stuff { a, b }
    }
    fn make_a(_ctx: Option<&mut Ctx>) -> A { A {} }
    fn make_b(_ctx: Option<&mut Ctx>) -> B { B {} }
}

fn main() {
    let mut ctx = Ctx {};
    no_opt::make_stuff(&mut ctx);
    with_opt::make_stuff(Some(&mut ctx));
    println!("Done.");
}

Error:

error[E0382]: use of moved value: `ctx`
  --> src/main.rs:23:24
   |
21 |     pub fn make_stuff(ctx: Option<&mut Ctx>) -> Stuff {
   |                       --- move occurs because `ctx` has type `Option<&mut Ctx>`, which does not implement the `Copy` trait
22 |         let a = make_a(ctx);
   |                        --- value moved here
23 |         let b = make_b(ctx);
   |                        ^^^ value used here after move
   |
note: consider changing this parameter type in function `make_a` to borrow instead if owning the value isn't necessary
  --> src/main.rs:26:21

3 posts - 3 participants

Read full topic

🏷️ Rust_feed