Why does deref coercion not occur here?

[playground]

trait TextSized: Copy {
    fn text_size(self) -> usize;
}

impl TextSized for &'_ str {
    fn text_size(self) -> usize {
        self.len()
    }
}

fn takes_text_sized<T: TextSized>(_: T) {}

fn test(s: &String) {
    s.text_size();               //  ok
    takes_text_sized(s);         // nok
    takes_text_sized::<&str>(s); //  ok
}

Is this a limitation of the implementation or a (deliberate?) limitation of the language?

As an aside, a way to provide "deref coersion" via (a) blanket impl(s) of the trait, if one exists, would also be appreciated, but said blanket impls should not get in the way of implementing the trait for char or Rope. (This can include changing the signature of the trait; the ultimate goal is to have a function TextSize::of(_) that can take any "text like" handle, with the primitive inputs being &str and char.)

Deref coercion does not happen when it is converting into a generic parameter, because if that worked, someone might add an impl TextSized for &String later, silently changing behaviour of your code to use the other impl.

3 Likes

To expand on @alice's answer, More generally coercions won't happen if there is any type inference. This includes inferering generic parameters.

2 Likes