Unnamed repository; edit this file 'description' to name the repository.
Merge rust-analyzer/text-size#23
23: Add a deref-removing impl for TextSized r=CAD97 a=CAD97 Notably, given `s: &SmolStr`, `TextSize::of(s)` does not work, where `TextUnit::of_str(s)` did, because the concrete type could be deref-coerced to. (It's probably a limitation of the language that deref coersion does not apply here, but it's one we have to live with.) So we provide a blanket impl for any type that derefs (directly) to `str`. Alternatively, we can provide a deeper blanket impl that derefs any number of references recursively [[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=008b5e0c2edd332b34b3efa42ce2a40a)]: ```rust impl<D> TextSized for &'_ D where D: Deref, for<'a> &'a D::Target: TextSized, { #[inline] fn text_size(self) -> TextSize { self.deref().text_size() } } ``` This is "only" at the cost of a little extra impl complexity. Co-authored-by: CAD97 <[email protected]>
bors[bot] 2020-03-24
parent 3f4556b · parent 5468ef0 · commit 3d1a768
-rw-r--r--lib/text-size/src/traits.rs15
-rw-r--r--lib/text-size/tests/constructors.rs31
2 files changed, 45 insertions, 1 deletions
diff --git a/lib/text-size/src/traits.rs b/lib/text-size/src/traits.rs
index 7064dbc658..6f3462bee5 100644
--- a/lib/text-size/src/traits.rs
+++ b/lib/text-size/src/traits.rs
@@ -1,4 +1,7 @@
-use {crate::TextSize, std::convert::TryInto};
+use {
+ crate::TextSize,
+ std::{convert::TryInto, ops::Deref},
+};
/// Text-like structures that have a text size.
pub trait TextSized: Copy {
@@ -15,6 +18,16 @@ impl TextSized for &'_ str {
}
}
+impl<D> TextSized for &'_ D
+where
+ D: Deref<Target = str>,
+{
+ #[inline]
+ fn text_size(self) -> TextSize {
+ self.deref().text_size()
+ }
+}
+
impl TextSized for char {
#[inline]
fn text_size(self) -> TextSize {
diff --git a/lib/text-size/tests/constructors.rs b/lib/text-size/tests/constructors.rs
new file mode 100644
index 0000000000..eba587b539
--- /dev/null
+++ b/lib/text-size/tests/constructors.rs
@@ -0,0 +1,31 @@
+use {
+ std::{borrow::Cow, ops::Deref},
+ text_size::*,
+};
+
+struct StringLike<'a>(&'a str);
+
+impl Deref for StringLike<'_> {
+ type Target = str;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[test]
+fn main() {
+ let s = "";
+ let _ = TextSize::of(&s);
+
+ let s = String::new();
+ let _ = TextSize::of(&s);
+
+ let s = Cow::Borrowed("");
+ let _ = TextSize::of(&s);
+
+ let s = Cow::Owned(String::new());
+ let _ = TextSize::of(&s);
+
+ let s = StringLike("");
+ let _ = TextSize::of(&s);
+}