-
Notifications
You must be signed in to change notification settings - Fork 13.3k
implement From<Vec<char>>
and From<&'a [char]>
for String
#35054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I know that |
|
s.push(c); | ||
} | ||
s | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably makes sense to delegate to the &[char]
impl here instead of duplicating the code.
It's possible we could do something clever to reuse the Vec
s buffer, though I don't think it's worth thinking about in this PR.
That's an unstable optimization for purely ASCII text. A single non-ascii character in the string of any size (think of © or «) and the buffer is guaranteed to be reallocated. It may be reasonable to use some small correction ( |
@petrochenkov Yes, a single non-ASCII character will change that. However, this is what we do everywhere, allocations are always based on the minimum capacity that will be necessary (it's always the |
Thanks for the suggestions everyone. I'll be back online in a couple hours & I'll push some changes. -------- Original message -------- @petrochenkov Yes, a single non-ASCII character will change that. However, this is what we do everywhere, allocations are always based on the minimum capacity that will be necessary (it's always the Iterator::size_hint().0 that is used for initial capacity). — |
Sounds reasonable to me! |
4f775cc
to
b3f2a2f
Compare
Is it ok to leave the impl as |
r? @brson |
I feel like the impl From<Vec<char>> for String {
fn from(mut v: Vec<char>) -> String {
unsafe {
let ptr = v.as_mut_ptr() as *mut u8;
let mut bytes = 0;
{
let mut rest = v.as_mut_slice();
while let Some((chr, rest_)) = {rest}.split_first_mut() {
for byte in chr.encode_utf8() {
*ptr.offset(bytes) = byte;
bytes += 1;
}
rest = rest_;
}
}
let cap = v.capacity();
::std::mem::forget(v);
String::from_raw_parts(ptr, bytes as usize, cap)
}
}
}
// Perhaps this code could be made better, I didn’t ponder much on it. |
@nagisa as @brson mentioned earlier we could indeed do things like reuse the buffer, but for now it doesn't seem worth the unsafe complexity when no one's clamboring for it. @pwoolcoc yeah I think it's best to stay concrete and avoid generics for |
thanks @alexcrichton, I think it is ready to go but I am unable to replicate the test failure that travis is reporting |
Ah yeah that's ok, if you rebase on master it should fix it as the PR to solve that problem went in a few hours ago |
Though there are ways to convert a slice or vec of chars into a string, it would be nice to be able to just do `String::from(['a', 'b', 'c'])`, so this PR implements `From<Vec<char>>` and `From<&'a [char]>` for String.
b3f2a2f
to
ac73335
Compare
Seems to go at odds with the philosophy of I’d like to point out that I implemented the code I pasted above manually two or three times already in various locations and so far the desire to reuse the allocation was pretty strong in each use-case. The implementation as proposed by the PR is plain useless as far as I’m and my code are concerned, which is exactly why I am complaining. Shall I send a PR against this PR? |
@pwoolcoc The next steps are to wait for the libs team to approve the new APIs. Typically this takes until next tuesday, though if enough of them chime in here it could go faster. @nagisa I recognize that optimization is desirable, but still prefer to do it as a follow up, for a few reasons: unsafe optimizations require a different set of eyes and more thorough review; I want to lower barriers to contribution, not frustrate contributors by expanding the scope of PRs, make landing small contributions faster; generally, I'd like to hold up fewer issues by waiting for perfection, and be more willing to settle for incremental progress. (On the subject of making small / first-time contributions faster - it is quite frustrating that any minor lib feature enhancements have a week turnaround waiting for the libs team to meet face-to-face. Very bad contributor experience.) |
@brson ok, thanks! |
@bors r+ libs team is happy |
📌 Commit ac73335 has been approved by |
implement `From<Vec<char>>` and `From<&'a [char]>` for `String` Though there are ways to convert a slice or vec of chars into a string, it would be nice to be able to just do `String::from(&['a', 'b', 'c'])`, so this PR implements `From<Vec<char>>` and `From<&'a [char]>` for String.
Revert "implement `From<Vec<char>>` and `From<&'a [char]>` for `String`" This reverts commit ac73335. This is a revert of #35054, which resulted in at least 7 known regressions, reported [here](https://internals.rust-lang.org/t/regression-report-stable-2016-08-16-vs-beta-2016-09-21/4119) and [here](#36352), which will hit stable next week. I think this breakage was somewhat unanticipated, and we did not realize so many crates were broken until this week, so reverting is the conservative thing to do until we figure out how not to cause so much breakage. I've run crater on the revert and did not find any new breakage from the revert. Fixes #36352 cc @pwoolcoc @rust-lang/libs
Though there are ways to convert a slice or vec of chars into a string,
it would be nice to be able to just do
String::from(&['a', 'b', 'c'])
,so this PR implements
From<Vec<char>>
andFrom<&'a [char]>
forString.