From 96ce56d5c25cf840ed8d2464666b5e6520eb6374 Mon Sep 17 00:00:00 2001 From: Guillaume Girol Date: Thu, 24 May 2018 23:50:28 +0200 Subject: [PATCH 01/18] std::fs::DirEntry.metadata(): use fstatat instead of lstat when possible --- src/libstd/sys/unix/fs.rs | 43 +++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 77968ffdedf37..e2448ae4a1fef 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -25,6 +25,8 @@ use sys_common::{AsInner, FromInner}; #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))] use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64}; +#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))] +use libc::{fstatat, dirfd}; #[cfg(target_os = "android")] use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64, dirent as dirent64, open as open64}; @@ -48,11 +50,15 @@ pub struct FileAttr { stat: stat64, } -pub struct ReadDir { +// all DirEntry's will have a reference to this struct +struct InnerReadDir { dirp: Dir, - root: Arc, + root: PathBuf, } +#[derive(Clone)] +pub struct ReadDir(Arc); + struct Dir(*mut libc::DIR); unsafe impl Send for Dir {} @@ -60,8 +66,8 @@ unsafe impl Sync for Dir {} pub struct DirEntry { entry: dirent64, - root: Arc, - // We need to store an owned copy of the directory name + dir: ReadDir, + // We need to store an owned copy of the entry name // on Solaris and Fuchsia because a) it uses a zero-length // array to store the name, b) its lifetime between readdir // calls is not guaranteed. @@ -207,7 +213,7 @@ impl fmt::Debug for ReadDir { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame. // Thus the result will be e g 'ReadDir("/home")' - fmt::Debug::fmt(&*self.root, f) + fmt::Debug::fmt(&*self.0.root, f) } } @@ -240,7 +246,7 @@ impl Iterator for ReadDir { entry: *entry_ptr, name: ::slice::from_raw_parts(name as *const u8, namelen as usize).to_owned().into_boxed_slice(), - root: self.root.clone() + dir: self.clone() }; if ret.name_bytes() != b"." && ret.name_bytes() != b".." { return Some(Ok(ret)) @@ -254,11 +260,11 @@ impl Iterator for ReadDir { unsafe { let mut ret = DirEntry { entry: mem::zeroed(), - root: self.root.clone() + dir: self.clone(), }; let mut entry_ptr = ptr::null_mut(); loop { - if readdir64_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { + if readdir64_r(self.0.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { return Some(Err(Error::last_os_error())) } if entry_ptr.is_null() { @@ -281,13 +287,27 @@ impl Drop for Dir { impl DirEntry { pub fn path(&self) -> PathBuf { - self.root.join(OsStr::from_bytes(self.name_bytes())) + self.dir.0.root.join(OsStr::from_bytes(self.name_bytes())) } pub fn file_name(&self) -> OsString { OsStr::from_bytes(self.name_bytes()).to_os_string() } + #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))] + pub fn metadata(&self) -> io::Result { + let fd = cvt(unsafe {dirfd(self.dir.0.dirp.0)})?; + let mut stat: stat64 = unsafe { mem::zeroed() }; + cvt(unsafe { + fstatat(fd, + self.entry.d_name.as_ptr(), + &mut stat as *mut _ as *mut _, + libc::AT_SYMLINK_NOFOLLOW) + })?; + Ok(FileAttr { stat: stat }) + } + + #[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "android")))] pub fn metadata(&self) -> io::Result { lstat(&self.path()) } @@ -664,14 +684,15 @@ impl fmt::Debug for File { } pub fn readdir(p: &Path) -> io::Result { - let root = Arc::new(p.to_path_buf()); + let root = p.to_path_buf(); let p = cstr(p)?; unsafe { let ptr = libc::opendir(p.as_ptr()); if ptr.is_null() { Err(Error::last_os_error()) } else { - Ok(ReadDir { dirp: Dir(ptr), root: root }) + let inner = InnerReadDir { dirp: Dir(ptr), root }; + Ok(ReadDir(Arc::new(inner))) } } } From 202cbafd3d67736fc0a124fcfe67999f5fca9750 Mon Sep 17 00:00:00 2001 From: Abhishek koserwal Date: Mon, 28 May 2018 17:27:15 +0530 Subject: [PATCH 02/18] Update build instructions --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 19ef96fae015c..04816762f14cb 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Read ["Installation"] from [The Book]. 3. Build and install: ```sh + $ git submodule update --init --recursive --progress $ ./x.py build && sudo ./x.py install ``` From b54fb5eda3d0f753834cf42cafe3719c0657c809 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 28 May 2018 09:18:04 -0400 Subject: [PATCH 03/18] Add doc link from discriminant struct to function. --- src/libcore/mem.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 059c099d66b56..c033b670798c4 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -835,7 +835,9 @@ pub unsafe fn transmute_copy(src: &T) -> U { /// Opaque type representing the discriminant of an enum. /// -/// See the `discriminant` function in this module for more information. +/// See the [`discriminant`] function in this module for more information. +/// +/// [`discriminant`]: fn.discriminant.html #[stable(feature = "discriminant_value", since = "1.21.0")] pub struct Discriminant(u64, PhantomData T>); From 125b32ca2eecc1c4ecca5ddf46f391eabe61e682 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Mon, 28 May 2018 20:19:39 -0600 Subject: [PATCH 04/18] Stabilize SliceIndex trait. Fixes #35729 According to recommendations in https://github.com/rust-lang/rust/issues/35729#issuecomment-377784884 --- src/liballoc/lib.rs | 1 - src/liballoc/slice.rs | 2 +- src/libcore/slice/mod.rs | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 91de3ad0c390b..a56420d52d0d5 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -104,7 +104,6 @@ #![feature(ptr_internals)] #![feature(ptr_offset_from)] #![feature(rustc_attrs)] -#![feature(slice_get_slice)] #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 161493f389226..8686ecd7bcf7b 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -121,7 +121,7 @@ pub use core::slice::{RSplit, RSplitMut}; pub use core::slice::{from_raw_parts, from_raw_parts_mut}; #[stable(feature = "from_ref", since = "1.28.0")] pub use core::slice::{from_ref, from_mut}; -#[unstable(feature = "slice_get_slice", issue = "35729")] +#[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; #[unstable(feature = "exact_chunks", issue = "47115")] pub use core::slice::{ExactChunks, ExactChunksMut}; diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ab986e4c86d88..878c1051d54e8 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1977,35 +1977,69 @@ fn slice_index_overflow_fail() -> ! { panic!("attempted to index slice up to maximum usize"); } +mod private_slice_index { + use super::ops; + #[stable(feature = "slice_get_slice", since = "1.28.0")] + pub trait Sealed {} + + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for usize {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::Range {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::RangeTo {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::RangeFrom {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::RangeFull {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::RangeInclusive {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl Sealed for ops::RangeToInclusive {} +} + /// A helper trait used for indexing operations. -#[unstable(feature = "slice_get_slice", issue = "35729")] +#[stable(feature = "slice_get_slice", since = "1.28.0")] #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] -pub trait SliceIndex { +pub trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. + #[stable(feature = "slice_get_slice", since = "1.28.0")] type Output: ?Sized; /// Returns a shared reference to the output at this location, if in /// bounds. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] fn get(self, slice: &T) -> Option<&Self::Output>; /// Returns a mutable reference to the output at this location, if in /// bounds. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>; /// Returns a shared reference to the output at this location, without /// performing any bounds checking. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, without /// performing any bounds checking. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output; /// Returns a shared reference to the output at this location, panicking /// if out of bounds. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] fn index(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, panicking /// if out of bounds. + #[unstable(feature = "slice_index_methods", issue = "0")] + #[doc(hidden)] fn index_mut(self, slice: &mut T) -> &mut Self::Output; } From 068fc44c04f77a9ae1c7662c08ccdf56639f09c5 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Tue, 29 May 2018 00:56:49 -0600 Subject: [PATCH 05/18] Make implentation methods for SliceIndex #[doc(hidden)] --- src/libcore/slice/mod.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 878c1051d54e8..0df3088c1ff28 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2048,6 +2048,7 @@ impl SliceIndex<[T]> for usize { type Output = T; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&T> { if self < slice.len() { unsafe { @@ -2059,6 +2060,7 @@ impl SliceIndex<[T]> for usize { } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { if self < slice.len() { unsafe { @@ -2070,22 +2072,26 @@ impl SliceIndex<[T]> for usize { } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &T { &*slice.as_ptr().offset(self as isize) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T { &mut *slice.as_mut_ptr().offset(self as isize) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &T { // NB: use intrinsic indexing &(*slice)[self] } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut T { // NB: use intrinsic indexing &mut (*slice)[self] @@ -2097,6 +2103,7 @@ impl SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { if self.start > self.end || self.end > slice.len() { None @@ -2108,6 +2115,7 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if self.start > self.end || self.end > slice.len() { None @@ -2119,16 +2127,19 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { from_raw_parts(slice.as_ptr().offset(self.start as isize), self.end - self.start) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { from_raw_parts_mut(slice.as_mut_ptr().offset(self.start as isize), self.end - self.start) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { if self.start > self.end { slice_index_order_fail(self.start, self.end); @@ -2141,6 +2152,7 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.start > self.end { slice_index_order_fail(self.start, self.end); @@ -2158,31 +2170,37 @@ impl SliceIndex<[T]> for ops::RangeTo { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (0..self.end).get(slice) } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..self.end).get_mut(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (0..self.end).get_unchecked(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (0..self.end).get_unchecked_mut(slice) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (0..self.end).index(slice) } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..self.end).index_mut(slice) } @@ -2193,31 +2211,37 @@ impl SliceIndex<[T]> for ops::RangeFrom { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (self.start..slice.len()).get(slice) } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (self.start..slice.len()).get_mut(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (self.start..slice.len()).get_unchecked(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..slice.len()).get_unchecked_mut(slice) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (self.start..slice.len()).index(slice) } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..slice.len()).index_mut(slice) } @@ -2228,31 +2252,37 @@ impl SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { Some(slice) } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { Some(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { slice } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { slice } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { slice } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { slice } @@ -2264,34 +2294,40 @@ impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { if self.end == usize::max_value() { None } else { (self.start..self.end + 1).get(slice) } } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if self.end == usize::max_value() { None } else { (self.start..self.end + 1).get_mut(slice) } } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (self.start..self.end + 1).get_unchecked(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..self.end + 1).get_unchecked_mut(slice) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index(slice) } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index_mut(slice) @@ -2303,31 +2339,37 @@ impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; #[inline] + #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (0..=self.end).get(slice) } #[inline] + #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..=self.end).get_mut(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (0..=self.end).get_unchecked(slice) } #[inline] + #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.end).get_unchecked_mut(slice) } #[inline] + #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (0..=self.end).index(slice) } #[inline] + #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.end).index_mut(slice) } From 5b1be00dd786583f2efc321d1309de8b0506fe45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 29 May 2018 10:41:33 +0300 Subject: [PATCH 06/18] Move slice::exact_chunks directly above exact_chunks_mut for more consistent docs order See https://github.com/rust-lang/rust/issues/47115#issuecomment-392532855 --- src/libcore/slice/mod.rs | 70 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ab986e4c86d88..e1e08392a23b3 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -691,41 +691,6 @@ impl [T] { Chunks { v: self, chunk_size: chunk_size } } - /// Returns an iterator over `chunk_size` elements of the slice at a - /// time. The chunks are slices and do not overlap. If `chunk_size` does - /// not divide the length of the slice, then the last up to `chunk_size-1` - /// elements will be omitted. - /// - /// Due to each chunk having exactly `chunk_size` elements, the compiler - /// can often optimize the resulting code better than in the case of - /// [`chunks`]. - /// - /// # Panics - /// - /// Panics if `chunk_size` is 0. - /// - /// # Examples - /// - /// ``` - /// #![feature(exact_chunks)] - /// - /// let slice = ['l', 'o', 'r', 'e', 'm']; - /// let mut iter = slice.exact_chunks(2); - /// assert_eq!(iter.next().unwrap(), &['l', 'o']); - /// assert_eq!(iter.next().unwrap(), &['r', 'e']); - /// assert!(iter.next().is_none()); - /// ``` - /// - /// [`chunks`]: #method.chunks - #[unstable(feature = "exact_chunks", issue = "47115")] - #[inline] - pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks { - assert!(chunk_size != 0); - let rem = self.len() % chunk_size; - let len = self.len() - rem; - ExactChunks { v: &self[..len], chunk_size: chunk_size} - } - /// Returns an iterator over `chunk_size` elements of the slice at a time. /// The chunks are mutable slices, and do not overlap. If `chunk_size` does /// not divide the length of the slice, then the last chunk will not @@ -761,6 +726,41 @@ impl [T] { ChunksMut { v: self, chunk_size: chunk_size } } + /// Returns an iterator over `chunk_size` elements of the slice at a + /// time. The chunks are slices and do not overlap. If `chunk_size` does + /// not divide the length of the slice, then the last up to `chunk_size-1` + /// elements will be omitted. + /// + /// Due to each chunk having exactly `chunk_size` elements, the compiler + /// can often optimize the resulting code better than in the case of + /// [`chunks`]. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + /// + /// # Examples + /// + /// ``` + /// #![feature(exact_chunks)] + /// + /// let slice = ['l', 'o', 'r', 'e', 'm']; + /// let mut iter = slice.exact_chunks(2); + /// assert_eq!(iter.next().unwrap(), &['l', 'o']); + /// assert_eq!(iter.next().unwrap(), &['r', 'e']); + /// assert!(iter.next().is_none()); + /// ``` + /// + /// [`chunks`]: #method.chunks + #[unstable(feature = "exact_chunks", issue = "47115")] + #[inline] + pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks { + assert!(chunk_size != 0); + let rem = self.len() % chunk_size; + let len = self.len() - rem; + ExactChunks { v: &self[..len], chunk_size: chunk_size} + } + /// Returns an iterator over `chunk_size` elements of the slice at a time. /// The chunks are mutable slices, and do not overlap. If `chunk_size` does /// not divide the length of the slice, then the last up to `chunk_size-1` From 0d821db6a7f23744720994a43013a1d018fdc3ea Mon Sep 17 00:00:00 2001 From: CrLF0710 Date: Tue, 29 May 2018 15:58:50 +0800 Subject: [PATCH 07/18] Replace `if` with `if and only if` in the definition dox of `Sync` The old text was: "The precise definition is: a type T is Sync if &T is Send." Since we've also got ``` impl<'a, T> Send for &'a T where T: Sync + ?Sized, ``` I purpose we can change the `if` to `if and only if` to make it more precise. --- src/libcore/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 77db165bcbde3..3d3f63ecf37d5 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -294,7 +294,7 @@ pub trait Copy : Clone { /// This trait is automatically implemented when the compiler determines /// it's appropriate. /// -/// The precise definition is: a type `T` is `Sync` if `&T` is +/// The precise definition is: a type `T` is `Sync` if and only if `&T` is /// [`Send`][send]. In other words, if there is no possibility of /// [undefined behavior][ub] (including data races) when passing /// `&T` references between threads. From 11c39acfd6a40cab1fb795fdb6c2bb9e128fcd9d Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Tue, 29 May 2018 10:06:13 +0200 Subject: [PATCH 08/18] Link the docs of panic!() and compile_error!() Fixes #47275. These two macros are similar, but different, and could do with documentation links to each other. --- src/libstd/macros.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 8da70f5717e71..b6936987d0b37 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -38,10 +38,13 @@ /// The multi-argument form of this macro panics with a string and has the /// [`format!`] syntax for building a string. /// +/// See also the macro [`compile_error!`], for raising errors during compilation. +/// /// [runwrap]: ../std/result/enum.Result.html#method.unwrap /// [`Option`]: ../std/option/enum.Option.html#method.unwrap /// [`Result`]: ../std/result/enum.Result.html /// [`format!`]: ../std/macro.format.html +/// [`compile_error!`]: ../std/macro.compile_error.html /// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html /// /// # Current implementation @@ -286,7 +289,8 @@ pub mod builtin { /// Unconditionally causes compilation to fail with the given error message when encountered. /// /// This macro should be used when a crate uses a conditional compilation strategy to provide - /// better error messages for erroneous conditions. + /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`], + /// which emits an error at *runtime*, rather than during compilation. /// /// # Examples /// @@ -313,6 +317,8 @@ pub mod builtin { /// #[cfg(not(any(feature = "foo", feature = "bar")))] /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.") /// ``` + /// + /// [`panic!`]: ../std/macro.panic.html #[stable(feature = "compile_error_macro", since = "1.20.0")] #[macro_export] macro_rules! compile_error { From 1d7a0df66176ed45e5cf6975cdcab992ffccd47b Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Tue, 29 May 2018 10:07:14 +0200 Subject: [PATCH 09/18] Add sentence to compile_error!() docs It now details why using compile_error!() is different from just not having the final macro_rules!() branch. --- src/libstd/macros.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index b6936987d0b37..677647da40359 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -296,7 +296,9 @@ pub mod builtin { /// /// Two such examples are macros and `#[cfg]` environments. /// - /// Emit better compiler error if a macro is passed invalid values. + /// Emit better compiler error if a macro is passed invalid values. Without the final branch, + /// the compiler would still emit an error, but the error's message would not mention the two + /// valid values. /// /// ```compile_fail /// macro_rules! give_me_foo_or_bar { From 9fcc61bf9f2148ede0e97537f4b1ecc80e675f09 Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Tue, 29 May 2018 11:31:14 +0200 Subject: [PATCH 10/18] Mention spec and indented blocks in doctest docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a new section to the Documentation Test docs, which briefly mentions indented code blocks, and links to the CommonMark specification for both. I’m not sure about saying "fenced code blocks the more popular choice in the Rust community” because it seems like I’m speaking for everyone, but I can’t think of a better way to phrase it! --- src/doc/rustdoc/src/documentation-tests.md | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index fd7d1713ca574..61cfebb97e74c 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -284,3 +284,27 @@ environment that has no network access. compiles, then the test will fail. However please note that code failing with the current Rust release may work in a future release, as new features are added. + +## Syntax reference + +The *exact* syntax for code blocks, including the edge cases, can be found +in the [Fenced Code Blocks](https://spec.commonmark.org/0.28/#fenced-code-blocks) +section of the CommonMark specification. + +Rustdoc also accepts *indented* code blocks as an alternative to fenced +code blocks: instead of surrounding your code with three backticks, you +can indent each line by four or more spaces. + +``````markdown + let foo = "foo"; + assert_eq!(foo, "foo"); +`````` + +These, too, are documented in the CommonMark specification, in the +[Indented Code Blocks](https://spec.commonmark.org/0.28/#indented-code-blocks) +section. + +However, it's preferable to use fenced code blocks over indented code blocks. +Not only are fenced code blocks the more popular choice in the Rust community, +but there is no way to use directives such as `ignore` or `should_panic` with +indented code blocks. From 18ff09d6605ca24f970aedcdb2951b406d53a2dd Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 29 May 2018 01:51:36 +0000 Subject: [PATCH 11/18] typeck: Do not pass the field check on field error If a struct pattern has a field error return an error. --- src/librustc_typeck/check/_match.rs | 13 ++++++-- src/test/ui/issue-51102.rs | 48 +++++++++++++++++++++++++++++ src/test/ui/issue-51102.stderr | 24 +++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issue-51102.rs create mode 100644 src/test/ui/issue-51102.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 439c0e2d610fa..39b7e24377522 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -720,8 +720,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.demand_eqtype(pat.span, expected, pat_ty); // Type check subpatterns. - self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm); - pat_ty + if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) { + pat_ty + } else { + self.tcx.types.err + } } fn check_pat_path(&self, @@ -846,7 +849,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); variant: &'tcx ty::VariantDef, fields: &'gcx [Spanned], etc: bool, - def_bm: ty::BindingMode) { + def_bm: ty::BindingMode) -> bool { let tcx = self.tcx; let (substs, adt) = match adt_ty.sty { @@ -864,6 +867,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap(); + let mut no_field_errors = true; let mut inexistent_fields = vec![]; // Typecheck each field. @@ -879,6 +883,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); format!("multiple uses of `{}` in pattern", field.ident)) .span_label(*occupied.get(), format!("first use of `{}`", field.ident)) .emit(); + no_field_errors = false; tcx.types.err } Vacant(vacant) => { @@ -891,6 +896,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); }) .unwrap_or_else(|| { inexistent_fields.push((span, field.ident)); + no_field_errors = false; tcx.types.err }) } @@ -989,5 +995,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); diag.emit(); } } + no_field_errors } } diff --git a/src/test/ui/issue-51102.rs b/src/test/ui/issue-51102.rs new file mode 100644 index 0000000000000..c8f106687ae1c --- /dev/null +++ b/src/test/ui/issue-51102.rs @@ -0,0 +1,48 @@ +// Copyright 2018 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. + +enum SimpleEnum { + NoState, +} + +struct SimpleStruct { + no_state_here: u64, +} + +fn main() { + let _ = |simple| { + match simple { + SimpleStruct { + state: 0, + //~^ struct `SimpleStruct` does not have a field named `state` [E0026] + .. + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleStruct { + no_state_here: 0, + no_state_here: 1 + //~^ ERROR field `no_state_here` bound multiple times in the pattern [E0025] + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleEnum::NoState { + state: 0 + //~^ ERROR variant `SimpleEnum::NoState` does not have a field named `state` [E0026] + } => (), + } + }; +} diff --git a/src/test/ui/issue-51102.stderr b/src/test/ui/issue-51102.stderr new file mode 100644 index 0000000000000..a4bd0fb914fee --- /dev/null +++ b/src/test/ui/issue-51102.stderr @@ -0,0 +1,24 @@ +error[E0026]: struct `SimpleStruct` does not have a field named `state` + --> $DIR/issue-51102.rs:23:17 + | +LL | state: 0, + | ^^^^^^^^ struct `SimpleStruct` does not have this field + +error[E0025]: field `no_state_here` bound multiple times in the pattern + --> $DIR/issue-51102.rs:34:17 + | +LL | no_state_here: 0, + | ---------------- first use of `no_state_here` +LL | no_state_here: 1 + | ^^^^^^^^^^^^^^^^ multiple uses of `no_state_here` in pattern + +error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state` + --> $DIR/issue-51102.rs:43:17 + | +LL | state: 0 + | ^^^^^^^^ variant `SimpleEnum::NoState` does not have this field + +error: aborting due to 3 previous errors + +Some errors occurred: E0025, E0026. +For more information about an error, try `rustc --explain E0025`. From 8f8a7b9a7b236ba02afc1589901acc6b125d6fec Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Tue, 29 May 2018 16:04:37 +0200 Subject: [PATCH 12/18] Phrasing tweak in doctest docs --- src/doc/rustdoc/src/documentation-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 61cfebb97e74c..3253e4d6269d4 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -305,6 +305,6 @@ These, too, are documented in the CommonMark specification, in the section. However, it's preferable to use fenced code blocks over indented code blocks. -Not only are fenced code blocks the more popular choice in the Rust community, +Not only are fenced code blocks considered more idiomatic for Rust code, but there is no way to use directives such as `ignore` or `should_panic` with indented code blocks. From 5a0bf0968ff497825a8f335b7e87c7ae3f849bc0 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 29 May 2018 23:25:53 +0200 Subject: [PATCH 13/18] It turns out that the diagnostics generated from NLL for these cases are now exactly the same as that produced by AST borrowck. Bravo! --- .../ui/generator/pattern-borrow.nll.stderr | 11 ------ src/test/ui/issue-45697.nll.stderr | 34 ------------------- 2 files changed, 45 deletions(-) delete mode 100644 src/test/ui/generator/pattern-borrow.nll.stderr delete mode 100644 src/test/ui/issue-45697.nll.stderr diff --git a/src/test/ui/generator/pattern-borrow.nll.stderr b/src/test/ui/generator/pattern-borrow.nll.stderr deleted file mode 100644 index 48f23486a317c..0000000000000 --- a/src/test/ui/generator/pattern-borrow.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0626]: borrow may still be in use when generator yields - --> $DIR/pattern-borrow.rs:19:24 - | -LL | if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when generator yields - | ^^^^^^ -LL | yield (); - | -------- possible yield occurs here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/issue-45697.nll.stderr b/src/test/ui/issue-45697.nll.stderr deleted file mode 100644 index a85972fcd7a1c..0000000000000 --- a/src/test/ui/issue-45697.nll.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast) - --> $DIR/issue-45697.rs:30:9 - | -LL | let z = copy_borrowed_ptr(&mut y); - | - borrow of `*y.pointer` occurs here -LL | *y.pointer += 1; - | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here - -error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir) - --> $DIR/issue-45697.rs:30:9 - | -LL | let z = copy_borrowed_ptr(&mut y); - | ------ borrow of `y` occurs here -LL | *y.pointer += 1; - | ^^^^^^^^^^^^^^^ use of borrowed `y` -... -LL | *z.pointer += 1; - | --------------- borrow later used here - -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir) - --> $DIR/issue-45697.rs:30:9 - | -LL | let z = copy_borrowed_ptr(&mut y); - | ------ borrow of `*y.pointer` occurs here -LL | *y.pointer += 1; - | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here -... -LL | *z.pointer += 1; - | --------------- borrow later used here - -error: aborting due to 3 previous errors - -Some errors occurred: E0503, E0506. -For more information about an error, try `rustc --explain E0503`. From 07b9d17f9faad46491e4ee048ba1b4eb0eaa31d8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 May 2018 11:36:31 +1000 Subject: [PATCH 14/18] Remove `ObligationForest::cache_list`. It's never used in a meaningful way. --- src/librustc_data_structures/obligation_forest/mod.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 42a17d33fa6f5..612f44f09cf65 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -75,9 +75,6 @@ pub struct ObligationForest { done_cache: FxHashSet, /// An cache of the nodes in `nodes`, indexed by predicate. waiting_cache: FxHashMap, - /// A list of the obligations added in snapshots, to allow - /// for their removal. - cache_list: Vec, scratch: Option>, } @@ -158,7 +155,6 @@ impl ObligationForest { nodes: vec![], done_cache: FxHashSet(), waiting_cache: FxHashMap(), - cache_list: vec![], scratch: Some(vec![]), } } @@ -207,7 +203,6 @@ impl ObligationForest { debug!("register_obligation_at({:?}, {:?}) - ok, new index is {}", obligation, parent, self.nodes.len()); v.insert(NodeIndex::new(self.nodes.len())); - self.cache_list.push(obligation.as_predicate().clone()); self.nodes.push(Node::new(parent, obligation)); Ok(()) } From 9b6940d0b46284f24410050e9bfde0a9ab08d0fb Mon Sep 17 00:00:00 2001 From: Nicolas Koch Date: Wed, 30 May 2018 06:33:54 +0200 Subject: [PATCH 15/18] fs: copy: Use File::set_permissions instead of fs::set_permissions We already got the open file descriptor at this point. Don't make the kernel resolve the path again. --- src/libstd/sys/unix/fs.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 889d21cad65aa..9d0d377905720 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -807,14 +807,14 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { let perm = reader.metadata()?.permissions(); let ret = io::copy(&mut reader, &mut writer)?; - set_permissions(to, perm)?; + writer.set_permissions(perm)?; Ok(ret) } #[cfg(any(target_os = "linux", target_os = "android"))] pub fn copy(from: &Path, to: &Path) -> io::Result { use cmp; - use fs::{File, set_permissions}; + use fs::File; use sync::atomic::{AtomicBool, Ordering}; // Kernel prior to 4.5 don't have copy_file_range @@ -886,7 +886,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { // Try again with fallback method assert_eq!(written, 0); let ret = io::copy(&mut reader, &mut writer)?; - set_permissions(to, perm)?; + writer.set_permissions(perm)?; return Ok(ret) }, _ => return Err(err), @@ -894,6 +894,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } } - set_permissions(to, perm)?; + writer.set_permissions(perm)?; Ok(written) } From 71813374aa7c93d02c94ff194d5ef31990ed980a Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Tue, 29 May 2018 22:57:25 -0600 Subject: [PATCH 16/18] Revert "Make implentation methods for SliceIndex #[doc(hidden)]" This reverts commit 068fc44c04f77a9ae1c7662c08ccdf56639f09c5. --- src/libcore/slice/mod.rs | 48 ---------------------------------------- 1 file changed, 48 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0df3088c1ff28..6851f68afda3d 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2009,37 +2009,31 @@ pub trait SliceIndex: private_slice_index::Sealed { /// Returns a shared reference to the output at this location, if in /// bounds. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] fn get(self, slice: &T) -> Option<&Self::Output>; /// Returns a mutable reference to the output at this location, if in /// bounds. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>; /// Returns a shared reference to the output at this location, without /// performing any bounds checking. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, without /// performing any bounds checking. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output; /// Returns a shared reference to the output at this location, panicking /// if out of bounds. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] fn index(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, panicking /// if out of bounds. #[unstable(feature = "slice_index_methods", issue = "0")] - #[doc(hidden)] fn index_mut(self, slice: &mut T) -> &mut Self::Output; } @@ -2048,7 +2042,6 @@ impl SliceIndex<[T]> for usize { type Output = T; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&T> { if self < slice.len() { unsafe { @@ -2060,7 +2053,6 @@ impl SliceIndex<[T]> for usize { } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { if self < slice.len() { unsafe { @@ -2072,26 +2064,22 @@ impl SliceIndex<[T]> for usize { } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &T { &*slice.as_ptr().offset(self as isize) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T { &mut *slice.as_mut_ptr().offset(self as isize) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &T { // NB: use intrinsic indexing &(*slice)[self] } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut T { // NB: use intrinsic indexing &mut (*slice)[self] @@ -2103,7 +2091,6 @@ impl SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { if self.start > self.end || self.end > slice.len() { None @@ -2115,7 +2102,6 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if self.start > self.end || self.end > slice.len() { None @@ -2127,19 +2113,16 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { from_raw_parts(slice.as_ptr().offset(self.start as isize), self.end - self.start) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { from_raw_parts_mut(slice.as_mut_ptr().offset(self.start as isize), self.end - self.start) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { if self.start > self.end { slice_index_order_fail(self.start, self.end); @@ -2152,7 +2135,6 @@ impl SliceIndex<[T]> for ops::Range { } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.start > self.end { slice_index_order_fail(self.start, self.end); @@ -2170,37 +2152,31 @@ impl SliceIndex<[T]> for ops::RangeTo { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (0..self.end).get(slice) } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..self.end).get_mut(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (0..self.end).get_unchecked(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (0..self.end).get_unchecked_mut(slice) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (0..self.end).index(slice) } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..self.end).index_mut(slice) } @@ -2211,37 +2187,31 @@ impl SliceIndex<[T]> for ops::RangeFrom { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (self.start..slice.len()).get(slice) } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (self.start..slice.len()).get_mut(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (self.start..slice.len()).get_unchecked(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..slice.len()).get_unchecked_mut(slice) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (self.start..slice.len()).index(slice) } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..slice.len()).index_mut(slice) } @@ -2252,37 +2222,31 @@ impl SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { Some(slice) } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { Some(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { slice } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { slice } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { slice } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { slice } @@ -2294,40 +2258,34 @@ impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { if self.end == usize::max_value() { None } else { (self.start..self.end + 1).get(slice) } } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if self.end == usize::max_value() { None } else { (self.start..self.end + 1).get_mut(slice) } } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (self.start..self.end + 1).get_unchecked(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (self.start..self.end + 1).get_unchecked_mut(slice) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index(slice) } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index_mut(slice) @@ -2339,37 +2297,31 @@ impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; #[inline] - #[doc(hidden)] fn get(self, slice: &[T]) -> Option<&[T]> { (0..=self.end).get(slice) } #[inline] - #[doc(hidden)] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..=self.end).get_mut(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { (0..=self.end).get_unchecked(slice) } #[inline] - #[doc(hidden)] unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.end).get_unchecked_mut(slice) } #[inline] - #[doc(hidden)] fn index(self, slice: &[T]) -> &[T] { (0..=self.end).index(slice) } #[inline] - #[doc(hidden)] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.end).index_mut(slice) } From b43f76ebcf0bcb36073918b79450331fb15819f0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 May 2018 16:58:48 +1000 Subject: [PATCH 17/18] Inline `NodeIndex` methods. Because they are small and hot. --- src/librustc_data_structures/obligation_forest/node_index.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs index 37512e4bcd57f..d89bd22ec9637 100644 --- a/src/librustc_data_structures/obligation_forest/node_index.rs +++ b/src/librustc_data_structures/obligation_forest/node_index.rs @@ -17,11 +17,13 @@ pub struct NodeIndex { } impl NodeIndex { + #[inline] pub fn new(value: usize) -> NodeIndex { assert!(value < (u32::MAX as usize)); NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() } } + #[inline] pub fn get(self) -> usize { (self.index.get() - 1) as usize } From c5ee3b6df1db2c4410b0e8d7a80a2885cf5628f1 Mon Sep 17 00:00:00 2001 From: Nicolas Koch Date: Wed, 30 May 2018 12:09:20 +0200 Subject: [PATCH 18/18] Remobve unused import --- src/libstd/sys/unix/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 9d0d377905720..758286fce6ca5 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -796,7 +796,7 @@ pub fn canonicalize(p: &Path) -> io::Result { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub fn copy(from: &Path, to: &Path) -> io::Result { - use fs::{File, set_permissions}; + use fs::File; if !from.is_file() { return Err(Error::new(ErrorKind::InvalidInput, "the source path is not an existing regular file"))