Closed
Description
Calling .as_deref() on an Option<Box> does not resolve to Option<&str> as expected.
It seems to resolve to Option<&Box>, leading to a type mismatch (expected &str, found &String) when pattern matching string literals.
This behavior is unexpected, especially given that Box should deref to String, and String to str.
I tried this code:
fn main() {
let user_mail: Option<Box<String>> = Some(Box::new("[email protected]".to_string()));
// This should return Option<&str>
let string_slice = user_mail.as_deref();
match string_slice {
Some("[email protected]") => println!("Matched!"),
Some(other) => println!("Other: {}", other),
None => println!("None"),
}
}
I expected to see this happen: .as_deref() on Option<Box> should dereference all the way to Option<&str>, making it matchable with &str literals directly.
Instead, this happened: (mail underlined on this line : Some("[email protected]") => println!("Matched!"))
error[E0308]: mismatched types
expected `&String`
found `&str`
Meta
- ✅ Bug still occurs on
stable
(1.86.0) - ✅ Bug also occurs on
beta
- ✅ Bug also occurs on
nightly
rustc --version --verbose
:
rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-apple-darwin
release: 1.86.0
LLVM version: 19.1.7
Backtrace
Not applicable — no panic occurred.
💡 Workaround (Manual Pattern Matching)
While .as_deref()
fails to resolve as expected, the following pattern using .as_str()
works correctly and behaves as intended:
fn main() {
let user_mail: Option<Box<String>> = Some(Box::new("[email protected]".to_string()));
match user_mail {
Some(ref boxed_string) if boxed_string.as_str() == "[email protected]" => {
println!("user mail OK!");
}
Some(ref other) => {
println!("user mail KO!: {}", other);
}
None => {
println!("No user email");
}
}
}