Recently ran into this problem when looking into extending the Pattern API for slices.
Essentially the problem is that we can impl Pattern<&[T]> for &[T]
and use that in various associated functions like
pub fn starts_with<'a, P: Pattern<&'a [T]>>(&'a self, pattern: P) -> bool
However, that will break existing usage that depends on deref coercion:
error[E0277]: the trait bound `&Vec<{integer}>: Pattern<&[{integer}]>` is not satisfied
--> library/alloc/benches/slice.rs:98:31
|
98 | b.iter(|| vec.starts_with(&match_vec))
| ----------- ^^^^^^^^^^ the trait `Pattern<&[{integer}]>` is not implemented for `&Vec<{integer}>`
| |
| required by a bound introduced by this call
This is quite unfortunate, as it means that we can't use the Pattern
API to implement this.
I found one reference to this behavior at Suggest dereference operations when a deref coercion won't work · Issue #39029 · rust-lang/rust · GitHub, which suggests that this was an explicit decision that is unlikely to be reversed.
My thoughts
Why can't we enable this for references? In every case of a reference, the impl just calls out to &Self::Target
anyways. For instance, impl Pattern for &String
just delegates to &str
.
Could negative bounds help here? We could add something like
impl<'p, 'hs, T, V> Pattern<&'hs [T]> for &'p V
where
T: PartialEq + 'p,
V: ops::Deref<Target = [T]>,
V != T, // otherwise this conflicts with impl for &T