@@ -3658,6 +3658,10 @@ impl String {
36583658 while let Some ( l_c) = wc. pop ( ) {
36593659 l_c. to_uppercase ( ) . for_each ( |u_c| wc. write ( u_c) ) ;
36603660 }
3661+ // SAFETY: At this point, none of the methods of wc panicked
3662+ unsafe {
3663+ wc. finalize ( ) ;
3664+ }
36613665 }
36623666
36633667 /// Converts this string to its lowercase equivalent in-place.
@@ -3725,6 +3729,10 @@ impl String {
37253729 u_c. is_cased ( ) || ( word_final_so_far && u_c. is_case_ignorable ( ) ) ;
37263730 }
37273731 }
3732+ // SAFETY: At this point, none of the methods of wc panicked
3733+ unsafe {
3734+ wc. finalize ( ) ;
3735+ }
37283736 }
37293737}
37303738
@@ -3734,39 +3742,19 @@ impl String {
37343742struct WriteChars < ' a > {
37353743 // This is the internal buffer of the string temporarily changed to Vec<u8> because
37363744 // it will contain non utf8 bytes.
3737- // invariant: self.v.len() == original string until drop is run
3745+ // invariant: self.v.len() == original string until finalize is run
37383746 v : Vec < u8 > ,
37393747 // A reference kept to restore the string at the end
3740- // (ie drop time)
3748+ // (ie finalize time)
37413749 s : & ' a mut String ,
37423750 // invariant: write_offset <= read_offset
37433751 write_offset : usize ,
37443752 // invariant: self.read_offset <= self.v.len()
3745- // before the Drop
3753+ // before finalize
37463754 read_offset : usize ,
37473755 buffer : VecDeque < u8 > ,
37483756}
37493757
3750- impl < ' a > Drop for WriteChars < ' a > {
3751- // Set the proper length of the string's storage
3752- // or grow it to add what is still in the buffer.
3753- fn drop ( & mut self ) {
3754- if self . buffer . is_empty ( ) {
3755- // SAFETY: if the queue is empty, then
3756- // there were less bytes than in the original so we can simply shrink
3757- unsafe {
3758- self . v . set_len ( self . write_offset ) ;
3759- }
3760- } else {
3761- let ( q1, q2) = self . buffer . as_slices ( ) ;
3762- self . v . extend_from_slice ( q1) ;
3763- self . v . extend_from_slice ( q2) ;
3764- } ;
3765- // SAFETY: this is valid utf8
3766- * self . s = unsafe { String :: from_utf8_unchecked ( core:: mem:: take ( & mut self . v ) ) }
3767- }
3768- }
3769-
37703758#[ unstable( issue = "none" , feature = "std_internals" ) ]
37713759impl < ' a > WriteChars < ' a > {
37723760 fn new ( s : & ' a mut String ) -> Self {
@@ -3806,4 +3794,26 @@ impl<'a> WriteChars<'a> {
38063794 self . write_offset += direct_copy_length;
38073795 self . buffer . extend ( & buffer[ direct_copy_length..len] ) ;
38083796 }
3797+
3798+ // Set the proper length of the string's storage
3799+ // or grow it to add what is still in the buffer.
3800+ /// Finalize should be run for the modifications to be actually written back to the string
3801+ /// # Safety
3802+ /// Must not be called if one of the previous method calls of self panicked because the buffer
3803+ /// may contain invalid utf8
3804+ unsafe fn finalize ( mut self ) {
3805+ if self . buffer . is_empty ( ) {
3806+ // SAFETY: if the queue is empty, then
3807+ // there were less bytes than in the original so we can simply shrink
3808+ unsafe {
3809+ self . v . set_len ( self . write_offset ) ;
3810+ }
3811+ } else {
3812+ let ( q1, q2) = self . buffer . as_slices ( ) ;
3813+ self . v . extend_from_slice ( q1) ;
3814+ self . v . extend_from_slice ( q2) ;
3815+ } ;
3816+ // SAFETY: this is valid utf8
3817+ * self . s = unsafe { String :: from_utf8_unchecked ( core:: mem:: take ( & mut self . v ) ) }
3818+ }
38093819}
0 commit comments