From bc45e474a0e871dc2d28abdc75d68d84c5249a8c Mon Sep 17 00:00:00 2001 From: Aaron Rennow Date: Sat, 27 Mar 2021 14:25:52 -0400 Subject: [PATCH 01/16] Add std::os::unix::fs::DirEntryExt2::file_name_ref(&self) -> &OsStr DirEntryExt2 is a new trait with the same purpose as DirEntryExt, but sealed --- library/std/src/os/unix/fs.rs | 38 ++++++++++++++++++++++++++++++++++ library/std/src/sys/unix/fs.rs | 4 ++++ 2 files changed, 42 insertions(+) diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 9cf51be2836fb..3939d3c4ca67a 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -9,6 +9,8 @@ use crate::path::Path; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; // Used for `File::read` on intra-doc links +use crate::ffi::OsStr; +use crate::sealed::Sealed; #[allow(unused_imports)] use io::{Read, Write}; @@ -839,6 +841,42 @@ impl DirEntryExt for fs::DirEntry { } } +/// Sealed Unix-specific extension methods for [`fs::DirEntry`]. +#[unstable(feature = "dir_entry_ext2", issue = "85573")] +pub trait DirEntryExt2: Sealed { + /// Returns a reference to the underlying `OsStr` of this entry's filename. + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::fs::DirEntryExt2; + /// use std::{fs, io}; + /// + /// fn main() -> io::Result<()> { + /// let mut entries = fs::read_dir(".")?.collect::, io::Error>>()?; + /// entries.sort_unstable_by(|a, b| a.file_name_ref().cmp(b.file_name_ref())); + /// + /// for p in entries { + /// println!("{:?}", p); + /// } + /// + /// Ok(()) + /// } + /// ``` + fn file_name_ref(&self) -> &OsStr; +} + +/// Allows extension traits within `std`. +#[unstable(feature = "sealed", issue = "none")] +impl Sealed for fs::DirEntry {} + +#[unstable(feature = "dir_entry_ext2", issue = "85573")] +impl DirEntryExt2 for fs::DirEntry { + fn file_name_ref(&self) -> &OsStr { + self.as_inner().file_name_os_str() + } +} + /// Creates a new symbolic link on the filesystem. /// /// The `link` path will be a symbolic link pointing to the `original` path. diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index ef14865fbcd39..eae156bff4156 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -647,6 +647,10 @@ impl DirEntry { fn name_bytes(&self) -> &[u8] { &*self.name } + + pub fn file_name_os_str(&self) -> &OsStr { + OsStr::from_bytes(self.name_bytes()) + } } impl OpenOptions { From 719dafc48b3a076e9f6341be97bad0cef316f24b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jun 2021 09:19:36 +0200 Subject: [PATCH 02/16] double-check mutability inside Allocation --- compiler/rustc_middle/src/mir/interpret/allocation.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index ee3902991e911..c0cfc7b1ba4ec 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -340,6 +340,8 @@ impl Allocation { range: AllocRange, val: ScalarMaybeUninit, ) -> AllocResult { + assert!(self.mutability == Mutability::Mut); + let val = match val { ScalarMaybeUninit::Scalar(scalar) => scalar, ScalarMaybeUninit::Uninit => { @@ -463,6 +465,7 @@ impl Allocation { if range.size.bytes() == 0 { return; } + assert!(self.mutability == Mutability::Mut); self.init_mask.set_range(range.start, range.end(), is_init); } } From 618c805746dbbc874afa538f97fc5f643aa9f6dc Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 30 Jun 2021 19:59:39 +0100 Subject: [PATCH 03/16] Remove alloc/malloc/calloc/realloc doc aliases --- library/alloc/src/boxed.rs | 3 --- library/alloc/src/macros.rs | 2 -- library/alloc/src/string.rs | 2 -- library/alloc/src/vec/mod.rs | 7 ------- 4 files changed, 14 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 13b42442dcf09..53bfe02d0e7a3 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -187,8 +187,6 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[inline(always)] - #[doc(alias = "alloc")] - #[doc(alias = "malloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn new(x: T) -> Self { box x @@ -239,7 +237,6 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[doc(alias = "calloc")] #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed() -> Box> { Self::new_zeroed_in(Global) diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index 6a64587a2237f..189da9f06392a 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -35,8 +35,6 @@ /// /// [`Vec`]: crate::vec::Vec #[cfg(not(test))] -#[doc(alias = "alloc")] -#[doc(alias = "malloc")] #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(box_syntax, liballoc_internals)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index a34f530762d52..a9c627534fd82 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -419,8 +419,6 @@ impl String { /// ``` #[cfg(not(no_global_oom_handling))] #[inline] - #[doc(alias = "alloc")] - #[doc(alias = "malloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(capacity: usize) -> String { String { vec: Vec::with_capacity(capacity) } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 4ac28b8308e73..08c46cf2f4f27 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -459,7 +459,6 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[inline] - #[doc(alias = "malloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(capacity: usize) -> Self { Self::with_capacity_in(capacity, Global) @@ -799,7 +798,6 @@ impl Vec { /// assert!(vec.capacity() >= 11); /// ``` #[cfg(not(no_global_oom_handling))] - #[doc(alias = "realloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve(&mut self, additional: usize) { self.buf.reserve(self.len, additional); @@ -826,7 +824,6 @@ impl Vec { /// assert!(vec.capacity() >= 11); /// ``` #[cfg(not(no_global_oom_handling))] - #[doc(alias = "realloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve_exact(&mut self, additional: usize) { self.buf.reserve_exact(self.len, additional); @@ -864,7 +861,6 @@ impl Vec { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[doc(alias = "realloc")] #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.buf.try_reserve(self.len, additional) @@ -906,7 +902,6 @@ impl Vec { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[doc(alias = "realloc")] #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.buf.try_reserve_exact(self.len, additional) @@ -927,7 +922,6 @@ impl Vec { /// assert!(vec.capacity() >= 3); /// ``` #[cfg(not(no_global_oom_handling))] - #[doc(alias = "realloc")] #[stable(feature = "rust1", since = "1.0.0")] pub fn shrink_to_fit(&mut self) { // The capacity is never less than the length, and there's nothing to do when @@ -958,7 +952,6 @@ impl Vec { /// assert!(vec.capacity() >= 3); /// ``` #[cfg(not(no_global_oom_handling))] - #[doc(alias = "realloc")] #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")] pub fn shrink_to(&mut self, min_capacity: usize) { if self.capacity() > min_capacity { From fc2705d707db7b219a8af48ee8f5385354ff5da3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 30 Jun 2021 20:25:57 +0100 Subject: [PATCH 04/16] Remove "delete" doc aliases --- library/alloc/src/collections/btree/map.rs | 1 - library/alloc/src/collections/btree/set.rs | 1 - library/std/src/collections/hash/map.rs | 1 - library/std/src/collections/hash/set.rs | 1 - library/std/src/fs.rs | 3 --- 5 files changed, 7 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index d7519c6d0936c..1cc1e6b04de19 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -889,7 +889,6 @@ impl BTreeMap { /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` - #[doc(alias = "delete")] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, key: &Q) -> Option where diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 737932d931c02..bb7818c5c2e79 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -810,7 +810,6 @@ impl BTreeSet { /// assert_eq!(set.remove(&2), true); /// assert_eq!(set.remove(&2), false); /// ``` - #[doc(alias = "delete")] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool where diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index a1f52a9c2e880..0f87681aaea1d 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -893,7 +893,6 @@ where /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` - #[doc(alias = "delete")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, k: &Q) -> Option diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 5220c8ad70977..27b0336a05633 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -875,7 +875,6 @@ where /// assert_eq!(set.remove(&2), true); /// assert_eq!(set.remove(&2), false); /// ``` - #[doc(alias = "delete")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 9076656f64e9f..2abde9896c54a 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1551,7 +1551,6 @@ impl AsInner for DirEntry { /// Ok(()) /// } /// ``` -#[doc(alias = "delete")] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_file>(path: P) -> io::Result<()> { fs_imp::unlink(path.as_ref()) @@ -1986,7 +1985,6 @@ pub fn create_dir_all>(path: P) -> io::Result<()> { /// Ok(()) /// } /// ``` -#[doc(alias = "delete")] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir>(path: P) -> io::Result<()> { fs_imp::rmdir(path.as_ref()) @@ -2024,7 +2022,6 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// Ok(()) /// } /// ``` -#[doc(alias = "delete")] #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir_all>(path: P) -> io::Result<()> { fs_imp::remove_dir_all(path.as_ref()) From e2536bb271ead2228f5a7c54db043fe681d61b3f Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 30 Jun 2021 20:25:04 +0100 Subject: [PATCH 05/16] Remove "length" doc aliases --- library/alloc/src/collections/binary_heap.rs | 1 - library/alloc/src/collections/btree/map.rs | 1 - library/alloc/src/collections/btree/set.rs | 1 - library/alloc/src/collections/linked_list.rs | 1 - library/alloc/src/collections/vec_deque/mod.rs | 1 - library/alloc/src/string.rs | 1 - library/alloc/src/vec/mod.rs | 1 - library/core/src/iter/traits/exact_size.rs | 1 - library/core/src/slice/mod.rs | 1 - library/core/src/str/mod.rs | 1 - library/std/src/collections/hash/map.rs | 1 - library/std/src/collections/hash/set.rs | 1 - library/std/src/ffi/os_str.rs | 1 - 13 files changed, 13 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 544e18d1ff391..2f656e4a6b4ac 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -1034,7 +1034,6 @@ impl BinaryHeap { /// /// assert_eq!(heap.len(), 2); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { self.data.len() diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 1cc1e6b04de19..dfd693d13b330 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2164,7 +2164,6 @@ impl BTreeMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")] pub const fn len(&self) -> usize { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index bb7818c5c2e79..34ec27e461c75 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1020,7 +1020,6 @@ impl BTreeSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")] pub const fn len(&self) -> usize { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 1a58ad51f78d3..da9de6831a4cd 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -586,7 +586,6 @@ impl LinkedList { /// dl.push_back(3); /// assert_eq!(dl.len(), 3); /// ``` - #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 5d03be35e466f..461e701be054e 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1036,7 +1036,6 @@ impl VecDeque { /// v.push_back(1); /// assert_eq!(v.len(), 1); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { count(self.tail, self.head, self.cap()) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index a9c627534fd82..f7247e947e4db 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1532,7 +1532,6 @@ impl String { /// assert_eq!(fancy_f.len(), 4); /// assert_eq!(fancy_f.chars().count(), 3); /// ``` - #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 08c46cf2f4f27..61599259735c7 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1813,7 +1813,6 @@ impl Vec { /// let a = vec![1, 2, 3]; /// assert_eq!(a.len(), 3); /// ``` - #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs index 167db3359f240..a476799b70d6c 100644 --- a/library/core/src/iter/traits/exact_size.rs +++ b/library/core/src/iter/traits/exact_size.rs @@ -97,7 +97,6 @@ pub trait ExactSizeIterator: Iterator { /// /// assert_eq!(5, five.len()); /// ``` - #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn len(&self) -> usize { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 27cb70d9c8e5c..de25c984abf90 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -95,7 +95,6 @@ impl [T] { /// let a = [1, 2, 3]; /// assert_eq!(a.len(), 3); /// ``` - #[doc(alias = "length")] #[cfg_attr(not(bootstrap), lang = "slice_len_fn")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 065acd3f38bb2..7ca95a02dd8f4 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -138,7 +138,6 @@ impl str { /// assert_eq!("ƒoo".len(), 4); // fancy f! /// assert_eq!("ƒoo".chars().count(), 3); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_len", since = "1.39.0")] #[inline] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 0f87681aaea1d..d7cb8a556367c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -454,7 +454,6 @@ impl HashMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` - #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { self.base.len() diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 27b0336a05633..272e1c2be2b40 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -202,7 +202,6 @@ impl HashSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` - #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index ca391ffb3d56c..2a85f375ae279 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -694,7 +694,6 @@ impl OsStr { /// let os_str = OsStr::new("foo"); /// assert_eq!(os_str.len(), 3); /// ``` - #[doc(alias = "length")] #[stable(feature = "osstring_simple_functions", since = "1.9.0")] #[inline] pub fn len(&self) -> usize { From 6d34a2e0074c5ce3e0da4743616ec5b3e96253fb Mon Sep 17 00:00:00 2001 From: Aris Merchant <22333129+inquisitivecrystal@users.noreply.github.com> Date: Thu, 1 Jul 2021 15:07:09 -0700 Subject: [PATCH 06/16] Stabilize `Seek::rewind` --- library/std/src/io/mod.rs | 3 +-- library/std/src/io/tests.rs | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 00b85604a3f67..594cef27b4138 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1736,7 +1736,6 @@ pub trait Seek { /// # Example /// /// ```no_run - /// #![feature(seek_rewind)] /// use std::io::{Read, Seek, Write}; /// use std::fs::OpenOptions; /// @@ -1754,7 +1753,7 @@ pub trait Seek { /// f.read_to_string(&mut buf).unwrap(); /// assert_eq!(&buf, hello); /// ``` - #[unstable(feature = "seek_rewind", issue = "85149")] + #[stable(feature = "seek_rewind", since = "1.55.0")] fn rewind(&mut self) -> Result<()> { self.seek(SeekFrom::Start(0))?; Ok(()) diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index b73bcf85fbee2..1beb72a9a5072 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -336,6 +336,10 @@ fn seek_position() -> io::Result<()> { assert_eq!(c.stream_position()?, 8); assert_eq!(c.stream_position()?, 8); + c.rewind()?; + assert_eq!(c.stream_position()?, 0); + assert_eq!(c.stream_position()?, 0); + Ok(()) } From a8bb7fa76b3d9d288ad12e9a86be96ee0e6abadf Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 13 May 2021 18:59:41 +0100 Subject: [PATCH 07/16] aborts: Clarify documentation and comments In the docs for intrinsics::abort(): * Strengthen the recommendation by to use process::abort instead. * Document the fact that it (ab)uses an LLVM debug trap and what the likely consequences are. * State that the precise behaviour is unstable. In the docs for process::abort(): * Promise that we have the same behaviour as C `abort()`. * Document the likely consequences, including, specifically, the consequences on Unix. In the internal comment for unix::abort_internal: * Refer to the public docs for the public API functions. * Correct and expand the description of libc::abort. Specifically: * Do not claim that abort() unregisters signal handlers. It doesn't; it honours the SIGABRT handler. * Discuss, extensively, the issue with abort() flushing stdio buffers. * Describe the glibc behaviour in some detail. Co-authored-by: Mark Wooding Signed-off-by: Ian Jackson --- library/core/src/intrinsics.rs | 8 +++++-- library/std/src/process.rs | 4 ++++ library/std/src/sys/unix/mod.rs | 42 +++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index b4311bbe5f41f..8be4f5997693c 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -717,8 +717,12 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. /// - /// A more user-friendly and stable version of this operation is - /// [`std::process::abort`](../../std/process/fn.abort.html). + /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible, + /// as its behaviour is more user-friendly and more stable. + /// + /// The current implementation of `intrinsics::abort` (ab)uses a debug trap. On Unix, the + /// process will probably die of a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or + /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. pub fn abort() -> !; /// Informs the optimizer that this point in the code is not reachable, diff --git a/library/std/src/process.rs b/library/std/src/process.rs index b46d3dfc1e7c6..95108f96e061c 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1908,6 +1908,10 @@ pub fn exit(code: i32) -> ! { /// this function at a known point where there are no more destructors left /// to run. /// +/// The process's termination will be similar to that from the C `abort()` +/// function. On Unix, the process will die with signal `SIGABRT`, which +/// typically means that the shell prints "Aborted". +/// /// # Examples /// /// ```no_run diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index f3535b27128b3..2da71b2a448ac 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -217,13 +217,41 @@ pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> { if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) } } -// On Unix-like platforms, libc::abort will unregister signal handlers -// including the SIGABRT handler, preventing the abort from being blocked, and -// fclose streams, with the side effect of flushing them so libc buffered -// output will be printed. Additionally the shell will generally print a more -// understandable error message like "Abort trap" rather than "Illegal -// instruction" that intrinsics::abort would cause, as intrinsics::abort is -// implemented as an illegal instruction. +// libc::abort() will run the SIGABRT handler. That's fine because anyone who +// installs a SIGABRT handler already has to expect it to run in Very Bad +// situations (eg, malloc crashing). +// +// Current glibc's abort() function unblocks SIGABRT, raises SIGABRT, clears the +// SIGABRT handler and raises it again, and then starts to get creative. +// +// See the public documentation for `intrinsics::abort()` and `process::abort()` +// for further discussion. +// +// There is confusion about whether libc::abort() flushes stdio streams. +// libc::abort() is required by ISO C 99 (7.14.1.1p5) to be async-signal-safe, +// so flushing streams is at least extremely hard, if not entirely impossible. +// +// However, some versions of POSIX (eg IEEE Std 1003.1-2001) required abort to +// do so. In 1003.1-2004 this was fixed. +// +// glibc's implementation did the flush, unsafely, before glibc commit +// 91e7cf982d01 `abort: Do not flush stdio streams [BZ #15436]' by Florian +// Weimer. According to glibc's NEWS: +// +// The abort function terminates the process immediately, without flushing +// stdio streams. Previous glibc versions used to flush streams, resulting +// in deadlocks and further data corruption. This change also affects +// process aborts as the result of assertion failures. +// +// This is an accurate description of the problem. The only solution for +// program with nontrivial use of C stdio is a fixed libc - one which does not +// try to flush in abort - since even libc-internal errors, and assertion +// failures generated from C, will go via abort(). +// +// On systems with old, buggy, libcs, the impact can be severe for a +// multithreaded C program. It is much less severe for Rust, because Rust +// stdlib doesn't use libc stdio buffering. In a typical Rust program, which +// does not use C stdio, even a buggy libc::abort() is, in fact, safe. pub fn abort_internal() -> ! { unsafe { libc::abort() } } From de19e4d2b6328f09f11abea5e56cb22a0fe6536e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 17 May 2021 15:23:47 +0100 Subject: [PATCH 08/16] abort docs: Do not claim that intrinsics::abort is always a debug trap As per discussion here https://github.com/rust-lang/rust/pull/85377#pullrequestreview-660460501 Signed-off-by: Ian Jackson --- library/core/src/intrinsics.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 8be4f5997693c..12229009ec831 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -720,7 +720,9 @@ extern "rust-intrinsic" { /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible, /// as its behaviour is more user-friendly and more stable. /// - /// The current implementation of `intrinsics::abort` (ab)uses a debug trap. On Unix, the + /// The current implementation of `intrinsics::abort` (ab)uses a debug trap + /// on some popular platforms. + /// On Unix, the /// process will probably die of a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. pub fn abort() -> !; From 4e7c348140b0ddc074c874f27399a3149a67e84d Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 17 May 2021 15:29:47 +0100 Subject: [PATCH 09/16] abort docs: Document buffer non-flushing There is discussion of this in #40230 which requests clarification. Signed-off-by: Ian Jackson --- library/std/src/process.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 95108f96e061c..00027591a13ba 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1898,6 +1898,9 @@ pub fn exit(code: i32) -> ! { /// process, no destructors on the current stack or any other thread's stack /// will be run. /// +/// Rust IO buffers (eg, from `BufWriter`) will not be flushed. +/// Likewise, C stdio buffers will (on most platforms) not be flushed. +/// /// This is in contrast to the default behaviour of [`panic!`] which unwinds /// the current thread's stack and calls all destructors. /// When `panic="abort"` is set, either as an argument to `rustc` or in a From 44852e06039c037b3b44bea306ef7a7ce4d83929 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 7 Jun 2021 12:10:46 +0100 Subject: [PATCH 10/16] Talk about invalid instructions rather than debug traps And withdraw the allegation of "abuse". Adapted from a suggestion by @m-ou-se. Co-authored-by: Mara Bos Signed-off-by: Ian Jackson --- library/core/src/intrinsics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 12229009ec831..57508c1869275 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -720,8 +720,8 @@ extern "rust-intrinsic" { /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible, /// as its behaviour is more user-friendly and more stable. /// - /// The current implementation of `intrinsics::abort` (ab)uses a debug trap - /// on some popular platforms. + /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction, + /// on most platforms. /// On Unix, the /// process will probably die of a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. From 19c347ede96a439cc7045f23b7e087a17ac6bd0a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 7 Jun 2021 12:12:53 +0100 Subject: [PATCH 11/16] Talk about "terminate" rather than "die" Adapted from a suggestion by @m-ou-se. Co-authored-by: Mara Bos Signed-off-by: Ian Jackson --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 57508c1869275..7391992ca090f 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -723,7 +723,7 @@ extern "rust-intrinsic" { /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction, /// on most platforms. /// On Unix, the - /// process will probably die of a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or + /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. pub fn abort() -> !; From f73a555fc9b5def7f444b58eff69965910a662ff Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 5 Jul 2021 12:40:23 +0200 Subject: [PATCH 12/16] Use american spelling for behaviour Co-authored-by: Yuki Okushi --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7391992ca090f..c5a4bbd320804 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -718,7 +718,7 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible, - /// as its behaviour is more user-friendly and more stable. + /// as its behavior is more user-friendly and more stable. /// /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction, /// on most platforms. From 08d912fdcc4b9c8af3c00db78804f85abfadbd7a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 5 Jul 2021 12:43:45 +0200 Subject: [PATCH 13/16] s/die/terminate/ in abort documentation. --- library/std/src/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 00027591a13ba..11a0432ce27a1 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1912,7 +1912,7 @@ pub fn exit(code: i32) -> ! { /// to run. /// /// The process's termination will be similar to that from the C `abort()` -/// function. On Unix, the process will die with signal `SIGABRT`, which +/// function. On Unix, the process will terminate with signal `SIGABRT`, which /// typically means that the shell prints "Aborted". /// /// # Examples From 4fa54066b2f9e13233f4b438601296306aa95b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 5 Jul 2021 14:17:18 +0300 Subject: [PATCH 14/16] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 1fa82adfdca50..e5c1c8cf2fcfa 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 1fa82adfdca502a13f4dd952f9a50574870f5b7b +Subproject commit e5c1c8cf2fcfae3e15c8bcf5256e84cad3bd3436 From 469f4674fbed038c9d7675f1ae08354a6175b8e9 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 5 Jul 2021 16:26:54 +0200 Subject: [PATCH 15/16] Enable dir_entry_ext2 feature in doc test. Co-authored-by: Yuki Okushi --- library/std/src/os/unix/fs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 3939d3c4ca67a..f0abeba094d22 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -849,6 +849,7 @@ pub trait DirEntryExt2: Sealed { /// # Examples /// /// ``` + /// #![feature(dir_entry_ext2)] /// use std::os::unix::fs::DirEntryExt2; /// use std::{fs, io}; /// From 6f931da0f6abba92f4177e11407025e2b088da65 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 5 Jul 2021 11:18:13 -0400 Subject: [PATCH 16/16] Remove `impl Clean for {Ident, Symbol}` These were only used once, in a place where it was trivial to replace. Also, it's unclear what 'clean' would mean for these, so it seems better to be explicit. --- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7b1b23ff8e6d3..1edb855a5d63e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -552,7 +552,7 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item let source = format!( "macro_rules! {} {{\n{}}}", - name.clean(cx), + name, utils::render_macro_arms(matchers, ";") ); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b0e75493aa4dc..cc086427dd0cd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1814,20 +1814,6 @@ impl Clean for hir::PathSegment<'_> { } } -impl Clean for Ident { - #[inline] - fn clean(&self, cx: &mut DocContext<'_>) -> String { - self.name.clean(cx) - } -} - -impl Clean for Symbol { - #[inline] - fn clean(&self, _: &mut DocContext<'_>) -> String { - self.to_string() - } -} - impl Clean for hir::BareFnTy<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| {