diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 45daabf86ab..4db6d5d715c 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -104,7 +104,6 @@ macro_rules! spezialize_for_lengths { ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => { let mut target = $target; let iter = $iter; - let sep_len = $separator.len(); let sep_bytes = $separator; match $separator.len() { $( @@ -112,46 +111,31 @@ macro_rules! spezialize_for_lengths { // specialize the cases with small separator lengths $num => { for s in iter { - target.get_unchecked_mut(..$num) - .copy_from_slice(sep_bytes); - - let s_bytes = s.borrow().as_ref(); - let offset = s_bytes.len(); - target = {target}.get_unchecked_mut($num..); - target.get_unchecked_mut(..offset) - .copy_from_slice(s_bytes); - target = {target}.get_unchecked_mut(offset..); + copy_slice_and_advance!(target, sep_bytes); + copy_slice_and_advance!(target, s.borrow().as_ref()); } }, )* - 0 => { - // concat, same principle without the separator - for s in iter { - let s_bytes = s.borrow().as_ref(); - let offset = s_bytes.len(); - target.get_unchecked_mut(..offset) - .copy_from_slice(s_bytes); - target = {target}.get_unchecked_mut(offset..); - } - }, _ => { // arbitrary non-zero size fallback for s in iter { - target.get_unchecked_mut(..sep_len) - .copy_from_slice(sep_bytes); - - let s_bytes = s.borrow().as_ref(); - let offset = s_bytes.len(); - target = {target}.get_unchecked_mut(sep_len..); - target.get_unchecked_mut(..offset) - .copy_from_slice(s_bytes); - target = {target}.get_unchecked_mut(offset..); + copy_slice_and_advance!(target, sep_bytes); + copy_slice_and_advance!(target, s.borrow().as_ref()); } } } }; } +macro_rules! copy_slice_and_advance { + ($target:expr, $bytes:expr) => { + let len = $bytes.len(); + $target.get_unchecked_mut(..len) + .copy_from_slice($bytes); + $target = {$target}.get_unchecked_mut(len..); + } +} + // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262) // For this reason SliceConcatExt is not specialized for T: Copy and SliceConcatExt is the @@ -192,7 +176,7 @@ where // copy separator and strs over without bounds checks // generate loops with hardcoded offsets for small separators // massive improvements possible (~ x2) - spezialize_for_lengths!(sep, target, iter; 1, 2, 3, 4); + spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); } result.set_len(len); }