Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upimpl Add<{str, Cow<str>}> for Cow<str> #36430
Conversation
alexcrichton
added
the
T-libs
label
Sep 13, 2016
This comment has been minimized.
This comment has been minimized.
|
r? @alexcrichton – or do we need to discuss this first? |
rust-highfive
assigned
alexcrichton
Sep 13, 2016
alexcrichton
reviewed
Sep 14, 2016
| if self == "" { | ||
| Cow::Borrowed(rhs) | ||
| } else if rhs == "" { | ||
| self.clone() |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Thanks for the PR! Could you expand on the rationale for this as well? E.g. it seems specifically for the optimization where one side is empty? |
This comment has been minimized.
This comment has been minimized.
|
Exactly. I have found this optimization while looking at Raph Levien's xi-editor, and thought it'd be a good idea to have it in libcollections. |
This comment has been minimized.
This comment has been minimized.
|
There's a relevant discussion happening in the internals forum right now: https://internals.rust-lang.org/t/implement-add-for-string-string/4088/7 Personally, I am opposed to adding further As an addendum to that, it may be a good idea to lay out what basic mathematical operator properties we like for the operator trait implementations to respect (commutativity, associativity, etc.). Obviously, as they are safe traits, such properties couldn't be relied on in safe code, but including an explanation of them in the docs would (hopefully) encourage the creation of implementations which respect users' intuitions for those operators. |
This comment has been minimized.
This comment has been minimized.
|
I know where you come from, but |
This comment has been minimized.
This comment has been minimized.
|
Yeah, you may be right given that string concatenation via |
This comment has been minimized.
This comment has been minimized.
|
I've tagged for discussion in libs triage, but I agree that it's probably too late to remove Also @llogiq can you add |
This comment has been minimized.
This comment has been minimized.
|
That took way longer than usual due to my notebook (which was broken by my kids) failing when it gets hot – for example during a Rust build. @alexcrichton should I add anything else? |
This comment has been minimized.
This comment has been minimized.
|
Ah nope, just waiting on the libs team to discuss. Our conclusion was that this should be good to go. Want to squash the commits as well? |
This comment has been minimized.
This comment has been minimized.
|
scratch that, the kid's sleeping, found the time to squash. |
llogiq
force-pushed the
llogiq:cow_add
branch
from
b9b4810
to
dd13a80
Sep 29, 2016
This comment has been minimized.
This comment has been minimized.
|
@bors: r+ Oh wow, congratulations! I can definitely take over from here :) |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Sep 29, 2016
ollie27
suggested changes
Sep 29, 2016
|
It might be worth adding tests for |
| @@ -270,3 +270,49 @@ impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> { | |||
| self | |||
| } | |||
| } | |||
|
|
|||
| #[stable(feature = "cow_add", since = "1.13.0")] | |||
This comment has been minimized.
This comment has been minimized.
| } else if rhs == "" { | ||
| self | ||
| } else { | ||
| Cow::Owned(self.into_owned() + rhs) |
This comment has been minimized.
This comment has been minimized.
ollie27
Sep 29, 2016
Contributor
If self is a Cow::Borrowed it would be better to use String::with_capacity to create the new string so we avoid an extra reallocation.
| impl<'a> AddAssign<&'a str> for Cow<'a, str> { | ||
| fn add_assign(&mut self, rhs: &'a str) { | ||
| if rhs == "" { return; } | ||
| self.to_mut().push_str(rhs); |
This comment has been minimized.
This comment has been minimized.
ollie27
Sep 29, 2016
Contributor
This doesn't behave the same as the Add implementations. If self is empty this should result in a Cow::Borrowed like with Add not Cow::Owned.
| @@ -0,0 +1,65 @@ | |||
| // Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT | |||
This comment has been minimized.
This comment has been minimized.
ollie27
Sep 29, 2016
Contributor
You'll need to add mod cow_str; to src/libcollectionstest/lib.rs for this file to be used.
Also I'm pretty sure "2012-2013-2014" isn't the correct year
| assert_eq!("Hello, Rustaceans!", borrowed1 + owned2); | ||
|
|
||
| assert_eq!("Hello, World!", owned1 + borrowed2); | ||
| assert_eq!("Hello, Rustaceans!", owned1 + owned2); |
This comment has been minimized.
This comment has been minimized.
ollie27
Sep 29, 2016
Contributor
These two should presumably start with "Hi, ".
Also owned1 and owned2 have been consumed by this point so will need cloning or something earlier.
| } | ||
| } | ||
|
|
||
| fn check_cow_add_assign() { |
This comment has been minimized.
This comment has been minimized.
| impl<'a> Add<&'a str> for Cow<'a, str> { | ||
| type Output = Cow<'a, str>; | ||
|
|
||
| fn add(self, rhs: &'a str) -> Self { |
This comment has been minimized.
This comment has been minimized.
ollie27
Sep 29, 2016
Contributor
I think it would be worth adding documentation to these implementations as the semantics aren't really obvious. Especially explaining why the lifetimes have been restricted like they have.
| type Output = Cow<'a, str>; | ||
|
|
||
| fn add(self, rhs: &'a str) -> Self { | ||
| if self == "" { |
llogiq commentedSep 12, 2016
cc #35837