about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-10 08:29:33 +0000
committerbors <bors@rust-lang.org>2023-07-10 08:29:33 +0000
commit3ea096a28d6ebd00564869d62ece822af9743c6c (patch)
tree5803fda00e2ed5bfbff938e19453324144075fa4 /library/std/src
parent510277748ae729f1f81544d83b3e7af19cac9a70 (diff)
parenta3fdf75d126a02da4c27fd9e1cc16bdc93a5f133 (diff)
downloadrust-3ea096a28d6ebd00564869d62ece822af9743c6c.tar.gz
rust-3ea096a28d6ebd00564869d62ece822af9743c6c.zip
Auto merge of #2974 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/f32.rs5
-rw-r--r--library/std/src/f64.rs35
-rw-r--r--library/std/src/io/copy.rs81
-rw-r--r--library/std/src/io/copy/tests.rs38
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/sys/mod.rs50
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs (renamed from library/std/src/personality/dwarf/eh.rs)0
-rw-r--r--library/std/src/sys/personality/dwarf/mod.rs (renamed from library/std/src/personality/dwarf/mod.rs)0
-rw-r--r--library/std/src/sys/personality/dwarf/tests.rs (renamed from library/std/src/personality/dwarf/tests.rs)0
-rw-r--r--library/std/src/sys/personality/emcc.rs (renamed from library/std/src/personality/emcc.rs)0
-rw-r--r--library/std/src/sys/personality/gcc.rs (renamed from library/std/src/personality/gcc.rs)0
-rw-r--r--library/std/src/sys/personality/mod.rs (renamed from library/std/src/personality.rs)0
12 files changed, 170 insertions, 40 deletions
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index bed90418be1..bc532990e94 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -500,10 +500,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f32 {
-        #[cfg(target_os = "android")]
-        return crate::sys::android::log2f32(self);
-        #[cfg(not(target_os = "android"))]
-        return unsafe { intrinsics::log2f32(self) };
+        crate::sys::log2f32(self)
     }
 
     /// Returns the base 10 logarithm of the number.
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index e72de05ca41..5af9f8bcb23 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -456,7 +456,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f64 {
-        self.log_wrapper(|n| unsafe { intrinsics::logf64(n) })
+        crate::sys::log_wrapper(self, |n| unsafe { intrinsics::logf64(n) })
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -500,12 +500,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f64 {
-        self.log_wrapper(|n| {
-            #[cfg(target_os = "android")]
-            return crate::sys::android::log2f64(n);
-            #[cfg(not(target_os = "android"))]
-            return unsafe { intrinsics::log2f64(n) };
-        })
+        crate::sys::log_wrapper(self, crate::sys::log2f64)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -525,7 +520,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f64 {
-        self.log_wrapper(|n| unsafe { intrinsics::log10f64(n) })
+        crate::sys::log_wrapper(self, |n| unsafe { intrinsics::log10f64(n) })
     }
 
     /// The positive difference of two numbers.
@@ -962,28 +957,4 @@ impl f64 {
     pub fn atanh(self) -> f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
-
-    // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
-    // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
-    // of expected NaN).
-    #[rustc_allow_incoherent_impl]
-    fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
-        if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
-            log_fn(self)
-        } else if self.is_finite() {
-            if self > 0.0 {
-                log_fn(self)
-            } else if self == 0.0 {
-                Self::NEG_INFINITY // log(0) = -Inf
-            } else {
-                Self::NAN // log(-n) = NaN
-            }
-        } else if self.is_nan() {
-            self // log(NaN) = NaN
-        } else if self > 0.0 {
-            self // log(Inf) = Inf
-        } else {
-            Self::NAN // log(-Inf) = NaN
-        }
-    }
 }
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index ef1f4031ef2..3322940d245 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -1,4 +1,8 @@
 use super::{BorrowedBuf, BufReader, BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
+use crate::alloc::Allocator;
+use crate::cmp;
+use crate::collections::VecDeque;
+use crate::io::IoSlice;
 use crate::mem::MaybeUninit;
 
 #[cfg(test)]
@@ -86,7 +90,7 @@ where
 
 /// Specialization of the read-write loop that reuses the internal
 /// buffer of a BufReader. If there's no buffer then the writer side
-/// should be used intead.
+/// should be used instead.
 trait BufferedReaderSpec {
     fn buffer_size(&self) -> usize;
 
@@ -104,7 +108,39 @@ where
     }
 
     default fn copy_to(&mut self, _to: &mut (impl Write + ?Sized)) -> Result<u64> {
-        unimplemented!("only called from specializations");
+        unreachable!("only called from specializations")
+    }
+}
+
+impl BufferedReaderSpec for &[u8] {
+    fn buffer_size(&self) -> usize {
+        // prefer this specialization since the source "buffer" is all we'll ever need,
+        // even if it's small
+        usize::MAX
+    }
+
+    fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
+        let len = self.len();
+        to.write_all(self)?;
+        *self = &self[len..];
+        Ok(len as u64)
+    }
+}
+
+impl<A: Allocator> BufferedReaderSpec for VecDeque<u8, A> {
+    fn buffer_size(&self) -> usize {
+        // prefer this specialization since the source "buffer" is all we'll ever need,
+        // even if it's small
+        usize::MAX
+    }
+
+    fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
+        let len = self.len();
+        let (front, back) = self.as_slices();
+        let bufs = &mut [IoSlice::new(front), IoSlice::new(back)];
+        to.write_all_vectored(bufs)?;
+        self.clear();
+        Ok(len as u64)
     }
 }
 
@@ -218,6 +254,47 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
     }
 }
 
+impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
+    fn buffer_size(&self) -> usize {
+        cmp::max(DEFAULT_BUF_SIZE, self.capacity() - self.len())
+    }
+
+    fn copy_from<R: Read + ?Sized>(&mut self, reader: &mut R) -> Result<u64> {
+        let mut bytes = 0;
+
+        // avoid allocating before we have determined that there's anything to read
+        if self.capacity() == 0 {
+            bytes = stack_buffer_copy(&mut reader.take(DEFAULT_BUF_SIZE as u64), self)?;
+            if bytes == 0 {
+                return Ok(0);
+            }
+        }
+
+        loop {
+            self.reserve(DEFAULT_BUF_SIZE);
+            let mut buf: BorrowedBuf<'_> = self.spare_capacity_mut().into();
+            match reader.read_buf(buf.unfilled()) {
+                Ok(()) => {}
+                Err(e) if e.kind() == ErrorKind::Interrupted => continue,
+                Err(e) => return Err(e),
+            };
+
+            let read = buf.filled().len();
+            if read == 0 {
+                break;
+            }
+
+            // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
+            // and the number of read bytes can't exceed the spare capacity since
+            // that's what the buffer is borrowing from.
+            unsafe { self.set_len(self.len() + read) };
+            bytes += read as u64;
+        }
+
+        Ok(bytes)
+    }
+}
+
 fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
     reader: &mut R,
     writer: &mut W,
diff --git a/library/std/src/io/copy/tests.rs b/library/std/src/io/copy/tests.rs
index 8c816af15b8..af137eaf856 100644
--- a/library/std/src/io/copy/tests.rs
+++ b/library/std/src/io/copy/tests.rs
@@ -1,4 +1,6 @@
 use crate::cmp::{max, min};
+use crate::collections::VecDeque;
+use crate::io;
 use crate::io::*;
 
 #[test]
@@ -19,7 +21,7 @@ struct ShortReader {
 
 impl Read for ShortReader {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
-        let bytes = min(self.cap, self.read_size);
+        let bytes = min(self.cap, self.read_size).min(buf.len());
         self.cap -= bytes;
         self.observed_buffer = max(self.observed_buffer, buf.len());
         Ok(bytes)
@@ -78,6 +80,40 @@ fn copy_specializes_bufreader() {
     );
 }
 
+#[test]
+fn copy_specializes_to_vec() {
+    let cap = 123456;
+    let mut source = ShortReader { cap, observed_buffer: 0, read_size: 1337 };
+    let mut sink = Vec::new();
+    assert_eq!(cap as u64, io::copy(&mut source, &mut sink).unwrap());
+    assert!(
+        source.observed_buffer > DEFAULT_BUF_SIZE,
+        "expected a large buffer to be provided to the reader"
+    );
+}
+
+#[test]
+fn copy_specializes_from_vecdeque() {
+    let mut source = VecDeque::with_capacity(100 * 1024);
+    for _ in 0..20 * 1024 {
+        source.push_front(0);
+    }
+    for _ in 0..20 * 1024 {
+        source.push_back(0);
+    }
+    let mut sink = WriteObserver { observed_buffer: 0 };
+    assert_eq!(40 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
+    assert_eq!(20 * 1024, sink.observed_buffer);
+}
+
+#[test]
+fn copy_specializes_from_slice() {
+    let mut source = [1; 60 * 1024].as_slice();
+    let mut sink = WriteObserver { observed_buffer: 0 };
+    assert_eq!(60 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
+    assert_eq!(60 * 1024, sink.observed_buffer);
+}
+
 #[cfg(unix)]
 mod io_benches {
     use crate::fs::File;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 72b9ad3480b..d287397aab3 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -603,7 +603,6 @@ pub mod alloc;
 
 // Private support modules
 mod panicking;
-mod personality;
 
 #[path = "../../backtrace/src/lib.rs"]
 #[allow(dead_code, unused_attributes, fuzzy_provenance_casts)]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index c72be13804d..beea3f23c2d 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -23,6 +23,7 @@
 #![allow(missing_debug_implementations)]
 
 pub mod common;
+mod personality;
 
 cfg_if::cfg_if! {
     if #[cfg(unix)] {
@@ -60,3 +61,52 @@ cfg_if::cfg_if! {
         pub const FULL_BACKTRACE_DEFAULT: bool = false;
     }
 }
+
+#[cfg(not(test))]
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "android")] {
+        pub use self::android::log2f32;
+        pub use self::android::log2f64;
+    } else {
+        #[inline]
+        pub fn log2f32(n: f32) -> f32 {
+            unsafe { crate::intrinsics::log2f32(n) }
+        }
+
+        #[inline]
+        pub fn log2f64(n: f64) -> f64 {
+            unsafe { crate::intrinsics::log2f64(n) }
+        }
+    }
+}
+
+// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
+// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
+// of expected NaN).
+#[cfg(not(test))]
+#[cfg(any(target_os = "solaris", target_os = "illumos"))]
+#[inline]
+pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
+    if n.is_finite() {
+        if n > 0.0 {
+            log_fn(n)
+        } else if n == 0.0 {
+            f64::NEG_INFINITY // log(0) = -Inf
+        } else {
+            f64::NAN // log(-n) = NaN
+        }
+    } else if n.is_nan() {
+        n // log(NaN) = NaN
+    } else if n > 0.0 {
+        n // log(Inf) = Inf
+    } else {
+        f64::NAN // log(-Inf) = NaN
+    }
+}
+
+#[cfg(not(test))]
+#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
+#[inline]
+pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
+    log_fn(n)
+}
diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index 79624703a4c..79624703a4c 100644
--- a/library/std/src/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
diff --git a/library/std/src/personality/dwarf/mod.rs b/library/std/src/sys/personality/dwarf/mod.rs
index 652fbe95a14..652fbe95a14 100644
--- a/library/std/src/personality/dwarf/mod.rs
+++ b/library/std/src/sys/personality/dwarf/mod.rs
diff --git a/library/std/src/personality/dwarf/tests.rs b/library/std/src/sys/personality/dwarf/tests.rs
index 1644f37083a..1644f37083a 100644
--- a/library/std/src/personality/dwarf/tests.rs
+++ b/library/std/src/sys/personality/dwarf/tests.rs
diff --git a/library/std/src/personality/emcc.rs b/library/std/src/sys/personality/emcc.rs
index cb52ae89b19..cb52ae89b19 100644
--- a/library/std/src/personality/emcc.rs
+++ b/library/std/src/sys/personality/emcc.rs
diff --git a/library/std/src/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index 6552d96ca69..6552d96ca69 100644
--- a/library/std/src/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
diff --git a/library/std/src/personality.rs b/library/std/src/sys/personality/mod.rs
index 386a399f532..386a399f532 100644
--- a/library/std/src/personality.rs
+++ b/library/std/src/sys/personality/mod.rs