From 15cd5a18a656252e32e7320fde3072be7b59db18 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 20 Jul 2016 17:26:12 -0700 Subject: std: Fix usage of SOCK_CLOEXEC This code path was intended to only get executed on Linux, but unfortunately the `cfg!` was malformed so it actually never got executed. --- src/libstd/sys/unix/net.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index a784741c88c..6f1b70acb60 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -67,7 +67,7 @@ impl Socket { // this option, however, was added in 2.6.27, and we still support // 2.6.18 as a kernel, so if the returned error is EINVAL we // fallthrough to the fallback. - if cfg!(linux) { + if cfg!(target_os = "linux") { match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) { Ok(fd) => return Ok(Socket(FileDesc::new(fd))), Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {} @@ -87,7 +87,7 @@ impl Socket { let mut fds = [0, 0]; // Like above, see if we can set cloexec atomically - if cfg!(linux) { + if cfg!(target_os = "linux") { match cvt(libc::socketpair(fam, ty | SOCK_CLOEXEC, 0, fds.as_mut_ptr())) { Ok(_) => { return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))); -- cgit 1.4.1-3-g733a5 From 90bb8d469c495f48cf0da67c7811fd887a8b0655 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 23 Jul 2016 01:57:21 +0200 Subject: Add DirBuilder doc examples --- src/libstd/fs.rs | 19 ++++++++++++++++++- src/libstd/sys/unix/ext/fs.rs | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index c28f70b8692..c74e508a69b 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1397,6 +1397,14 @@ pub fn set_permissions>(path: P, perm: Permissions) impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. + /// + /// # Examples + /// + /// ``` + /// use std::fs::DirBuilder; + /// + /// let builder = DirBuilder::new(); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] pub fn new() -> DirBuilder { DirBuilder { @@ -1409,7 +1417,16 @@ impl DirBuilder { /// all parent directories if they do not exist with the same security and /// permissions settings. /// - /// This option defaults to `false` + /// This option defaults to `false`. + /// + /// # Examples + /// + /// ``` + /// use std::fs::DirBuilder; + /// + /// let mut builder = DirBuilder::new(); + /// builder.recursive(true); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] pub fn recursive(&mut self, recursive: bool) -> &mut Self { self.recursive = recursive; diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index bb90a977433..d1f26fec249 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -239,6 +239,16 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to /// 0o777. + /// + /// # Examples + /// + /// ```ignore + /// use std::fs::DirBuilder; + /// use std::os::unix::fs::DirBuilderExt; + /// + /// let mut builder = DirBuilder::new(); + /// builder.mode(0o755); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] fn mode(&mut self, mode: u32) -> &mut Self; } -- cgit 1.4.1-3-g733a5 From 16699635bc467b0940c11675dd73e7e444088c4e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 24 Jul 2016 16:52:28 +0200 Subject: Add DirEntry doc examples --- src/libstd/fs.rs | 55 +++++++++++++++++++++++++++++++++++++++++++ src/libstd/sys/unix/ext/fs.rs | 16 +++++++++++++ 2 files changed, 71 insertions(+) (limited to 'src/libstd/sys') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index d1453b05a79..6547cb6acbe 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -846,6 +846,26 @@ impl DirEntry { /// On Windows this function is cheap to call (no extra system calls /// needed), but on Unix platforms this function is the equivalent of /// calling `symlink_metadata` on the path. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// if let Ok(metadata) = entry.metadata() { + /// // Now let's show our entry's permissions! + /// println!("{:?}: {:?}", entry.path(), metadata.permissions()); + /// } else { + /// println!("Couldn't get metadata for {:?}", entry.path()); + /// } + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn metadata(&self) -> io::Result { self.0.metadata().map(Metadata) @@ -861,6 +881,26 @@ impl DirEntry { /// On Windows and most Unix platforms this function is free (no extra /// system calls needed), but some Unix platforms may require the equivalent /// call to `symlink_metadata` to learn about the target file type. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// if let Ok(file_type) = entry.file_type() { + /// // Now let's show our entry's file type! + /// println!("{:?}: {:?}", entry.path(), file_type); + /// } else { + /// println!("Couldn't get file type for {:?}", entry.path()); + /// } + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn file_type(&self) -> io::Result { self.0.file_type().map(FileType) @@ -868,6 +908,21 @@ impl DirEntry { /// Returns the bare file name of this directory entry without any other /// leading path component. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// println!("{:?}", entry.file_name()); + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn file_name(&self) -> OsString { self.0.file_name() diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index bb90a977433..17c093e6cac 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -196,6 +196,22 @@ impl FileTypeExt for fs::FileType { pub trait DirEntryExt { /// Returns the underlying `d_ino` field in the contained `dirent` /// structure. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// use std::os::unix::fs::DirEntryExt; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// println!("{:?}: {}", entry.file_name(), entry.ino()); + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] fn ino(&self) -> u64; } -- cgit 1.4.1-3-g733a5 From 1aa8dad854155221db7cec19b6105c673e4a871e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 30 Apr 2016 16:37:44 +0200 Subject: DoubleEndedIterator for Args The number of arguments given to a process is always known, which makes implementing DoubleEndedIterator possible. That way, the Iterator::rev() method becomes usable, among others. Signed-off-by: Sebastian Thiel Tidy for DoubleEndedIterator I chose to not create a new feature for it, even though technically, this makes me lie about the original availability of the implementation. Verify with @alexchrichton Setup feature flag for new std::env::Args iterators Add test for Args reverse iterator It's somewhat depending on the input of the test program, but made in such a way that should be somewhat flexible to changes to the way it is called. Deduplicate windows ArgsOS code for DEI DEI = DoubleEndedIterator Move env::args().rev() test to run-pass It must be controlling it's arguments for full isolation. Remove superfluous feature name Assert all arguments returned by env::args().rev() Let's be very sure it works as we expect, why take chances. Fix rval of os_string_from_ptr A trait cannot be returned, but only the corresponding object. Deref pointers to actually operate on the argument Put unsafe to correct location --- src/libstd/env.rs | 11 +++++++ src/libstd/sys/unix/os.rs | 4 +++ src/libstd/sys/windows/os.rs | 27 ++++++++++------ src/test/run-pass/env-args-reverse-iterator.rs | 44 ++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 src/test/run-pass/env-args-reverse-iterator.rs (limited to 'src/libstd/sys') diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 6956dc0d901..01bc733d440 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -587,6 +587,13 @@ impl ExactSizeIterator for Args { fn len(&self) -> usize { self.inner.len() } } +#[stable(feature = "env_iterators", since = "1.11.0")] +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + self.inner.next_back().map(|s| s.into_string().unwrap()) + } +} + #[stable(feature = "env", since = "1.0.0")] impl Iterator for ArgsOs { type Item = OsString; @@ -599,6 +606,10 @@ impl ExactSizeIterator for ArgsOs { fn len(&self) -> usize { self.inner.len() } } +#[stable(feature = "env_iterators", since = "1.11.0")] +impl DoubleEndedIterator for ArgsOs { + fn next_back(&mut self) -> Option { self.inner.next_back() } +} /// Constants associated with the current target #[stable(feature = "env", since = "1.0.0")] pub mod consts { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 21ce6b19ceb..a8cb1ce49d2 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -308,6 +308,10 @@ impl ExactSizeIterator for Args { fn len(&self) -> usize { self.iter.len() } } +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { self.iter.next_back() } +} + /// Returns the command line arguments /// /// Returns a list of the command line arguments. diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 32ca32e76cb..0cea7f81e36 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -278,23 +278,30 @@ pub struct Args { cur: *mut *mut u16, } +unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString { + let mut len = 0; + while *ptr.offset(len) != 0 { len += 1; } + + // Push it onto the list. + let ptr = ptr as *const u16; + let buf = slice::from_raw_parts(ptr, len as usize); + OsStringExt::from_wide(buf) +} + impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.range.next().map(|i| unsafe { - let ptr = *self.cur.offset(i); - let mut len = 0; - while *ptr.offset(len) != 0 { len += 1; } - - // Push it onto the list. - let ptr = ptr as *const u16; - let buf = slice::from_raw_parts(ptr, len as usize); - OsStringExt::from_wide(buf) - }) + self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } } +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) + } +} + impl ExactSizeIterator for Args { fn len(&self) -> usize { self.range.len() } } diff --git a/src/test/run-pass/env-args-reverse-iterator.rs b/src/test/run-pass/env-args-reverse-iterator.rs new file mode 100644 index 00000000000..d22fa6494f0 --- /dev/null +++ b/src/test/run-pass/env-args-reverse-iterator.rs @@ -0,0 +1,44 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::env::args; +use std::process::Command; + +fn assert_reverse_iterator_for_program_arguments(program_name: &str) { + let args: Vec<_> = args().rev().collect(); + + assert!(args.len() == 4); + assert_eq!(args[0], "c"); + assert_eq!(args[1], "b"); + assert_eq!(args[2], "a"); + assert_eq!(args[3], program_name); + + println!("passed"); +} + +fn main() { + let mut args = args(); + let me = args.next().unwrap(); + + if let Some(_) = args.next() { + assert_reverse_iterator_for_program_arguments(&me); + return + } + + let output = Command::new(&me) + .arg("a") + .arg("b") + .arg("c") + .output() + .unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); +} -- cgit 1.4.1-3-g733a5 From d464422c0a15b88a7f5791652ce1f881959fcc44 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 15:21:25 -0500 Subject: rustbuild: make backtraces (RUST_BACKTRACE) optional but keep them enabled by default to maintain the status quo. When disabled shaves ~56KB off every x86_64-unknown-linux-gnu binary. To disable backtraces you have to use a config.toml (see src/bootstrap/config.toml.example for details) when building rustc/std: $ python bootstrap.py --config=config.toml --- src/bootstrap/config.rs | 4 ++++ src/bootstrap/config.toml.example | 3 +++ src/bootstrap/lib.rs | 3 +++ src/libstd/Cargo.toml | 1 + src/libstd/build.rs | 3 ++- src/libstd/panicking.rs | 16 ++++++++++++---- src/libstd/sys/common/mod.rs | 2 ++ src/libstd/sys/unix/mod.rs | 1 + src/rustc/std_shim/Cargo.toml | 1 + 9 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e64d7e5a437..aafbf68d1b7 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -72,6 +72,7 @@ pub struct Config { // libstd features pub debug_jemalloc: bool, pub use_jemalloc: bool, + pub backtrace: bool, // support for RUST_BACKTRACE // misc pub channel: String, @@ -134,6 +135,7 @@ struct Rust { debuginfo: Option, debug_jemalloc: Option, use_jemalloc: Option, + backtrace: Option, default_linker: Option, default_ar: Option, channel: Option, @@ -158,6 +160,7 @@ impl Config { let mut config = Config::default(); config.llvm_optimize = true; config.use_jemalloc = true; + config.backtrace = true; config.rust_optimize = true; config.rust_optimize_tests = true; config.submodules = true; @@ -230,6 +233,7 @@ impl Config { set(&mut config.rust_rpath, rust.rpath); set(&mut config.debug_jemalloc, rust.debug_jemalloc); set(&mut config.use_jemalloc, rust.use_jemalloc); + set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel.clone()); config.rustc_default_linker = rust.default_linker.clone(); config.rustc_default_ar = rust.default_ar.clone(); diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 6f065842328..2894adafef6 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -99,6 +99,9 @@ # Whether or not jemalloc is built with its debug option set #debug-jemalloc = false +# Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) +#backtrace = true + # The default linker that will be used by the generated compiler. Note that this # is not the linker used to link said compiler. #default-linker = "cc" diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 367322e8816..25356b86221 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -652,6 +652,9 @@ impl Build { if self.config.use_jemalloc { features.push_str(" jemalloc"); } + if self.config.backtrace { + features.push_str(" backtrace"); + } return features } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index eded6e24f3e..b442d21b72b 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -27,5 +27,6 @@ build_helper = { path = "../build_helper" } gcc = "0.3" [features] +backtrace = [] jemalloc = ["alloc_jemalloc"] debug-jemalloc = ["alloc_jemalloc/debug"] diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 9c408366f8b..9018e48d06b 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -25,7 +25,8 @@ fn main() { let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); - if !target.contains("apple") && !target.contains("msvc") && !target.contains("emscripten"){ + if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") && + !target.contains("emscripten") { build_libbacktrace(&host, &target); } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index d73e9542d21..319fbdaac55 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -28,8 +28,10 @@ use intrinsics; use mem; use raw; use sys_common::rwlock::RWLock; +#[cfg(feature = "backtrace")] use sync::atomic::{AtomicBool, Ordering}; use sys::stdio::Stderr; +#[cfg(feature = "backtrace")] use sys_common::backtrace; use sys_common::thread_info; use sys_common::util; @@ -71,6 +73,7 @@ enum Hook { static HOOK_LOCK: RWLock = RWLock::new(); static mut HOOK: Hook = Hook::Default; +#[cfg(feature = "backtrace")] static FIRST_PANIC: AtomicBool = AtomicBool::new(true); /// Registers a custom panic hook, replacing any that was previously registered. @@ -183,10 +186,12 @@ impl<'a> Location<'a> { } fn default_hook(info: &PanicInfo) { + #[cfg(feature = "backtrace")] let panics = PANIC_COUNT.with(|c| c.get()); // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. + #[cfg(feature = "backtrace")] let log_backtrace = panics >= 2 || backtrace::log_enabled(); let file = info.location.file; @@ -207,10 +212,13 @@ fn default_hook(info: &PanicInfo) { let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}", name, msg, file, line); - if log_backtrace { - let _ = backtrace::write(err); - } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { - let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace."); + #[cfg(feature = "backtrace")] + { + if log_backtrace { + let _ = backtrace::write(err); + } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { + let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace."); + } } }; diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index c9279883ae5..67b19682fc9 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -28,6 +28,7 @@ macro_rules! rtassert { pub mod args; pub mod at_exit_imp; +#[cfg(feature = "backtrace")] pub mod backtrace; pub mod condvar; pub mod io; @@ -42,6 +43,7 @@ pub mod thread_local; pub mod util; pub mod wtf8; +#[cfg(feature = "backtrace")] #[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), all(windows, target_env = "gnu")))] pub mod gnu; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index f0fd42fc99b..9aac7be8017 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -30,6 +30,7 @@ use libc; pub mod weak; pub mod android; +#[cfg(feature = "backtrace")] pub mod backtrace; pub mod condvar; pub mod ext; diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index 5602ef866b8..693cbe06ba9 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -46,3 +46,4 @@ std = { path = "../../libstd" } [features] jemalloc = ["std/jemalloc"] debug-jemalloc = ["std/debug-jemalloc"] +backtrace = ["std/backtrace"] -- cgit 1.4.1-3-g733a5 From 774fbdf40deb9b257dd6aa166096fed1eeac80c2 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 22:33:45 -0500 Subject: keep backtraces if using the old build system --- src/libstd/panicking.rs | 24 +++++++++++++----------- src/libstd/sys/common/mod.rs | 4 ++-- src/libstd/sys/unix/mod.rs | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 319fbdaac55..57a4c3df70a 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -28,11 +28,7 @@ use intrinsics; use mem; use raw; use sys_common::rwlock::RWLock; -#[cfg(feature = "backtrace")] -use sync::atomic::{AtomicBool, Ordering}; use sys::stdio::Stderr; -#[cfg(feature = "backtrace")] -use sys_common::backtrace; use sys_common::thread_info; use sys_common::util; use thread; @@ -73,8 +69,6 @@ enum Hook { static HOOK_LOCK: RWLock = RWLock::new(); static mut HOOK: Hook = Hook::Default; -#[cfg(feature = "backtrace")] -static FIRST_PANIC: AtomicBool = AtomicBool::new(true); /// Registers a custom panic hook, replacing any that was previously registered. /// @@ -186,13 +180,17 @@ impl<'a> Location<'a> { } fn default_hook(info: &PanicInfo) { - #[cfg(feature = "backtrace")] - let panics = PANIC_COUNT.with(|c| c.get()); + #[cfg(any(not(cargobuild), feature = "backtrace"))] + use sys_common::backtrace; // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. - #[cfg(feature = "backtrace")] - let log_backtrace = panics >= 2 || backtrace::log_enabled(); + #[cfg(any(not(cargobuild), feature = "backtrace"))] + let log_backtrace = { + let panics = PANIC_COUNT.with(|c| c.get()); + + panics >= 2 || backtrace::log_enabled() + }; let file = info.location.file; let line = info.location.line; @@ -212,8 +210,12 @@ fn default_hook(info: &PanicInfo) { let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}", name, msg, file, line); - #[cfg(feature = "backtrace")] + #[cfg(any(not(cargobuild), feature = "backtrace"))] { + use sync::atomic::{AtomicBool, Ordering}; + + static FIRST_PANIC: AtomicBool = AtomicBool::new(true); + if log_backtrace { let _ = backtrace::write(err); } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 67b19682fc9..a1f3f477b3a 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -28,7 +28,7 @@ macro_rules! rtassert { pub mod args; pub mod at_exit_imp; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] pub mod backtrace; pub mod condvar; pub mod io; @@ -43,7 +43,7 @@ pub mod thread_local; pub mod util; pub mod wtf8; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] #[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), all(windows, target_env = "gnu")))] pub mod gnu; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 9aac7be8017..1c25c8f77c1 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -30,7 +30,7 @@ use libc; pub mod weak; pub mod android; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] pub mod backtrace; pub mod condvar; pub mod ext; -- cgit 1.4.1-3-g733a5 From 3d09b4a0d58200da84fe19cd3b0003d61e5b1791 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 27 Jul 2016 12:10:31 +0200 Subject: Rename `char::escape` to `char::escape_debug` and add tracking issue --- src/libcollections/lib.rs | 2 +- src/libcollections/str.rs | 6 +++--- src/libcollectionstest/str.rs | 22 ++++++++++---------- src/libcore/char.rs | 24 +++++++++++----------- src/libcore/fmt/mod.rs | 4 ++-- src/libcoretest/char.rs | 4 ++-- src/libcoretest/lib.rs | 3 ++- src/librustc_unicode/char.rs | 8 ++++---- src/librustc_unicode/lib.rs | 2 +- src/libstd/lib.rs | 15 +++++++------- src/libstd/sys/common/wtf8.rs | 6 +++--- .../run-pass/sync-send-iterators-in-libcore.rs | 2 +- 12 files changed, 50 insertions(+), 48 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 333219bc5e5..7fc6e54d69f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -33,7 +33,7 @@ #![feature(allow_internal_unstable)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(char_escape)] +#![cfg_attr(not(test), feature(char_escape_debug))] #![feature(core_intrinsics)] #![feature(dropck_parametricity)] #![feature(fmt_internals)] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index a63ea9d3ec7..4c64019de09 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1697,12 +1697,12 @@ impl str { return s; } - /// Escapes each char in `s` with `char::escape`. + /// Escapes each char in `s` with `char::escape_debug`. #[unstable(feature = "str_escape", reason = "return type may change to be an iterator", issue = "27791")] - pub fn escape(&self) -> String { - self.chars().flat_map(|c| c.escape()).collect() + pub fn escape_debug(&self) -> String { + self.chars().flat_map(|c| c.escape_debug()).collect() } /// Escapes each char in `s` with `char::escape_default`. diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 870f8a3a1ec..a61925cd3be 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -704,17 +704,17 @@ fn test_escape_unicode() { } #[test] -fn test_escape() { - assert_eq!("abc".escape_default(), "abc"); - assert_eq!("a c".escape_default(), "a c"); - assert_eq!("éèê".escape_default(), "éèê"); - assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t"); - assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\"); - assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\u{ff}"); - assert_eq!("\u{100}\u{ffff}".escape_default(), "\u{100}\\u{ffff}"); - assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\u{10000}\\u{10ffff}"); - assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}"); - assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r"); +fn test_escape_debug() { + assert_eq!("abc".escape_debug(), "abc"); + assert_eq!("a c".escape_debug(), "a c"); + assert_eq!("éèê".escape_debug(), "éèê"); + assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t"); + assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\"); + assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}"); + assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}"); + assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}"); + assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}"); + assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r"); } #[test] diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 3e435b47110..a3440fe8aa6 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -264,8 +264,8 @@ pub trait CharExt { fn escape_unicode(self) -> EscapeUnicode; #[stable(feature = "core", since = "1.6.0")] fn escape_default(self) -> EscapeDefault; - #[unstable(feature = "char_escape", issue = "0")] - fn escape(self) -> Escape; + #[unstable(feature = "char_escape_debug", issue = "35068")] + fn escape_debug(self) -> EscapeDebug; #[stable(feature = "core", since = "1.6.0")] fn len_utf8(self) -> usize; #[stable(feature = "core", since = "1.6.0")] @@ -330,7 +330,7 @@ impl CharExt for char { } #[inline] - fn escape(self) -> Escape { + fn escape_debug(self) -> EscapeDebug { let init_state = match self { '\t' => EscapeDefaultState::Backslash('t'), '\r' => EscapeDefaultState::Backslash('r'), @@ -339,7 +339,7 @@ impl CharExt for char { c if is_printable(c) => EscapeDefaultState::Char(c), c => EscapeDefaultState::Unicode(c.escape_unicode()), }; - Escape(EscapeDefault { state: init_state }) + EscapeDebug(EscapeDefault { state: init_state }) } #[inline] @@ -618,24 +618,24 @@ impl ExactSizeIterator for EscapeDefault { /// An iterator that yields the literal escape code of a `char`. /// -/// This `struct` is created by the [`escape()`] method on [`char`]. See its +/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its /// documentation for more. /// -/// [`escape()`]: ../../std/primitive.char.html#method.escape +/// [`escape_debug()`]: ../../std/primitive.char.html#method.escape_debug /// [`char`]: ../../std/primitive.char.html -#[unstable(feature = "char_escape", issue = "0")] +#[unstable(feature = "char_escape_debug", issue = "35068")] #[derive(Clone, Debug)] -pub struct Escape(EscapeDefault); +pub struct EscapeDebug(EscapeDefault); -#[unstable(feature = "char_escape", issue = "0")] -impl Iterator for Escape { +#[unstable(feature = "char_escape_debug", issue = "35068")] +impl Iterator for EscapeDebug { type Item = char; fn next(&mut self) -> Option { self.0.next() } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } -#[unstable(feature = "char_escape", issue = "0")] -impl ExactSizeIterator for Escape { } +#[unstable(feature = "char_escape_debug", issue = "35068")] +impl ExactSizeIterator for EscapeDebug { } /// An iterator over `u8` entries represending the UTF-8 encoding of a `char` /// value. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3bcdce57af0..173c55e35d5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1383,7 +1383,7 @@ impl Debug for str { f.write_char('"')?; let mut from = 0; for (i, c) in self.char_indices() { - let esc = c.escape(); + let esc = c.escape_debug(); // If char needs escaping, flush backlog so far and write, else skip if esc.len() != 1 { f.write_str(&self[from..i])?; @@ -1409,7 +1409,7 @@ impl Display for str { impl Debug for char { fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('\'')?; - for c in self.escape() { + for c in self.escape_debug() { f.write_char(c)? } f.write_char('\'') diff --git a/src/libcoretest/char.rs b/src/libcoretest/char.rs index ec757b0b5d3..4632419336d 100644 --- a/src/libcoretest/char.rs +++ b/src/libcoretest/char.rs @@ -124,9 +124,9 @@ fn test_is_digit() { } #[test] -fn test_escape() { +fn test_escape_debug() { fn string(c: char) -> String { - c.escape().collect() + c.escape_debug().collect() } let s = string('\n'); assert_eq!(s, "\\n"); diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 1ef2b58351f..ef0042808f9 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -14,6 +14,7 @@ #![feature(borrow_state)] #![feature(box_syntax)] #![feature(cell_extras)] +#![feature(char_escape_debug)] #![feature(const_fn)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -29,10 +30,10 @@ #![feature(slice_patterns)] #![feature(step_by)] #![feature(test)] +#![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] -#![feature(try_from)] extern crate core; extern crate test; diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 683d5289ab5..7e308684a25 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -36,7 +36,7 @@ use tables::{conversions, derived_property, general_category, property}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::char::{EncodeUtf16, EncodeUtf8, Escape, EscapeDefault, EscapeUnicode}; +pub use core::char::{EncodeUtf16, EncodeUtf8, EscapeDebug, EscapeDefault, EscapeUnicode}; // unstable reexports #[unstable(feature = "decode_utf8", issue = "33906")] @@ -296,10 +296,10 @@ impl char { /// /// assert_eq!(quote, "\\n"); /// ``` - #[unstable(feature = "char_escape", issue = "0")] + #[unstable(feature = "char_escape_debug", issue = "35068")] #[inline] - pub fn escape(self) -> Escape { - C::escape(self) + pub fn escape_debug(self) -> EscapeDebug { + C::escape_debug(self) } /// Returns an iterator that yields the literal escape code of a `char`. diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs index 8c91d3b6a92..3ae905eba27 100644 --- a/src/librustc_unicode/lib.rs +++ b/src/librustc_unicode/lib.rs @@ -32,7 +32,7 @@ #![cfg_attr(not(stage0), deny(warnings))] #![no_std] -#![feature(char_escape)] +#![feature(char_escape_debug)] #![feature(core_char_ext)] #![feature(decode_utf8)] #![feature(lang_items)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d05a5a09614..865d067cdb6 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -218,8 +218,9 @@ #![feature(associated_consts)] #![feature(borrow_state)] #![feature(box_syntax)] -#![feature(cfg_target_vendor)] #![feature(cfg_target_thread_local)] +#![feature(cfg_target_vendor)] +#![feature(char_escape_debug)] #![feature(char_internals)] #![feature(collections)] #![feature(collections_bound)] @@ -229,10 +230,10 @@ #![feature(dropck_parametricity)] #![feature(float_extras)] #![feature(float_from_str_radix)] -#![feature(fnbox)] #![feature(fn_traits)] -#![feature(heap_api)] +#![feature(fnbox)] #![feature(hashmap_hasher)] +#![feature(heap_api)] #![feature(inclusive_range)] #![feature(int_error_internals)] #![feature(into_cow)] @@ -242,6 +243,7 @@ #![feature(linkage)] #![feature(macro_reexport)] #![cfg_attr(test, feature(map_values_mut))] +#![feature(needs_panic_runtime)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] @@ -249,10 +251,11 @@ #![feature(optin_builtin_traits)] #![feature(panic_unwind)] #![feature(placement_in_syntax)] +#![feature(question_mark)] #![feature(rand)] #![feature(raw)] -#![feature(repr_simd)] #![feature(reflect_marker)] +#![feature(repr_simd)] #![feature(rustc_attrs)] #![feature(shared)] #![feature(sip_hash_13)] @@ -266,6 +269,7 @@ #![feature(str_utf16)] #![feature(test, rustc_private)] #![feature(thread_local)] +#![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] @@ -273,9 +277,6 @@ #![feature(unwind_attributes)] #![feature(vec_push_all)] #![feature(zero_one)] -#![feature(question_mark)] -#![feature(try_from)] -#![feature(needs_panic_runtime)] // Issue# 30592: Systematically use alloc_system during stage0 since jemalloc // might be unavailable or disabled diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 2c1a656290f..c0e6ec46b55 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -390,7 +390,7 @@ impl fmt::Debug for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn write_str_escaped(f: &mut fmt::Formatter, s: &str) -> fmt::Result { use fmt::Write; - for c in s.chars().flat_map(|c| c.escape_default()) { + for c in s.chars().flat_map(|c| c.escape_debug()) { f.write_char(c)? } Ok(()) @@ -1064,9 +1064,9 @@ mod tests { #[test] fn wtf8buf_show() { - let mut string = Wtf8Buf::from_str("a\té 💩\r"); + let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(format!("{:?}", string), r#""a\t\u{e9} \u{1f4a9}\r\u{D800}""#); + assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{D800}\""); } #[test] diff --git a/src/test/run-pass/sync-send-iterators-in-libcore.rs b/src/test/run-pass/sync-send-iterators-in-libcore.rs index 93178994815..d12bdf182fa 100644 --- a/src/test/run-pass/sync-send-iterators-in-libcore.rs +++ b/src/test/run-pass/sync-send-iterators-in-libcore.rs @@ -67,7 +67,7 @@ macro_rules! is_sync_send { fn main() { // for char.rs - all_sync_send!("Я", escape_default, escape_unicode); + all_sync_send!("Я", escape_debug, escape_default, escape_unicode); // for iter.rs all_sync_send_mutable_ref!([1], iter); -- cgit 1.4.1-3-g733a5 From 8d3f20f9061273b215a7d86f8783f1ae66f9b3ae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Jul 2016 12:55:58 +0200 Subject: Add doc examples for std::fs::unix::OpenOptionsExt --- src/libstd/sys/unix/ext/fs.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 54340773a42..1e0dc3c833e 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -63,6 +63,18 @@ pub trait OpenOptionsExt { /// If no `mode` is set, the default of `0o666` will be used. /// The operating system masks out bits with the systems `umask`, to produce /// the final permissions. + /// + /// # Examples + /// + /// ```rust,ignore + /// extern crate libc; + /// use std::fs::OpenOptions; + /// use std::os::unix::fs::OpenOptionsExt; + /// + /// let mut options = OpenOptions::new(); + /// options.mode(0o644); // Give read/write for owner and read for others. + /// let file = options.open("foo.txt"); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&mut self, mode: u32) -> &mut Self; -- cgit 1.4.1-3-g733a5 From 123bf1e95d05282dc32d9a2403859dd827d84309 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Jul 2016 13:04:24 +0200 Subject: Add OpenOptionsExt doc examples --- src/libstd/sys/unix/ext/fs.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 1e0dc3c833e..77587918ac9 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -25,15 +25,53 @@ use sys::platform::fs::MetadataExt as UnixMetadataExt; pub trait PermissionsExt { /// Returns the underlying raw `mode_t` bits that are the standard Unix /// permissions for this file. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// let f = try!(File::create("foo.txt")); + /// let metadata = try!(f.metadata()); + /// let permissions = metadata.permissions(); + /// + /// println!("permissions: {}", permissions.mode()); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; /// Sets the underlying raw bits for this set of permissions. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// let f = try!(File::create("foo.txt")); + /// let metadata = try!(f.metadata()); + /// let mut permissions = metadata.permissions(); + /// + /// permissions.set_mode(0o644); // Read/write for owner and read for others. + /// assert_eq!(permissions.mode(), 0o644); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); /// Creates a new instance of `Permissions` from the given set of Unix /// permission bits. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::Permissions; + /// use std::os::unix::fs::PermissionsExt; + /// + /// // Read/write for owner and read for others. + /// let permissions = Permissions::from_mode(0o644); + /// assert_eq!(permissions.mode(), 0o644); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn from_mode(mode: u32) -> Self; } -- cgit 1.4.1-3-g733a5 From bb6c27e74d08b78709b6fb87f5cb149f4366ccb6 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Thu, 28 Jul 2016 11:30:38 +0200 Subject: Escape the unmatched surrogates with lower-case hexadecimal numbers It's done the same way for the rest of the codepoint escapes. --- src/libstd/sys/common/wtf8.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index c0e6ec46b55..c1b4f8a8c88 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -408,7 +408,7 @@ impl fmt::Debug for Wtf8 { &self.bytes[pos .. surrogate_pos] )}, )?; - write!(formatter, "\\u{{{:X}}}", surrogate)?; + write!(formatter, "\\u{{{:x}}}", surrogate)?; pos = surrogate_pos + 3; } } @@ -1066,7 +1066,7 @@ mod tests { fn wtf8buf_show() { let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{D800}\""); + assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\""); } #[test] -- cgit 1.4.1-3-g733a5