Why can't I pass Option<&mut T> like I can &mut T
⚓ Rust 📅 2026-05-22 👤 surdeus 👁️ 2In 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?
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
🏷️ Rust_feed