Summary
Add a Coerce trait that will let create/update functions to also accept &Vec<T>/&String wherever &[T]/&str is expected.
Motivation
Ergonomics. We get rid of some (most?) of the as_slice() calls. Users would be able to change code that looks like this string.push_str(another_string.as_slice()) to string.push_str(&another_string).
Detailed design
We add a Coerce trait that we’ll let us “coerce” a &Vec<T> into a &[T]. The signature looks like this:
trait Coerce<P> {
fn coerce(self) -> P;
}
Then we can implement it on &Vec<T> and &[T]:
impl<'a, T> Coerce<&'a [T]> for &'a [T] {
fn coerce(self) -> &'a [T] {
self
}
}
impl<'a, T> Coerce<&'a [T]> for &'a Vec<T> {
fn coerce(self) -> &'a [T] {
self.as_slice()
}
}
Now we can change any function/method that expects a &[T] to actually accept &Vec<T> or &[T]. As an example, the append method would become:
fn append<S: Coerce<&'a [T]>>(mut self, second: S) -> Vec<T> {
self.push_all(second.coerce());
self
}
This new append method would allow this:
let v1 = vec!(1u8, 2, 3);
let v2 = vec!(4u8, 5, 6);
let v3 = v1.append(&v2); // you can still use `v1.append(v2.as_slice())`
(Toy example in the playpen)
This treatment can also be applied to the String/&str pair.
Implementation “plan”
-
&Vec<T> and &[T] will implement Coerce<&[T]>
-
&String and &str will implement Coerce<&str>
- Update all the functions/methods in the standard library from accepting
&str/&[T] to accept S where S: Coerce<&str>/S: Coerce<&[T]>.
This last step should break a minimal amount of code (I’m not 100% sure), because the updated functions would still accept &[T]/&str.
Drawbacks
- The signature of functions/methods become more complex.
Alternatives
Don’t do this, and use of the following alternatives:
Advantages of this proposal over the alternatives
- Can be implemented right now.
- It doesn’t need a lang item nor DST.
- Shortest notation:
&string vs &*string vs string[..] vs string.as_slice()
Ultimately if this doesn’t get implemented in the standard library, users can still implement this idea in their libraries.
Open questions
-
&mut Vec<T> could implement Coerce<&'a mut [T]>, but I’m not sure if that’s actually useful.
This just occurred to me in the morning, I figured I’d post it as a Pre-RFC to get feedback on the idea. I’m especially interested in hearing why do you think we should not do this.