about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorStefan Lankes <stlankes@users.noreply.github.com>2019-10-22 19:01:09 +0200
committerGitHub <noreply@github.com>2019-10-22 19:01:09 +0200
commitddcd157d03a067419d7f5b4375cfaff5a474856a (patch)
treec0b1bc8b196ff630dc9b7dfcf6f4e869e38b5e6c /src/libstd
parent8a11c61a7af9ffa6585ee93b266e02fa1d642ba8 (diff)
parent57bfb8096295150c06559da10adc5629e445a4ac (diff)
Merge branch 'master' into rusty-hermit
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ffi/c_str.rs26
-rw-r--r--src/libstd/io/stdio.rs2
-rw-r--r--src/libstd/keyword_docs.rs67
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/net/udp.rs2
-rw-r--r--src/libstd/panic.rs2
-rw-r--r--src/libstd/panicking.rs17
-rw-r--r--src/libstd/process.rs12
-rw-r--r--src/libstd/sys/unix/fd.rs34
-rw-r--r--src/libstd/sys/unix/fs.rs2
10 files changed, 111 insertions, 55 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 483f2ba52ec..6dcda986310 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -327,7 +327,31 @@ impl CString {
     /// [`NulError`]: struct.NulError.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
-        Self::_new(t.into())
+        trait SpecIntoVec {
+            fn into_vec(self) -> Vec<u8>;
+        }
+        impl<T: Into<Vec<u8>>> SpecIntoVec for T {
+            default fn into_vec(self) -> Vec<u8> {
+                self.into()
+            }
+        }
+        // Specialization for avoiding reallocation.
+        impl SpecIntoVec for &'_ [u8] {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self);
+                v
+            }
+        }
+        impl SpecIntoVec for &'_ str {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self.as_bytes());
+                v
+            }
+        }
+
+        Self::_new(SpecIntoVec::into_vec(t))
     }
 
     fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index c798ee0e220..6574ef13db9 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -762,7 +762,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
 /// otherwise. `label` identifies the stream in a panic message.
 ///
 /// This function is used to print error messages, so it takes extra
-/// care to avoid causing a panic when `local_stream` is unusable.
+/// care to avoid causing a panic when `local_s` is unusable.
 /// For instance, if the TLS key for the local stream is
 /// already destroyed, or if the local stream is locked by another
 /// thread, it will just fall back to the global stream.
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index a8dfe924fdf..ab8a55660cb 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -33,9 +33,72 @@ mod as_keyword { }
 //
 /// Exit early from a loop.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// When `break` is encountered, execution of the associated loop body is
+/// immediately terminated.
+///
+/// ```rust
+/// let mut last = 0;
+///
+/// for x in 1..100 {
+///     if x > 12 {
+///         break;
+///     }
+///     last = x;
+/// }
+///
+/// assert_eq!(last, 12);
+/// println!("{}", last);
+/// ```
+///
+/// A break expression is normally associated with the innermost loop enclosing the
+/// `break` but a label can be used to specify which enclosing loop is affected.
+///
+///```rust
+/// 'outer: for i in 1..=5 {
+///     println!("outer iteration (i): {}", i);
+///
+///     'inner: for j in 1..=200 {
+///         println!("    inner iteration (j): {}", j);
+///         if j >= 3 {
+///             // breaks from inner loop, let's outer loop continue.
+///             break;
+///         }
+///         if i >= 2 {
+///             // breaks from outer loop, and directly to "Bye".
+///             break 'outer;
+///         }
+///     }
+/// }
+/// println!("Bye.");
+///```
+///
+/// When associated with `loop`, a break expression may be used to return a value from that loop.
+/// This is only valid with `loop` and not with any other type of loop.
+/// If no value is specified, `break;` returns `()`.
+/// Every `break` within a loop must return the same type.
+///
+/// ```rust
+/// let (mut a, mut b) = (1, 1);
+/// let result = loop {
+///     if b > 10 {
+///         break b;
+///     }
+///     let c = a + b;
+///     a = b;
+///     b = c;
+/// };
+/// // first number in Fibonacci sequence over 10:
+/// assert_eq!(result, 13);
+/// println!("{}", result);
+/// ```
+///
+/// For more details consult the [Reference on "break expression"] and the [Reference on "break and
+/// loop values"].
+///
+/// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions
+/// [Reference on "break and loop values"]:
+/// ../reference/expressions/loop-expr.html#break-and-loop-values
 ///
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
 mod break_keyword { }
 
 #[doc(keyword = "const")]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index af6cb656444..93d3e4ea3df 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -275,6 +275,7 @@
 #![feature(link_args)]
 #![feature(linkage)]
 #![feature(log_syntax)]
+#![feature(manually_drop_take)]
 #![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
 #![feature(needs_panic_runtime)]
@@ -297,6 +298,7 @@
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
 #![feature(slice_patterns)]
+#![feature(specialization)]
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stdsimd)]
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 46bbd8855de..a9e4457f423 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -202,7 +202,7 @@ impl UdpSocket {
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
     /// assert_eq!(socket.peer_addr().unwrap_err().kind(),
-    ///            ::std::io::ErrorKind::NotConnected);
+    ///            std::io::ErrorKind::NotConnected);
     /// ```
     #[stable(feature = "udp_peer_addr", since = "1.40.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 24c693790e8..577673b7e40 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -264,7 +264,7 @@ impl RefUnwindSafe for atomic::AtomicI128 {}
 #[cfg(target_has_atomic_load_store = "ptr")]
 #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
 impl RefUnwindSafe for atomic::AtomicUsize {}
-#[cfg(target_hastarget_has_atomic_load_store_atomic = "8")]
+#[cfg(target_has_atomic_load_store = "8")]
 #[unstable(feature = "integer_atomics", issue = "32976")]
 impl RefUnwindSafe for atomic::AtomicU8 {}
 #[cfg(target_has_atomic_load_store = "16")]
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 638ce1679b8..2dde81bb0ec 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -12,8 +12,7 @@ use core::panic::{BoxMeUp, PanicInfo, Location};
 use crate::any::Any;
 use crate::fmt;
 use crate::intrinsics;
-use crate::mem;
-use crate::ptr;
+use crate::mem::{self, ManuallyDrop};
 use crate::raw;
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::stdio::panic_output;
@@ -227,10 +226,9 @@ pub use realstd::rt::update_panic_count;
 
 /// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
 pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
-    #[allow(unions_with_drop_fields)]
     union Data<F, R> {
-        f: F,
-        r: R,
+        f: ManuallyDrop<F>,
+        r: ManuallyDrop<R>,
     }
 
     // We do some sketchy operations with ownership here for the sake of
@@ -261,7 +259,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     let mut any_data = 0;
     let mut any_vtable = 0;
     let mut data = Data {
-        f,
+        f: ManuallyDrop::new(f)
     };
 
     let r = __rust_maybe_catch_panic(do_call::<F, R>,
@@ -271,7 +269,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
 
     return if r == 0 {
         debug_assert!(update_panic_count(0) == 0);
-        Ok(data.r)
+        Ok(ManuallyDrop::into_inner(data.r))
     } else {
         update_panic_count(-1);
         debug_assert!(update_panic_count(0) == 0);
@@ -284,8 +282,9 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
         unsafe {
             let data = data as *mut Data<F, R>;
-            let f = ptr::read(&mut (*data).f);
-            ptr::write(&mut (*data).r, f());
+            let data = &mut (*data);
+            let f = ManuallyDrop::take(&mut data.f);
+            data.r = ManuallyDrop::new(f());
         }
     }
 }
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index da136ca6bf6..4b0cf8312f1 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1488,12 +1488,12 @@ impl Child {
 /// }
 ///
 /// fn main() {
-///     ::std::process::exit(match run_app() {
-///        Ok(_) => 0,
-///        Err(err) => {
-///            eprintln!("error: {:?}", err);
-///            1
-///        }
+///     std::process::exit(match run_app() {
+///         Ok(_) => 0,
+///         Err(err) => {
+///             eprintln!("error: {:?}", err);
+///             1
+///         }
 ///     });
 /// }
 /// ```
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index ac43526b50f..ba611a6b7e7 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -71,22 +71,7 @@ impl FileDesc {
         #[cfg(target_os = "android")]
         use super::android::cvt_pread64;
 
-        #[cfg(target_os = "emscripten")]
-        unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
-            -> io::Result<isize>
-        {
-            use crate::convert::TryInto;
-            use libc::pread64;
-            // pread64 on emscripten actually takes a 32 bit offset
-            if let Ok(o) = offset.try_into() {
-                cvt(pread64(fd, buf, count, o))
-            } else {
-                Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                   "cannot pread >2GB"))
-            }
-        }
-
-        #[cfg(not(any(target_os = "android", target_os = "emscripten")))]
+        #[cfg(not(target_os = "android"))]
         unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
             -> io::Result<isize>
         {
@@ -128,22 +113,7 @@ impl FileDesc {
         #[cfg(target_os = "android")]
         use super::android::cvt_pwrite64;
 
-        #[cfg(target_os = "emscripten")]
-        unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
-            -> io::Result<isize>
-        {
-            use crate::convert::TryInto;
-            use libc::pwrite64;
-            // pwrite64 on emscripten actually takes a 32 bit offset
-            if let Ok(o) = offset.try_into() {
-                cvt(pwrite64(fd, buf, count, o))
-            } else {
-                Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                   "cannot pwrite >2GB"))
-            }
-        }
-
-        #[cfg(not(any(target_os = "android", target_os = "emscripten")))]
+        #[cfg(not(target_os = "android"))]
         unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
             -> io::Result<isize>
         {
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 4054cb1f9c5..b34ebf7dae6 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -783,8 +783,6 @@ impl File {
             SeekFrom::End(off) => (libc::SEEK_END, off),
             SeekFrom::Current(off) => (libc::SEEK_CUR, off),
         };
-        #[cfg(target_os = "emscripten")]
-        let pos = pos as i32;
         let n = cvt(unsafe { lseek64(self.0.raw(), pos, whence) })?;
         Ok(n as u64)
     }