From 81cd1e64f38299276ce131db37994086ec94ad35 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 15 Jan 2019 20:48:52 -0800 Subject: Deprecate the unstable Vec::resize_default --- src/liballoc/vec.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index ba3b3dfbfc2..198d1ee4bb4 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1368,6 +1368,7 @@ impl Vec { /// # Examples /// /// ``` + /// # #![allow(deprecated)] /// #![feature(vec_resize_default)] /// /// let mut vec = vec![1, 2, 3]; @@ -1384,6 +1385,9 @@ impl Vec { /// [`Default`]: ../../std/default/trait.Default.html /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] + #[rustc_deprecated(reason = "This is moving towards being removed in favor \ + of `.resize_with(Default::default)`. If you disagree, please comment \ + in the tracking issue.", since = "1.33.0")] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); -- cgit 1.4.1-3-g733a5 From 6bfb280189ef6960525f18364c1b4644a913f4ce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 19:53:32 +0100 Subject: deprecate before_exec in favor of unsafe pre_exec --- src/libstd/sys/unix/ext/process.rs | 26 +++++++++++++++++++++++--- src/libstd/sys/unix/process/process_common.rs | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 0282aaae909..f5fc26dc9cc 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method should be unsafe, so it got deprecated in favor of the + /// unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -97,10 +117,10 @@ impl CommandExt for process::Command { self } - fn before_exec(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 2c55813c5cd..9975064ca65 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -149,7 +149,7 @@ impl Command { &mut self.closures } - pub fn before_exec(&mut self, + pub unsafe fn pre_exec(&mut self, f: Box io::Result<()> + Send + Sync>) { self.closures.push(f); } -- cgit 1.4.1-3-g733a5 From d48433d920ad27ab57a27f087bcdec79ab36bfdc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 19:57:06 +0100 Subject: also replace before_exec by pre_exec on redox --- src/libstd/sys/redox/ext/process.rs | 28 ++++++++++++++++++++++++---- src/libstd/sys/redox/process.rs | 2 +- src/libstd/sys/unix/ext/process.rs | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 941fba8755b..78917ea9188 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method should be unsafe, so it got deprecated in favor of the + /// unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -87,10 +107,10 @@ impl CommandExt for process::Command { self } - fn before_exec(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 4199ab98cf1..9b85fa41a0a 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -116,7 +116,7 @@ impl Command { self.gid = Some(id); } - pub fn before_exec(&mut self, + pub unsafe fn pre_exec(&mut self, f: Box io::Result<()> + Send + Sync>) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index f5fc26dc9cc..7cc5e994593 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on -- cgit 1.4.1-3-g733a5 From b1709d25e12fbffca53c30d05c16854256185900 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 20:00:08 +0100 Subject: update test --- src/test/run-pass/command-before-exec.rs | 83 -------------------------------- src/test/run-pass/command-pre-exec.rs | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 83 deletions(-) delete mode 100644 src/test/run-pass/command-before-exec.rs create mode 100644 src/test/run-pass/command-pre-exec.rs (limited to 'src') diff --git a/src/test/run-pass/command-before-exec.rs b/src/test/run-pass/command-before-exec.rs deleted file mode 100644 index 91d2636b2ae..00000000000 --- a/src/test/run-pass/command-before-exec.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![allow(stable_features)] -// ignore-windows - this is a unix-specific test -// ignore-cloudabi no processes -// ignore-emscripten no processes - -#![feature(process_exec, rustc_private)] - -extern crate libc; - -use std::env; -use std::io::Error; -use std::os::unix::process::CommandExt; -use std::process::Command; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; - -fn main() { - if let Some(arg) = env::args().nth(1) { - match &arg[..] { - "test1" => println!("hello2"), - "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), - "test3" => assert_eq!(env::current_dir().unwrap() - .to_str().unwrap(), "/"), - "empty" => {} - _ => panic!("unknown argument: {}", arg), - } - return - } - - let me = env::current_exe().unwrap(); - - let output = Command::new(&me).arg("test1").before_exec(|| { - println!("hello"); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert_eq!(output.stdout, b"hello\nhello2\n"); - - let output = Command::new(&me).arg("test2").before_exec(|| { - env::set_var("FOO", "BAR"); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let output = Command::new(&me).arg("test3").before_exec(|| { - env::set_current_dir("/").unwrap(); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let output = Command::new(&me).arg("bad").before_exec(|| { - Err(Error::from_raw_os_error(102)) - }).output().unwrap_err(); - assert_eq!(output.raw_os_error(), Some(102)); - - let pid = unsafe { libc::getpid() }; - assert!(pid >= 0); - let output = Command::new(&me).arg("empty").before_exec(move || { - let child = unsafe { libc::getpid() }; - assert!(child >= 0); - assert!(pid != child); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let mem = Arc::new(AtomicUsize::new(0)); - let mem2 = mem.clone(); - let output = Command::new(&me).arg("empty").before_exec(move || { - assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - assert_eq!(mem.load(Ordering::SeqCst), 0); -} diff --git a/src/test/run-pass/command-pre-exec.rs b/src/test/run-pass/command-pre-exec.rs new file mode 100644 index 00000000000..bca2b8410fa --- /dev/null +++ b/src/test/run-pass/command-pre-exec.rs @@ -0,0 +1,83 @@ +#![allow(stable_features)] +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes + +#![feature(process_exec, rustc_private)] + +extern crate libc; + +use std::env; +use std::io::Error; +use std::os::unix::process::CommandExt; +use std::process::Command; +use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; + +fn main() { + if let Some(arg) = env::args().nth(1) { + match &arg[..] { + "test1" => println!("hello2"), + "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), + "test3" => assert_eq!(env::current_dir().unwrap() + .to_str().unwrap(), "/"), + "empty" => {} + _ => panic!("unknown argument: {}", arg), + } + return + } + + let me = env::current_exe().unwrap(); + + let output = unsafe { Command::new(&me).arg("test1").pre_exec(|| { + println!("hello"); + Ok(()) + }).output().unwrap() }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"hello\nhello2\n"); + + let output = unsafe { Command::new(&me).arg("test2").pre_exec(|| { + env::set_var("FOO", "BAR"); + Ok(()) + }).output().unwrap() }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { Command::new(&me).arg("test3").pre_exec(|| { + env::set_current_dir("/").unwrap(); + Ok(()) + }).output().unwrap() }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { Command::new(&me).arg("bad").pre_exec(|| { + Err(Error::from_raw_os_error(102)) + }).output().unwrap_err() }; + assert_eq!(output.raw_os_error(), Some(102)); + + let pid = unsafe { libc::getpid() }; + assert!(pid >= 0); + let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { + let child = libc::getpid(); + assert!(child >= 0); + assert!(pid != child); + Ok(()) + }).output().unwrap() }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let mem = Arc::new(AtomicUsize::new(0)); + let mem2 = mem.clone(); + let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { + assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); + Ok(()) + }).output().unwrap() }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + assert_eq!(mem.load(Ordering::SeqCst), 0); +} -- cgit 1.4.1-3-g733a5 From cbbf8a7ff932b599227b27d34e9b015374f5b37a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:00:55 +0100 Subject: deprecate things a bit slower --- src/libstd/sys/redox/ext/process.rs | 2 +- src/libstd/sys/unix/ext/process.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 78917ea9188..4e669bbb2d7 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -65,7 +65,7 @@ pub trait CommandExt { /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] - #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 7cc5e994593..da0507c6542 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -65,7 +65,7 @@ pub trait CommandExt { /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] - #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { -- cgit 1.4.1-3-g733a5 From 6c67a7625fbd38b4b986981c553dc7eb5a7a4765 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:05:43 +0100 Subject: pre_exec: expand docs --- src/libstd/sys/redox/ext/process.rs | 7 ++++--- src/libstd/sys/unix/ext/process.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 4e669bbb2d7..55824dc4c05 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -48,7 +48,8 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. + /// invalid use of these duplicates. Moreover, POSIX demands that you only + /// perform operations that are explicitly documented as async-signal-safe. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these @@ -60,8 +61,8 @@ pub trait CommandExt { /// Schedules a closure to be run just before the `exec` function is /// invoked. /// - /// This method should be unsafe, so it got deprecated in favor of the - /// unsafe [`pre_exec`]. + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index da0507c6542..ac0abc761ff 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -48,7 +48,8 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. + /// invalid use of these duplicates. Moreover, POSIX demands that you only + /// perform operations that are explicitly documented as async-signal-safe. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these @@ -60,8 +61,8 @@ pub trait CommandExt { /// Schedules a closure to be run just before the `exec` function is /// invoked. /// - /// This method should be unsafe, so it got deprecated in favor of the - /// unsafe [`pre_exec`]. + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] -- cgit 1.4.1-3-g733a5 From 59da97d2b2d0e3d4baf70cd6fdf49c31c7def380 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:08:21 +0100 Subject: rustfmt the test --- src/test/run-pass/command-pre-exec.rs | 92 +++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/test/run-pass/command-pre-exec.rs b/src/test/run-pass/command-pre-exec.rs index bca2b8410fa..21783fedd39 100644 --- a/src/test/run-pass/command-pre-exec.rs +++ b/src/test/run-pass/command-pre-exec.rs @@ -2,7 +2,6 @@ // ignore-windows - this is a unix-specific test // ignore-cloudabi no processes // ignore-emscripten no processes - #![feature(process_exec, rustc_private)] extern crate libc; @@ -11,71 +10,104 @@ use std::env; use std::io::Error; use std::os::unix::process::CommandExt; use std::process::Command; -use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; fn main() { if let Some(arg) = env::args().nth(1) { match &arg[..] { "test1" => println!("hello2"), "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), - "test3" => assert_eq!(env::current_dir().unwrap() - .to_str().unwrap(), "/"), + "test3" => assert_eq!(env::current_dir().unwrap().to_str().unwrap(), "/"), "empty" => {} _ => panic!("unknown argument: {}", arg), } - return + return; } let me = env::current_exe().unwrap(); - let output = unsafe { Command::new(&me).arg("test1").pre_exec(|| { - println!("hello"); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test1") + .pre_exec(|| { + println!("hello"); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert_eq!(output.stdout, b"hello\nhello2\n"); - let output = unsafe { Command::new(&me).arg("test2").pre_exec(|| { - env::set_var("FOO", "BAR"); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test2") + .pre_exec(|| { + env::set_var("FOO", "BAR"); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = unsafe { Command::new(&me).arg("test3").pre_exec(|| { - env::set_current_dir("/").unwrap(); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test3") + .pre_exec(|| { + env::set_current_dir("/").unwrap(); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = unsafe { Command::new(&me).arg("bad").pre_exec(|| { - Err(Error::from_raw_os_error(102)) - }).output().unwrap_err() }; + let output = unsafe { + Command::new(&me) + .arg("bad") + .pre_exec(|| Err(Error::from_raw_os_error(102))) + .output() + .unwrap_err() + }; assert_eq!(output.raw_os_error(), Some(102)); let pid = unsafe { libc::getpid() }; assert!(pid >= 0); - let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { - let child = libc::getpid(); - assert!(child >= 0); - assert!(pid != child); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + let child = libc::getpid(); + assert!(child >= 0); + assert!(pid != child); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); let mem = Arc::new(AtomicUsize::new(0)); let mem2 = mem.clone(); - let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { - assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); -- cgit 1.4.1-3-g733a5 From 33ee99b26a499027546f88a7f4eeddd8d4985c39 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 11:16:37 +0100 Subject: more formatting --- src/libstd/sys/redox/process.rs | 6 ++++-- src/libstd/sys/unix/process/process_common.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 9b85fa41a0a..62eb8cb23ab 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -116,8 +116,10 @@ impl Command { self.gid = Some(id); } - pub unsafe fn pre_exec(&mut self, - f: Box io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 9975064ca65..7fa256e59b2 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -149,8 +149,10 @@ impl Command { &mut self.closures } - pub unsafe fn pre_exec(&mut self, - f: Box io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } -- cgit 1.4.1-3-g733a5 From e023403da2da17ba7320c53c415b960c93348247 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 11:17:59 +0100 Subject: POSIX requires async signal safety for fork in signal handlers, not in general --- src/libstd/sys/redox/ext/process.rs | 3 +-- src/libstd/sys/unix/ext/process.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 55824dc4c05..18aef768b5d 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -48,8 +48,7 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. Moreover, POSIX demands that you only - /// perform operations that are explicitly documented as async-signal-safe. + /// invalid use of these duplicates. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index ac0abc761ff..d869a2013dc 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -48,8 +48,7 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. Moreover, POSIX demands that you only - /// perform operations that are explicitly documented as async-signal-safe. + /// invalid use of these duplicates. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these -- cgit 1.4.1-3-g733a5 From f753d304c6c5d7f2c10147d783d58db7db4ffc4c Mon Sep 17 00:00:00 2001 From: Igor Sadikov Date: Tue, 5 Feb 2019 15:21:03 -0500 Subject: Suggest removing parentheses surrounding lifetimes --- src/libsyntax/parse/parser.rs | 17 +++++++++++++++-- src/test/ui/parser/trait-object-lifetime-parens.stderr | 8 ++++---- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cacdab980fa..1dbe3fb7ea6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5371,6 +5371,7 @@ impl<'a> Parser<'a> { if is_bound_start { let lo = self.span; let has_parens = self.eat(&token::OpenDelim(token::Paren)); + let inner_lo = self.span; let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None }; if self.token.is_lifetime() { if let Some(question_span) = question { @@ -5379,9 +5380,21 @@ impl<'a> Parser<'a> { } bounds.push(GenericBound::Outlives(self.expect_lifetime())); if has_parens { + let inner_span = inner_lo.to(self.prev_span); self.expect(&token::CloseDelim(token::Paren))?; - self.span_err(self.prev_span, - "parenthesized lifetime bounds are not supported"); + let mut err = self.struct_span_err( + lo.to(self.prev_span), + "parenthesized lifetime bounds are not supported" + ); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(inner_span) { + err.span_suggestion_short( + lo.to(self.prev_span), + "remove the parentheses", + snippet.to_owned(), + Applicability::MachineApplicable + ); + } + err.emit(); } } else { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr index a9b542ddcc4..94ca66aef72 100644 --- a/src/test/ui/parser/trait-object-lifetime-parens.stderr +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -1,14 +1,14 @@ error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:5:24 + --> $DIR/trait-object-lifetime-parens.rs:5:21 | LL | fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:8:27 + --> $DIR/trait-object-lifetime-parens.rs:8:24 | LL | let _: Box; //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: expected type, found `'a` --> $DIR/trait-object-lifetime-parens.rs:9:17 -- cgit 1.4.1-3-g733a5 From d87df696b1811dc6da6a0be1d90b4398a67eb87e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Feb 2019 16:18:12 +0100 Subject: fix overlapping mutable and shared references in BTreeMap's into_slices_mut --- src/liballoc/collections/btree/node.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index eb0667228d1..cb38e6470ab 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -645,6 +645,8 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } fn into_key_slice_mut(mut self) -> &'a mut [K] { + // Same as for `into_key_slice` above, we try to avoid a run-time check + // (the alignment comparison will usually be performed at compile-time). if mem::align_of::() > mem::align_of::>() && self.is_shared_root() { &mut [] } else { @@ -667,9 +669,26 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } } - fn into_slices_mut(self) -> (&'a mut [K], &'a mut [V]) { - let k = unsafe { ptr::read(&self) }; - (k.into_key_slice_mut(), self.into_val_slice_mut()) + fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) { + debug_assert!(!self.is_shared_root()); + // We cannot use the getters here, because calling the second one + // invalidates the reference returned by the first. + // More precisely, it is the call to `len` that is the culprit, + // because that creates a shared reference to the header, which *can* + // overlap with the keys. + unsafe { + let len = self.len(); + let leaf = self.as_leaf_mut(); + let keys = slice::from_raw_parts_mut( + MaybeUninit::first_ptr_mut(&mut (*leaf).keys), + len + ); + let vals = slice::from_raw_parts_mut( + MaybeUninit::first_ptr_mut(&mut (*leaf).vals), + len + ); + (keys, vals) + } } } -- cgit 1.4.1-3-g733a5 From f0bef49cf10c19b72b7d025aedb407ab5745c365 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Feb 2019 17:13:50 +0100 Subject: fix invalidating references in BTree iterators --- src/liballoc/collections/btree/map.rs | 32 ++++++++++++++++++++------------ src/liballoc/collections/btree/node.rs | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 5ec5064b735..18fdc8ca2e4 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1634,9 +1634,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { let mut cur_handle = match handle.right_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.front = kv.right_edge(); - return (k, v); + self.front = ptr::read(&kv).right_edge(); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1647,9 +1649,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { loop { match cur_handle.right_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.front = first_leaf_edge(kv.right_edge().descend()); - return (k, v); + self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend()); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1680,9 +1684,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { let mut cur_handle = match handle.left_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.back = kv.left_edge(); - return (k, v); + self.back = ptr::read(&kv).left_edge(); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1693,9 +1699,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { loop { match cur_handle.left_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.back = last_leaf_edge(kv.left_edge().descend()); - return (k, v); + self.back = last_leaf_edge(ptr::read(&kv).left_edge().descend()); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index cb38e6470ab..1cdf4fdd2db 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -675,7 +675,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { // invalidates the reference returned by the first. // More precisely, it is the call to `len` that is the culprit, // because that creates a shared reference to the header, which *can* - // overlap with the keys. + // overlap with the keys (and even the values, for ZST keys). unsafe { let len = self.len(); let leaf = self.as_leaf_mut(); -- cgit 1.4.1-3-g733a5 From 9312ca10b6cd672c4fa1da4b4a3cc232f7d7dde6 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 17 Feb 2019 23:55:45 -0800 Subject: Add a note about 2018e if someone uses `try {` in 2015e --- src/librustc_resolve/error_reporting.rs | 4 ++++ src/test/ui/try-block/try-block-in-edition2015.stderr | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 8300e691bbe..fe9ae8b8300 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -251,6 +251,10 @@ impl<'a> Resolver<'a> { format!("{}!", path_str), Applicability::MaybeIncorrect, ); + if path_str == "try" && span.rust_2015() { + err.note("if you want the `try` keyword, \ + you need to be in the 2018 edition"); + } } (Def::TyAlias(..), PathSource::Trait(_)) => { err.span_label(span, "type aliases cannot be used as traits"); diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index a7b81060d3d..7394fec6f36 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -16,6 +16,8 @@ error[E0574]: expected struct, variant or union type, found macro `try` | LL | let try_result: Option<_> = try { | ^^^ help: use `!` to invoke the macro: `try!` + | + = note: if you want the `try` keyword, you need to be in the 2018 edition error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From 64c915e3ade66d3335c445eed89509dc41502c13 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sat, 2 Feb 2019 01:29:39 +0100 Subject: override `VecDeque::try_rfold`, also update iterator This keeps the slice based iteration and updates the iterator state after each slice. It also uses a loop to reduce the amount of code. This uses unsafe code, so some thorough review would be appreciated. --- src/liballoc/benches/vec_deque.rs | 7 ++++ src/liballoc/collections/vec_deque.rs | 51 +++++++++++++++++++++++++--- src/liballoc/tests/vec_deque.rs | 64 +++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/liballoc/benches/vec_deque.rs b/src/liballoc/benches/vec_deque.rs index f7aadbdbd82..7d2d3cfa612 100644 --- a/src/liballoc/benches/vec_deque.rs +++ b/src/liballoc/benches/vec_deque.rs @@ -45,3 +45,10 @@ fn bench_mut_iter_1000(b: &mut Bencher) { black_box(sum); }) } + +#[bench] +fn bench_try_fold(b: &mut Bencher) { + let ring: VecDeque<_> = (0..1000).collect(); + + b.iter(|| black_box(ring.iter().try_fold(0, |a, b| Some(a + b)))) +} diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 99fa54acb08..3d91fd3daab 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2170,12 +2170,29 @@ impl<'a, T> Iterator for Iter<'a, T> { back.iter().fold(accum, &mut f) } - fn try_fold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + fn try_fold(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try, { - let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); - let accum = front.iter().try_fold(init, &mut f)?; - back.iter().try_fold(accum, &mut f) + let (mut iter, final_res); + if self.tail <= self.head { + // single slice self.ring[self.tail..self.head] + iter = self.ring[self.tail..self.head].iter(); + final_res = iter.try_fold(init, &mut f); + } else { + // two slices: self.ring[self.tail..], self.ring[..self.head] + let (front, back) = self.ring.split_at(self.tail); + let mut back_iter = back.iter(); + let res = back_iter.try_fold(init, &mut f); + let len = self.ring.len(); + self.tail = (self.ring.len() - back_iter.len()) & (len - 1); + iter = front[..self.head].iter(); + final_res = iter.try_fold(res?, &mut f); + } + self.tail = self.head - iter.len(); + final_res } } @@ -2197,6 +2214,30 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { accum = back.iter().rfold(accum, &mut f); front.iter().rfold(accum, &mut f) } + + fn try_rfold(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let (mut iter, final_res); + if self.tail <= self.head { + // single slice self.ring[self.tail..self.head] + iter = self.ring[self.tail..self.head].iter(); + final_res = iter.try_rfold(init, &mut f); + } else { + // two slices: self.ring[self.tail..], self.ring[..self.head] + let (front, back) = self.ring.split_at(self.tail); + let mut front_iter = front[..self.head].iter(); + let res = front_iter.try_rfold(init, &mut f); + self.head = front_iter.len(); + iter = back.iter(); + final_res = iter.try_rfold(res?, &mut f); + } + self.head = self.tail + iter.len(); + final_res + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index aa49bdb0090..f801e42006b 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1459,6 +1459,15 @@ fn test_try_fold_unit() { assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(()))); } + +#[test] +fn test_try_fold_unit_none() { + let v: std::collections::VecDeque<()> = [(); 10].iter().cloned().collect(); + let mut iter = v.into_iter(); + assert!(iter.try_fold((), |_, _| None).is_none()); + assert_eq!(iter.len(), 9); +} + #[test] fn test_try_fold_rotated() { let mut v: VecDeque<_> = (0..12).collect(); @@ -1471,3 +1480,58 @@ fn test_try_fold_rotated() { assert_eq!(Ok::<_, ()>(66), v.iter().try_fold(0, |a, b| Ok(a + b))); } } + +#[test] +fn test_try_fold_moves_iter() { + let v: VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect(); + let mut iter = v.into_iter(); + assert_eq!(iter.try_fold(0_i8, |acc, &x| acc.checked_add(x)), None); + assert_eq!(iter.next(), Some(&60)); +} + +#[test] +fn test_try_fold_exhaust_wrap() { + let mut v = VecDeque::with_capacity(7); + v.push_back(1); + v.push_back(1); + v.push_back(1); + v.pop_front(); + v.pop_front(); + let mut iter = v.iter(); + let _ = iter.try_fold(0, |_, _| Some(1)); + assert!(iter.is_empty()); +} + +#[test] +fn test_try_fold_wraparound() { + let mut v = VecDeque::with_capacity(8); + v.push_back(7); + v.push_back(8); + v.push_back(9); + v.push_front(2); + v.push_front(1); + let mut iter = v.iter(); + let _ = iter.find(|&&x| x == 2); + assert_eq!(Some(&7), iter.next()); +} + +#[test] +fn test_try_rfold_rotated() { + let mut v: VecDeque<_> = (0..12).collect(); + for n in 0..10 { + if n & 1 == 0 { + v.rotate_left(n); + } else { + v.rotate_right(n); + } + assert_eq!(Ok::<_, ()>(66), v.iter().try_rfold(0, |a, b| Ok(a + b))); + } +} + +#[test] +fn test_try_rfold_moves_iter() { + let v : VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect(); + let mut iter = v.into_iter(); + assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None); + assert_eq!(iter.next_back(), Some(&70)); +} -- cgit 1.4.1-3-g733a5 From abb07c42ecd364940c16ecd740116b847d7bcffc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Feb 2019 09:49:52 +0300 Subject: remove a bit of dead code --- src/libsyntax/ext/build.rs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 48f6e4c0c82..27b0cfb1630 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -9,12 +9,6 @@ use crate::ThinVec; use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span, DUMMY_SP}; -// Transitional re-exports so qquote can find the paths it is looking for -mod syntax { - pub use crate::ext; - pub use crate::parse; -} - pub trait AstBuilder { // paths fn path(&self, span: Span, strs: Vec ) -> ast::Path; -- cgit 1.4.1-3-g733a5 From 65622e319e21d95bb7275109aecacb8e2526ce04 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Feb 2019 10:10:11 +0300 Subject: cleanup macro after 2018 transition We can now use `?` --- src/libsyntax/ext/expand.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d398437d7af..f50663f9785 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -36,10 +36,8 @@ macro_rules! ast_fragments { ( $($Kind:ident($AstTy:ty) { $kind_name:expr; - // FIXME: HACK: this should be `$(one ...)?` and `$(many ...)?` but `?` macro - // repetition was removed from 2015 edition in #51587 because of ambiguities. - $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)* - $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)* + $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? + $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)? fn $make_ast:ident; })* ) => { -- cgit 1.4.1-3-g733a5 From ad096d1a0e82ecb1174d92ea08eb223d7dc0117a Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 20 Feb 2019 10:17:23 +0000 Subject: Dedup a rustdoc diagnostic construction --- src/librustdoc/passes/collect_intra_doc_links.rs | 30 +++++++----------------- 1 file changed, 8 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 62b79646f6b..7f7fffbba10 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -458,26 +458,18 @@ fn resolution_failure( link_range: Option>, ) { let sp = span_of_attrs(attrs); - let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); - let mut diag = if let Some(link_range) = link_range { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, + NodeId::from_u32(0), + sp, + &format!("`[{}]` cannot be resolved, ignoring it...", path_str), + ); + if let Some(link_range) = link_range { if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg, - ); + diag.set_span(sp); diag.span_label(sp, "cannot be resolved, ignoring"); - diag } else { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg, - ); - // blah blah blah\nblah\nblah [blah] blah blah\nblah blah // ^ ~~~~ // | link_range @@ -494,13 +486,7 @@ fn resolution_failure( before=link_range.start - last_new_line_offset, found=link_range.len(), )); - diag } - } else { - cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg) }; diag.help("to escape `[` and `]` characters, just add '\\' before them like \ `\\[` or `\\]`"); -- cgit 1.4.1-3-g733a5 From 8cf3605c50978a80668d834d8262b316edba60f0 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Wed, 20 Feb 2019 17:59:17 +0100 Subject: fix typo --- src/doc/rustdoc/src/documentation-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 242167aa917..c9acd3c307b 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -244,7 +244,7 @@ disambiguate the error type: /// use std::io; /// let mut input = String::new(); /// io::stdin().read_line(&mut input)?; -/// # Ok::<(), io:Error>(()) +/// # Ok::<(), io::Error>(()) /// ``` ``` -- cgit 1.4.1-3-g733a5 From 103ed0c347062967b8b5fe76a02f945da14aac72 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 20 Feb 2019 18:08:21 +0100 Subject: Search for target_triple.json only if builtin target not found Before this commit, if the builtin target was found, but an error happened when instantiating it (e.g. validating the target specification file failed, etc.), then we ignored those errors and proceeded to try to find a `target_triple.json` file, and if that failed, reported that as an error. With this commit, if rustc is supposed to provide the builtin target, and something fails while instantiating it, that error will get properly propagated. --- src/librustc_target/spec/mod.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 7cbf24402d7..bef2afc7b62 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -259,6 +259,11 @@ impl ToJson for MergeFunctions { } } +pub enum LoadTargetError { + BuiltinTargetNotFound(String), + Other(String), +} + pub type LinkArgs = BTreeMap>; pub type TargetResult = Result; @@ -269,21 +274,24 @@ macro_rules! supported_targets { /// List of supported targets const TARGETS: &[&str] = &[$($triple),*]; - fn load_specific(target: &str) -> TargetResult { + fn load_specific(target: &str) -> Result { match target { $( $triple => { - let mut t = $module::target()?; + let mut t = $module::target() + .map_err(LoadTargetError::Other)?; t.options.is_builtin = true; // round-trip through the JSON parser to ensure at // run-time that the parser works correctly - t = Target::from_json(t.to_json())?; + t = Target::from_json(t.to_json()) + .map_err(LoadTargetError::Other)?; debug!("Got builtin target: {:?}", t); Ok(t) }, )+ - _ => Err(format!("Unable to find target: {}", target)) + _ => Err(LoadTargetError::BuiltinTargetNotFound( + format!("Unable to find target: {}", target))) } } @@ -1176,8 +1184,10 @@ impl Target { match *target_triple { TargetTriple::TargetTriple(ref target_triple) => { // check if triple is in list of supported targets - if let Ok(t) = load_specific(target_triple) { - return Ok(t) + match load_specific(target_triple) { + Ok(t) => return Ok(t), + Err(LoadTargetError::BuiltinTargetNotFound(_)) => (), + Err(LoadTargetError::Other(e)) => return Err(e), } // search for a file named `target_triple`.json in RUST_TARGET_PATH -- cgit 1.4.1-3-g733a5 From b2a02c8d4aeb74fd6adc23e5eec935fc064e153a Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 20 Feb 2019 13:03:52 -0600 Subject: Fixes #58586: Make E0505 explain example fail for 2018 edition --- src/librustc_mir/diagnostics.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 4df3004a9ad..1aac78d8adc 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -1545,6 +1545,8 @@ Erroneous code example: ```compile_fail,E0505 struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { @@ -1552,13 +1554,15 @@ fn main() { { let _ref_to_val: &Value = &x; eat(x); + borrow(_ref_to_val); } } ``` -Here, the function `eat` takes the ownership of `x`. However, -`x` cannot be moved because it was borrowed to `_ref_to_val`. -To fix that you can do few different things: +Here, the function `eat` takes ownership of `x`. However, +`x` cannot be moved because the borrow to `_ref_to_val` +needs to last till the function `borrow`. +To fix that you can do a few different things: * Try to avoid moving the variable. * Release borrow before move. @@ -1569,6 +1573,8 @@ Examples: ``` struct Value {} +fn borrow(val: &Value) {} + fn eat(val: &Value) {} fn main() { @@ -1576,6 +1582,7 @@ fn main() { { let _ref_to_val: &Value = &x; eat(&x); // pass by reference, if it's possible + borrow(_ref_to_val); } } ``` @@ -1585,12 +1592,15 @@ Or: ``` struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { let x = Value{}; { let _ref_to_val: &Value = &x; + borrow(_ref_to_val); } eat(x); // release borrow and then move it. } @@ -1602,6 +1612,8 @@ Or: #[derive(Clone, Copy)] // implement Copy trait struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { @@ -1609,6 +1621,7 @@ fn main() { { let _ref_to_val: &Value = &x; eat(x); // it will be copied here. + borrow(_ref_to_val); } } ``` -- cgit 1.4.1-3-g733a5 From 102436d16a5e3d46fbd05afc7607e1a4b0209c8f Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Wed, 20 Feb 2019 21:59:13 +0100 Subject: Put Future trait into spotlight --- src/libcore/future/future.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 84e7147153e..a143b54a61f 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -24,6 +24,7 @@ use task::{Poll, Waker}; /// /// When using a future, you generally won't call `poll` directly, but instead /// `await!` the value. +#[doc(spotlight)] #[must_use = "futures do nothing unless polled"] pub trait Future { /// The type of value produced on completion. -- cgit 1.4.1-3-g733a5 From 6a5abea7092cf7ede5bb6b3489db94eb701cd04e Mon Sep 17 00:00:00 2001 From: Alex Gurganus Date: Wed, 20 Feb 2019 16:12:28 -0600 Subject: Remove braces from most E0505 examples The solution which uses braces to release the borrow before it is moved is only required to satisfy the 2015 edition borrow checker. All other examples give the expected results for both 2015 and 2018 editions. --- src/librustc_mir/diagnostics.rs | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 1aac78d8adc..f369324157a 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -1551,11 +1551,9 @@ fn eat(val: Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(x); - borrow(_ref_to_val); - } + let _ref_to_val: &Value = &x; + eat(x); + borrow(_ref_to_val); } ``` @@ -1579,11 +1577,9 @@ fn eat(val: &Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(&x); // pass by reference, if it's possible - borrow(_ref_to_val); - } + let _ref_to_val: &Value = &x; + eat(&x); // pass by reference, if it's possible + borrow(_ref_to_val); } ``` @@ -1618,11 +1614,9 @@ fn eat(val: Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(x); // it will be copied here. - borrow(_ref_to_val); - } + let _ref_to_val: &Value = &x; + eat(x); // it will be copied here. + borrow(_ref_to_val); } ``` -- cgit 1.4.1-3-g733a5 From 0f6d36375f76f31a5252b8b8ab5faaafb374e721 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Feb 2019 13:15:59 +0100 Subject: explain why we use static alignment in ref-to-place conversion --- src/librustc_mir/interpret/place.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index b29e09900f6..637f1dcc4a4 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -326,6 +326,10 @@ where let mplace = MemPlace { ptr: val.to_scalar_ptr()?, + // We could use the run-time alignment here. For now, we do not, because + // the point of tracking the alignment here is to make sure that the *static* + // alignment information emitted with the loads is correct. The run-time + // alignment can only be more restrictive. align: layout.align.abi, meta: val.to_meta()?, }; -- cgit 1.4.1-3-g733a5 From b01f81be7445ca83a8a9fd51937e3047c22eea09 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Feb 2019 16:14:31 +0100 Subject: remark about the one place where place computation calls size_and_align_of --- src/librustc_mir/interpret/place.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 637f1dcc4a4..ec701a939f2 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -389,9 +389,11 @@ where // above). In that case, all fields are equal. let field_layout = base.layout.field(self, usize::try_from(field).unwrap_or(0))?; - // Offset may need adjustment for unsized fields + // Offset may need adjustment for unsized fields. let (meta, offset) = if field_layout.is_unsized() { - // re-use parent metadata to determine dynamic field layout + // Re-use parent metadata to determine dynamic field layout. + // With custom DSTS, this *will* execute user-defined code, but the same + // happens at run-time so that's okay. let align = match self.size_and_align_of(base.meta, field_layout)? { Some((_, align)) => align, None if offset == Size::ZERO => -- cgit 1.4.1-3-g733a5 From 09a24545a848f0d89bb6464c2af730095b816618 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 21 Feb 2019 17:26:10 +0100 Subject: introduce benchmarks of BTreeSet.intersection --- src/liballoc/benches/btree/mod.rs | 1 + src/liballoc/benches/btree/set.rs | 88 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/liballoc/benches/btree/set.rs (limited to 'src') diff --git a/src/liballoc/benches/btree/mod.rs b/src/liballoc/benches/btree/mod.rs index 4dc2dfd9153..095ca5dd2e2 100644 --- a/src/liballoc/benches/btree/mod.rs +++ b/src/liballoc/benches/btree/mod.rs @@ -1 +1,2 @@ mod map; +mod set; diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs new file mode 100644 index 00000000000..08e1db5fbb7 --- /dev/null +++ b/src/liballoc/benches/btree/set.rs @@ -0,0 +1,88 @@ +use std::collections::BTreeSet; + +use rand::{thread_rng, Rng}; +use test::{black_box, Bencher}; + +fn random(n1: u32, n2: u32) -> [BTreeSet; 2] { + let mut rng = thread_rng(); + let mut set1 = BTreeSet::new(); + let mut set2 = BTreeSet::new(); + for _ in 0..n1 { + let i = rng.gen::(); + set1.insert(i); + } + for _ in 0..n2 { + let i = rng.gen::(); + set2.insert(i); + } + [set1, set2] +} + +fn staggered(n1: u32, n2: u32) -> [BTreeSet; 2] { + let mut even = BTreeSet::new(); + let mut odd = BTreeSet::new(); + for i in 0..n1 { + even.insert(i * 2); + } + for i in 0..n2 { + odd.insert(i * 2 + 1); + } + [even, odd] +} + +fn neg_vs_pos(n1: u32, n2: u32) -> [BTreeSet; 2] { + let mut neg = BTreeSet::new(); + let mut pos = BTreeSet::new(); + for i in -(n1 as i32)..=-1 { + neg.insert(i); + } + for i in 1..=(n2 as i32) { + pos.insert(i); + } + [neg, pos] +} + +fn pos_vs_neg(n1: u32, n2: u32) -> [BTreeSet; 2] { + let mut neg = BTreeSet::new(); + let mut pos = BTreeSet::new(); + for i in -(n1 as i32)..=-1 { + neg.insert(i); + } + for i in 1..=(n2 as i32) { + pos.insert(i); + } + [pos, neg] +} + +macro_rules! set_intersection_bench { + ($name: ident, $sets: expr) => { + #[bench] + pub fn $name(b: &mut Bencher) { + // setup + let sets = $sets; + + // measure + b.iter(|| { + let x = sets[0].intersection(&sets[1]).count(); + black_box(x); + }) + } + }; +} + +set_intersection_bench! {intersect_random_100, random(100, 100)} +set_intersection_bench! {intersect_random_10k, random(10_000, 10_000)} +set_intersection_bench! {intersect_random_10_vs_10k, random(10, 10_000)} +set_intersection_bench! {intersect_random_10k_vs_10, random(10_000, 10)} +set_intersection_bench! {intersect_staggered_100, staggered(100, 100)} +set_intersection_bench! {intersect_staggered_10k, staggered(10_000, 10_000)} +set_intersection_bench! {intersect_staggered_10_vs_10k, staggered(10, 10_000)} +set_intersection_bench! {intersect_staggered_10k_vs_10, staggered(10_000, 10)} +set_intersection_bench! {intersect_neg_vs_pos_100, neg_vs_pos(100, 100)} +set_intersection_bench! {intersect_neg_vs_pos_10k, neg_vs_pos(10_000, 10_000)} +set_intersection_bench! {intersect_neg_vs_pos_10_vs_10k,neg_vs_pos(10, 10_000)} +set_intersection_bench! {intersect_neg_vs_pos_10k_vs_10,neg_vs_pos(10_000, 10)} +set_intersection_bench! {intersect_pos_vs_neg_100, pos_vs_neg(100, 100)} +set_intersection_bench! {intersect_pos_vs_neg_10k, pos_vs_neg(10_000, 10_000)} +set_intersection_bench! {intersect_pos_vs_neg_10_vs_10k,pos_vs_neg(10, 10_000)} +set_intersection_bench! {intersect_pos_vs_neg_10k_vs_10,pos_vs_neg(10_000, 10)} -- cgit 1.4.1-3-g733a5 From 4867a8c4fa1d5da99e9e6e61b86b4ce85e0572d0 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Thu, 21 Feb 2019 19:26:45 +0100 Subject: Update miri links Miri has been moved to `rust-lang` a couple of days ago. --- CONTRIBUTING.md | 2 +- src/tools/publish_toolstate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9924055ca45..54344f688f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -162,7 +162,7 @@ it can be found [here][rctd]. Currently building Rust will also build the following external projects: * [clippy](https://github.com/rust-lang-nursery/rust-clippy) -* [miri](https://github.com/solson/miri) +* [miri](https://github.com/rust-lang/miri) * [rustfmt](https://github.com/rust-lang-nursery/rustfmt) * [rls](https://github.com/rust-lang-nursery/rls/) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index abcf14d90be..fb6132a5358 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -25,7 +25,7 @@ MAINTAINERS = { } REPOS = { - 'miri': 'https://github.com/solson/miri', + 'miri': 'https://github.com/rust-lang/miri', 'clippy-driver': 'https://github.com/rust-lang/rust-clippy', 'rls': 'https://github.com/rust-lang/rls', 'rustfmt': 'https://github.com/rust-lang/rustfmt', -- cgit 1.4.1-3-g733a5 From 88d55f537ddf6630aafb2e7755ebd9831b8031c0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 Feb 2019 11:04:10 +0300 Subject: Make std feature list sorted This helps to avoid merge conflicts when concurrent PRs append features to the end of the list. --- src/libstd/lib.rs | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f849daf2079..6dd3a6cc0fd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -215,16 +215,22 @@ // std may use features in a platform-specific way #![allow(unused_features)] +#![cfg_attr(test, feature(test, update_panic_count))] +#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), + feature(global_asm, range_contains, slice_index_methods, + decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] + // std is implemented with unstable features, many of which are internal // compiler details that will never be stable -#![cfg_attr(test, feature(test, update_panic_count))] -#![feature(alloc)] +// NB: the following list is sorted to minimize merge conflicts. +#![feature(align_offset)] #![feature(alloc_error_handler)] +#![feature(alloc_layout_extra)] +#![feature(alloc)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(align_offset)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] @@ -233,20 +239,28 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] +#![feature(checked_duration_since)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] -#![feature(const_raw_ptr_deref)] #![feature(const_cstr_unchecked)] +#![feature(const_raw_ptr_deref)] #![feature(core_intrinsics)] +#![feature(doc_alias)] +#![feature(doc_cfg)] +#![feature(doc_keyword)] +#![feature(doc_masked)] +#![feature(doc_spotlight)] #![feature(dropck_eyepatch)] #![feature(duration_constants)] #![feature(exact_size_is_empty)] +#![feature(exhaustive_patterns)] #![feature(external_doc)] #![feature(fixed_size_array)] #![feature(fn_traits)] #![feature(fnbox)] #![feature(futures_api)] #![feature(generator_trait)] +#![feature(hash_raw_entry)] #![feature(hashmap_internals)] #![feature(int_error_internals)] #![feature(integer_atomics)] @@ -254,31 +268,32 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(maybe_uninit)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] -#![feature(exhaustive_patterns)] +#![feature(non_exhaustive)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] +#![feature(panic_info_message)] #![feature(panic_internals)] #![feature(panic_unwind)] #![feature(prelude_import)] #![feature(ptr_internals)] #![feature(raw)] -#![feature(hash_raw_entry)] +#![feature(renamed_spin_loop)] #![feature(rustc_attrs)] #![feature(rustc_const_unstable)] -#![feature(std_internals)] -#![feature(stdsimd)] +#![feature(rustc_private)] #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] #![feature(slice_patterns)] #![feature(staged_api)] +#![feature(std_internals)] +#![feature(stdsimd)] #![feature(stmt_expr_attributes)] #![feature(str_internals)] -#![feature(renamed_spin_loop)] -#![feature(rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] #![feature(try_from)] @@ -286,19 +301,7 @@ #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] -#![feature(doc_cfg)] -#![feature(doc_masked)] -#![feature(doc_spotlight)] -#![feature(doc_alias)] -#![feature(doc_keyword)] -#![feature(panic_info_message)] -#![feature(non_exhaustive)] -#![feature(alloc_layout_extra)] -#![feature(maybe_uninit)] -#![feature(checked_duration_since)] -#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, - decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] +// NB: the above list is sorted to minimize merge conflicts. #![default_lib_allocator] -- cgit 1.4.1-3-g733a5