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:
A minimal, simple example (or a link to one) to actually reproduce the error at the top
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.
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 typeTarget, but receives an argument of whatever the associated typeTarget 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).