about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/slice/mod.rs9
-rw-r--r--library/core/src/slice/specialize.rs58
2 files changed, 60 insertions, 7 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 19a3b45e568..7db9c429212 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -34,6 +34,7 @@ mod iter;
 mod raw;
 mod rotate;
 mod sort;
+mod specialize;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use iter::{Chunks, ChunksMut, Windows};
@@ -2831,13 +2832,7 @@ impl<T> [T] {
     where
         T: Clone,
     {
-        if let Some((last, elems)) = self.split_last_mut() {
-            for el in elems {
-                el.clone_from(&value);
-            }
-
-            *last = value
-        }
+        specialize::SpecFill::spec_fill(self, value);
     }
 
     /// Fills `self` with elements returned by calling a closure repeatedly.
diff --git a/library/core/src/slice/specialize.rs b/library/core/src/slice/specialize.rs
new file mode 100644
index 00000000000..16a9588989c
--- /dev/null
+++ b/library/core/src/slice/specialize.rs
@@ -0,0 +1,58 @@
+use crate::ptr::write_bytes;
+
+pub(super) trait SpecFill<T> {
+    fn spec_fill(&mut self, value: T);
+}
+
+impl<T: Clone> SpecFill<T> for [T] {
+    default fn spec_fill(&mut self, value: T) {
+        if let Some((last, elems)) = self.split_last_mut() {
+            for el in elems {
+                el.clone_from(&value);
+            }
+
+            *last = value
+        }
+    }
+}
+
+impl<T: Copy> SpecFill<T> for [T] {
+    default fn spec_fill(&mut self, value: T) {
+        for item in self.iter_mut() {
+            *item = value;
+        }
+    }
+}
+
+impl SpecFill<u8> for [u8] {
+    fn spec_fill(&mut self, value: u8) {
+        // SAFETY: this is slice of u8
+        unsafe {
+            let ptr = self.as_mut_ptr();
+            let len = self.len();
+            write_bytes(ptr, value, len);
+        }
+    }
+}
+
+impl SpecFill<i8> for [i8] {
+    fn spec_fill(&mut self, value: i8) {
+        // SAFETY: this is slice of i8
+        unsafe {
+            let ptr = self.as_mut_ptr();
+            let len = self.len();
+            write_bytes(ptr, value as u8, len);
+        }
+    }
+}
+
+impl SpecFill<bool> for [bool] {
+    fn spec_fill(&mut self, value: bool) {
+        // SAFETY: this is slice of bool
+        unsafe {
+            let ptr = self.as_mut_ptr();
+            let len = self.len();
+            write_bytes(ptr, value as u8, len);
+        }
+    }
+}