-
-
Notifications
You must be signed in to change notification settings - Fork 52
Open
Description
Thanks for writing up the autoref specialization guide!
There's a similar technique which depends on Rust favoring inherent impls over traits.
Taking the DisplayToString example:
use std::fmt::{Display, Write};
pub trait DisplayToString {
fn my_to_string(&self) -> String;
}
pub struct DisplayToStringWrapper<'a, T: ?Sized>(pub &'a T);
// This is an inherent method, so it's tried first
impl<'a, T: AsRef<str> + ?Sized> DisplayToStringWrapper<'a, T> {
pub fn my_to_string(&self) -> String {
println!("called specialized impl");
self.0.as_ref().into()
}
}
// This is only used if the inherent method fails to type-check
impl<'a, T: Display + ?Sized> DisplayToString for DisplayToStringWrapper<'a, T> {
fn my_to_string(&self) -> String {
println!("blanket impl");
self.to_string()
}
}This can be more reliable than the autoref approach. For example, (&&String::from("hello")).my_to_string() will fall back to the slow path using autoref specialization but stick to the fast path with inherent impls. The drawback is that it only allows for one fallback case. Overall, I think this approach makes some interesting tradeoffs and may be worth calling (hehe) out in the article!
pickfire, ryanc-me, marcianx, 71 and akhilman
Metadata
Metadata
Assignees
Labels
No labels