I want to specialize &'static str
from &'a str
:
use std::borrow::Cow;
struct MyString {
inner: Cow<'static, str>,
}
impl From<&'static str> for MyString {
fn from(x: &'static str) -> Self {
MyString {
inner: Cow::Borrowed(x),
}
}
}
impl<T: Into<String>> From<T> for MyString {
fn from(x: T) -> Self {
MyString {
inner: Cow::Owned(x.into()),
}
}
}
fn main() {
match MyString::from("foo").inner {
Cow::Borrowed(..) => (),
_ => {
panic!();
}
}
let s = String::from("bar");
match MyString::from(s.as_ref()).inner {
Cow::Owned(..) => (),
_ => {
panic!();
}
}
match MyString::from(String::from("qux")).inner {
Cow::Owned(..) => (),
_ => {
panic!();
}
}
}
The gist is that MyString
stores a statically-allocated string literal as a &'static str
and all other strings as a String
. This allows MyString
to avoid having a lifetime parameter—i.e., MyString<'a>
, which is critical for my API, all while allowing the caller to pass in any kind of string and have MyString
automatically do the correct thing.
The problem is that the code doesn't compile:
error[E0119]: conflicting implementations of trait `std::convert::From<&'static str>` for type `MyString`:
--> src/main.rs:15:1
|
7 | impl From<&'static str> for MyString {
| ------------------------------------ first implementation here
...
15 | impl<T: Into<String>> From<T> for MyString {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyString`
Is there any trick that allows me to do what I want? If not, is lifetime specialization something that Rust will ever support?
Rust 1.51.0 does not have specialization of any kind. If I'm reading the specialization RFC correctly, then lifetime specialization will not be supported even when the RFC is implemented:
A hard constraint in the design of the trait system is that dispatch cannot depend on lifetime information. In particular, we both cannot, and should not allow specialization based on lifetimes:
We can't, because when the compiler goes to actually generate code ("trans"), lifetime information has been erased -- so we'd have no idea what specializations would soundly apply.
We shouldn't, because lifetime inference is subtle and would often lead to counterintuitive results. For example, you could easily fail to get
'static
even if it applies, because inference is choosing the smallest lifetime that matches the other constraints.
(Emphasis mine)
There's some examples further in the link that indicate some of the concrete issues.
I recommend using a Cow
to handle the "owned or borrowed" case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With