.as_deref() not tranforming Option<&String> to Option<&str>, please help

⚓ Rust    📅 2025-09-24    👤 surdeus    👁️ 8      

surdeus

Warning

This post was published 37 days ago. The information described in this article may have changed.

Hello, I am somewhat new to the language. I came across some behavior that is a little bit confusing. I thought .as_deref() on an Option<&String> would return an Option<&str> through Deref coercion, but it is isn't. I tried looking at the documentation for both the .as_deref() method and the impl Deref for String part, and I can't figure out why it isn't returning an Option<&str>

#![allow(unused)]
fn main() {
    let p = String::from("hey");
    let x = Some(&p);
    assert_eq!(x.as_deref(), Some("hey"));
    
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
 --> src/main.rs:5:30
  |
5 |     assert_eq!(x.as_deref(), Some("hey"));
  |                              ^^^^^^^^^^^ expected `Option<&String>`, found `Option<&str>`
  |
  = note: expected enum `Option<&String>`
             found enum `Option<&str>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 1 previous error

I thought maybe this could be because the underlying .deref() could work differently on a &String than it does a String, but this shows otherwise:

    let test = String::from("hello");
    let op = Some(&test);
    println!("{}", type_name_of_val(&op));
    let wow = match op {
        Some(t) => Some(t.deref()),
        None => None,
    };

    println!("{}", type_name_of_val(&wow));

output:

:!cargo run
[No write since last change]
   Compiling chapter v0.1.0 (/home/duc/Documents/Projects/learning_rust/chapter-15/chapter)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
     Running `target/debug/chapter`
core::option::Option<&alloc::string::String>
core::option::Option<&str>

6 posts - 6 participants

Read full topic

🏷️ Rust_feed