When and why does this error happen?

Warning: this post contains some bad LLM-code.

Rust beginner here. I read this error which am interested to understand:

An LLM fails to produce an example that fails with the error:

use std::ops::Deref;

fn take_ref(s: &str) {
    println!("{}", s);
}

fn main() {
    let boxed: Box<String> = Box::new("hello".to_string());
    let ref_str: &<Box<String> as Deref>::Target = &*boxed;
    take_ref(ref_str); // ERROR: expected `&str`, found `&String`
}

Besides, I expected ref_str to be &String; the annotation is overwhelming. It seems to mean "The result of deref as implemented for Box<String>".

The LLM-comment is wrong since &String will coerce since a function argument is a type coercion site.
So one expects that to pass, and it does.

I do understand LLMs make mistakes, but since I study their errors and do not paste their output in my codebase, they kind of are for me.
Could you provide help with:

  1. A minimal, simple example (or a link to one) to actually reproduce the error at the top
  2. Some context / explanation or recommended reading.

I suspect that part of the explanation has to do with the desugaring but can't quite go through it.

Thank you!

use std::ops::Deref;

#[derive(Debug)]
struct Target;

fn take_target(t: &Target) {
    println!("{t:?}");
}

fn take_deref<T>(t: T)
where
    T: Deref,
{
    take_target(t.deref())
}

fn main() {
    let s = "hello".to_string();
    take_deref(s);
}
   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:14:17
   |
14 |     take_target(t.deref())
   |     ----------- ^^^^^^^^^ expected `&Target`, found `&<T as Deref>::Target`
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected reference `&Target`
              found reference `&<T as Deref>::Target`
note: function defined here
  --> src/main.rs:6:4
   |
6  | fn take_target(t: &Target) {
   |    ^^^^^^^^^^^ ----------
help: consider constraining the associated type `<T as Deref>::Target` to `Target`
   |
12 |     T: Deref<Target = Target>,
   |             +++++++++++++++++

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

In case it is not clear: The function expects a reference to the concrete type Target, but receives an argument of whatever the associated type Target of the type implementing Deref happens to be.

Also the example you quoted is ten years old. It is certainly possible, that back in the dark ages, type coercion worked differently, or not at all (I'm only using Rust since a couple of years).

3 Likes

I see, what a mess of Targets. I tried with:

#[derive(Debug)]
struct MyTarget;

fn take_target(t: &MyTarget) {
    println!("{t:?}");
}

after reading your code and the last explanation. I find the error easier to interpret this way:

14 |     take_target(t.deref())
   |     ----------- ^^^^^^^^^ expected `&MyTarget`, found `&<T as Deref>::Target`

So it expected &MyTarget, but received a ref to whatever &MyTarget dereferences to.

I wonder if this was made even more obscure in that post by using the same words. Still it was a superb read.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.