about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-07-17 09:51:58 +0200
committerRalf Jung <post@ralfj.de>2019-07-19 09:45:38 +0200
commit13ed0cf9e86a4fdbf75152849353050fea5d4461 (patch)
treee36efbef3abc4f5770aca642b0d8aca04fa47803
parent33452b0587ad543c6d7cc0f41daad6d4be71842f (diff)
downloadrust-13ed0cf9e86a4fdbf75152849353050fea5d4461.tar.gz
rust-13ed0cf9e86a4fdbf75152849353050fea5d4461.zip
do not use mem::uninitialized in std::io
-rw-r--r--src/libcore/fmt/float.rs7
-rw-r--r--src/libstd/io/util.rs24
-rw-r--r--src/libstd/lib.rs1
3 files changed, 15 insertions, 17 deletions
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 4bd7d3b4b22..a2fff913ac7 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -12,10 +12,11 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
     unsafe {
         let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
         let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
-        // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
-        // `MaybeUninit` (here and elsewhere in this file).  Revisit this once
+        // FIXME(#53491): This is calling `get_mut` on an uninitialized
+        // `MaybeUninit` (here and elsewhere in this file). Revisit this once
         // we decided whether that is valid or not.
-        // Using `freeze` is *not enough*; `flt2dec::Part` is an enum!
+        // We can do this only because we are libstd and coupled to the compiler.
+        // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
         let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
                                                     *num, sign, precision,
                                                     false, buf.get_mut(), parts.get_mut());
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 1efccb53b75..20979e02a43 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -2,7 +2,7 @@
 
 use crate::fmt;
 use crate::io::{self, Read, Initializer, Write, ErrorKind, BufRead, IoSlice, IoSliceMut};
-use crate::mem;
+use crate::mem::MaybeUninit;
 
 /// Copies the entire contents of a reader into a writer.
 ///
@@ -43,27 +43,23 @@ use crate::mem;
 pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
     where R: Read, W: Write
 {
-    let mut buf = unsafe {
-        // This is still technically undefined behavior due to creating a reference
-        // to uninitialized data, but within libstd we can rely on more guarantees
-        // than if this code were in an external lib
-
-        // FIXME: This should probably be changed to an array of `MaybeUninit<u8>`
-        // once the `mem::MaybeUninit` slice APIs stabilize
-        let mut buf: mem::MaybeUninit<[u8; super::DEFAULT_BUF_SIZE]> = mem::MaybeUninit::uninit();
-        reader.initializer().initialize(&mut *buf.as_mut_ptr());
-        buf.assume_init()
-    };
+    let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit();
+    // FIXME(#53491): This is calling `get_mut` and `get_ref` on an uninitialized
+    // `MaybeUninit`. Revisit this once we decided whether that is valid or not.
+    // This is still technically undefined behavior due to creating a reference
+    // to uninitialized data, but within libstd we can rely on more guarantees
+    // than if this code were in an external lib
+    unsafe { reader.initializer().initialize(buf.get_mut()); }
 
     let mut written = 0;
     loop {
-        let len = match reader.read(&mut buf) {
+        let len = match reader.read(unsafe { buf.get_mut() }) {
             Ok(0) => return Ok(written),
             Ok(len) => len,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
             Err(e) => return Err(e),
         };
-        writer.write_all(&buf[..len])?;
+        writer.write_all(unsafe { &buf.get_ref()[..len] })?;
         written += len as u64;
     }
 }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 79b2f09f40a..49fb4be39b4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -272,6 +272,7 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
+#![feature(maybe_uninit_ref)]
 #![feature(mem_take)]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]