From 3803c090f85b3601414e7b6ed4467b38e1de8bf4 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 29 May 2021 10:08:00 +0200 Subject: [PATCH 01/19] Rename IoSlice(Mut)::advance to advance_slice To make way for a new IoSlice(Mut)::advance function that advances a single slice. Also changes the signature to accept a `&mut &mut [IoSlice]`, not returning anything. This will better match the future IoSlice::advance function. --- library/std/src/io/mod.rs | 19 +++++++++---------- library/std/src/io/tests.rs | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4c154dbe01a5a..39b5ba41843c6 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -253,6 +253,7 @@ mod tests; use crate::cmp; use crate::fmt; +use crate::mem::replace; use crate::ops::{Deref, DerefMut}; use crate::ptr; use crate::slice; @@ -1070,13 +1071,13 @@ impl<'a> IoSliceMut<'a> { /// ][..]; /// /// // Mark 10 bytes as read. - /// bufs = IoSliceMut::advance(bufs, 10); + /// IoSliceMut::advance_slice(&mut bufs, 10); /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); /// ``` #[unstable(feature = "io_slice_advance", issue = "62726")] #[inline] - pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] { + pub fn advance_slice(bufs: &mut &mut [IoSliceMut<'a>], n: usize) { // Number of buffers to remove. let mut remove = 0; // Total length of all the to be removed buffers. @@ -1090,11 +1091,10 @@ impl<'a> IoSliceMut<'a> { } } - let bufs = &mut bufs[remove..]; + *bufs = &mut replace(bufs, &mut [])[remove..]; if !bufs.is_empty() { bufs[0].0.advance(n - accumulated_len) } - bufs } } @@ -1179,12 +1179,12 @@ impl<'a> IoSlice<'a> { /// ][..]; /// /// // Mark 10 bytes as written. - /// bufs = IoSlice::advance(bufs, 10); + /// IoSlice::advance_slice(&mut bufs, 10); /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); #[unstable(feature = "io_slice_advance", issue = "62726")] #[inline] - pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] { + pub fn advance_slice(bufs: &mut &mut [IoSlice<'a>], n: usize) { // Number of buffers to remove. let mut remove = 0; // Total length of all the to be removed buffers. @@ -1198,11 +1198,10 @@ impl<'a> IoSlice<'a> { } } - let bufs = &mut bufs[remove..]; + *bufs = &mut replace(bufs, &mut [])[remove..]; if !bufs.is_empty() { bufs[0].0.advance(n - accumulated_len) } - bufs } } @@ -1511,7 +1510,7 @@ pub trait Write { fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> { // Guarantee that bufs is empty if it contains no data, // to avoid calling write_vectored if there is no data to be written. - bufs = IoSlice::advance(bufs, 0); + IoSlice::advance_slice(&mut bufs, 0); while !bufs.is_empty() { match self.write_vectored(bufs) { Ok(0) => { @@ -1520,7 +1519,7 @@ pub trait Write { &"failed to write whole buffer", )); } - Ok(n) => bufs = IoSlice::advance(bufs, n), + Ok(n) => IoSlice::advance_slice(&mut bufs, n), Err(ref e) if e.kind() == ErrorKind::Interrupted => {} Err(e) => return Err(e), } diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 2b14e16150317..0618a03a68084 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -353,7 +353,7 @@ fn test_read_to_end_capacity() -> io::Result<()> { } #[test] -fn io_slice_mut_advance() { +fn io_slice_mut_advance_slice() { let mut buf1 = [1; 8]; let mut buf2 = [2; 16]; let mut buf3 = [3; 8]; @@ -364,75 +364,75 @@ fn io_slice_mut_advance() { ][..]; // Only in a single buffer.. - bufs = IoSliceMut::advance(bufs, 1); + IoSliceMut::advance_slice(&mut bufs, 1); assert_eq!(bufs[0].deref(), [1; 7].as_ref()); assert_eq!(bufs[1].deref(), [2; 16].as_ref()); assert_eq!(bufs[2].deref(), [3; 8].as_ref()); // Removing a buffer, leaving others as is. - bufs = IoSliceMut::advance(bufs, 7); + IoSliceMut::advance_slice(&mut bufs, 7); assert_eq!(bufs[0].deref(), [2; 16].as_ref()); assert_eq!(bufs[1].deref(), [3; 8].as_ref()); // Removing a buffer and removing from the next buffer. - bufs = IoSliceMut::advance(bufs, 18); + IoSliceMut::advance_slice(&mut bufs, 18); assert_eq!(bufs[0].deref(), [3; 6].as_ref()); } #[test] -fn io_slice_mut_advance_empty_slice() { - let empty_bufs = &mut [][..]; +fn io_slice_mut_advance_slice_empty_slice() { + let mut empty_bufs = &mut [][..]; // Shouldn't panic. - IoSliceMut::advance(empty_bufs, 1); + IoSliceMut::advance_slice(&mut empty_bufs, 1); } #[test] -fn io_slice_mut_advance_beyond_total_length() { +fn io_slice_mut_advance_slice_beyond_total_length() { let mut buf1 = [1; 8]; let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; // Going beyond the total length should be ok. - bufs = IoSliceMut::advance(bufs, 9); + IoSliceMut::advance_slice(&mut bufs, 9); assert!(bufs.is_empty()); } #[test] -fn io_slice_advance() { +fn io_slice_advance_slice() { let buf1 = [1; 8]; let buf2 = [2; 16]; let buf3 = [3; 8]; let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; // Only in a single buffer.. - bufs = IoSlice::advance(bufs, 1); + IoSlice::advance_slice(&mut bufs, 1); assert_eq!(bufs[0].deref(), [1; 7].as_ref()); assert_eq!(bufs[1].deref(), [2; 16].as_ref()); assert_eq!(bufs[2].deref(), [3; 8].as_ref()); // Removing a buffer, leaving others as is. - bufs = IoSlice::advance(bufs, 7); + IoSlice::advance_slice(&mut bufs, 7); assert_eq!(bufs[0].deref(), [2; 16].as_ref()); assert_eq!(bufs[1].deref(), [3; 8].as_ref()); // Removing a buffer and removing from the next buffer. - bufs = IoSlice::advance(bufs, 18); + IoSlice::advance_slice(&mut bufs, 18); assert_eq!(bufs[0].deref(), [3; 6].as_ref()); } #[test] -fn io_slice_advance_empty_slice() { - let empty_bufs = &mut [][..]; +fn io_slice_advance_slice_empty_slice() { + let mut empty_bufs = &mut [][..]; // Shouldn't panic. - IoSlice::advance(empty_bufs, 1); + IoSlice::advance_slice(&mut empty_bufs, 1); } #[test] -fn io_slice_advance_beyond_total_length() { +fn io_slice_advance_slice_beyond_total_length() { let buf1 = [1; 8]; let mut bufs = &mut [IoSlice::new(&buf1)][..]; // Going beyond the total length should be ok. - bufs = IoSlice::advance(bufs, 9); + IoSlice::advance_slice(&mut bufs, 9); assert!(bufs.is_empty()); } From 49e25b5ef2be2577693aee585b58e0b6dbd79c1d Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 29 May 2021 10:18:19 +0200 Subject: [PATCH 02/19] Add IoSlice(Mut)::advance Advance the internal cursor of a single slice. --- library/std/src/io/mod.rs | 56 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 39b5ba41843c6..4746db5a9fdef 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1045,6 +1045,32 @@ impl<'a> IoSliceMut<'a> { /// Advance the internal cursor of the slice. /// + /// Also see [`IoSliceMut::advance_slice`] to advance the cursors of + /// multiple buffers. + /// + /// # Examples + /// + /// ``` + /// #![feature(io_slice_advance)] + /// + /// use std::io::IoSliceMut; + /// use std::ops::Deref; + /// + /// let mut data = [1; 8]; + /// let mut buf = IoSliceMut::new(&mut data); + /// + /// // Mark 10 bytes as read. + /// buf.advance(3); + /// assert_eq!(buf.deref(), [1; 5].as_ref()); + /// ``` + #[unstable(feature = "io_slice_advance", issue = "62726")] + #[inline] + pub fn advance(&mut self, n: usize) { + self.0.advance(n) + } + + /// Advance the internal cursor of the slices. + /// /// # Notes /// /// Elements in the slice may be modified if the cursor is not advanced to @@ -1093,7 +1119,7 @@ impl<'a> IoSliceMut<'a> { *bufs = &mut replace(bufs, &mut [])[remove..]; if !bufs.is_empty() { - bufs[0].0.advance(n - accumulated_len) + bufs[0].advance(n - accumulated_len) } } } @@ -1153,6 +1179,32 @@ impl<'a> IoSlice<'a> { /// Advance the internal cursor of the slice. /// + /// Also see [`IoSlice::advance_slice`] to advance the cursors of multiple + /// buffers. + /// + /// # Examples + /// + /// ``` + /// #![feature(io_slice_advance)] + /// + /// use std::io::IoSlice; + /// use std::ops::Deref; + /// + /// let mut data = [1; 8]; + /// let mut buf = IoSlice::new(&mut data); + /// + /// // Mark 10 bytes as read. + /// buf.advance(3); + /// assert_eq!(buf.deref(), [1; 5].as_ref()); + /// ``` + #[unstable(feature = "io_slice_advance", issue = "62726")] + #[inline] + pub fn advance(&mut self, n: usize) { + self.0.advance(n) + } + + /// Advance the internal cursor of the slices. + /// /// # Notes /// /// Elements in the slice may be modified if the cursor is not advanced to @@ -1200,7 +1252,7 @@ impl<'a> IoSlice<'a> { *bufs = &mut replace(bufs, &mut [])[remove..]; if !bufs.is_empty() { - bufs[0].0.advance(n - accumulated_len) + bufs[0].advance(n - accumulated_len) } } } From fd14c5207544971aab92bbbd3d2a47723b91b284 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 5 Jun 2021 13:06:10 +0200 Subject: [PATCH 03/19] Rename IoSlice(Mut)::advance_slice to advance_slices --- library/std/src/io/mod.rs | 16 ++++++++-------- library/std/src/io/tests.rs | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4746db5a9fdef..7187ec71bc9e3 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1045,7 +1045,7 @@ impl<'a> IoSliceMut<'a> { /// Advance the internal cursor of the slice. /// - /// Also see [`IoSliceMut::advance_slice`] to advance the cursors of + /// Also see [`IoSliceMut::advance_slices`] to advance the cursors of /// multiple buffers. /// /// # Examples @@ -1097,13 +1097,13 @@ impl<'a> IoSliceMut<'a> { /// ][..]; /// /// // Mark 10 bytes as read. - /// IoSliceMut::advance_slice(&mut bufs, 10); + /// IoSliceMut::advance_slices(&mut bufs, 10); /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); /// ``` #[unstable(feature = "io_slice_advance", issue = "62726")] #[inline] - pub fn advance_slice(bufs: &mut &mut [IoSliceMut<'a>], n: usize) { + pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) { // Number of buffers to remove. let mut remove = 0; // Total length of all the to be removed buffers. @@ -1179,7 +1179,7 @@ impl<'a> IoSlice<'a> { /// Advance the internal cursor of the slice. /// - /// Also see [`IoSlice::advance_slice`] to advance the cursors of multiple + /// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple /// buffers. /// /// # Examples @@ -1231,12 +1231,12 @@ impl<'a> IoSlice<'a> { /// ][..]; /// /// // Mark 10 bytes as written. - /// IoSlice::advance_slice(&mut bufs, 10); + /// IoSlice::advance_slices(&mut bufs, 10); /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); #[unstable(feature = "io_slice_advance", issue = "62726")] #[inline] - pub fn advance_slice(bufs: &mut &mut [IoSlice<'a>], n: usize) { + pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) { // Number of buffers to remove. let mut remove = 0; // Total length of all the to be removed buffers. @@ -1562,7 +1562,7 @@ pub trait Write { fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> { // Guarantee that bufs is empty if it contains no data, // to avoid calling write_vectored if there is no data to be written. - IoSlice::advance_slice(&mut bufs, 0); + IoSlice::advance_slices(&mut bufs, 0); while !bufs.is_empty() { match self.write_vectored(bufs) { Ok(0) => { @@ -1571,7 +1571,7 @@ pub trait Write { &"failed to write whole buffer", )); } - Ok(n) => IoSlice::advance_slice(&mut bufs, n), + Ok(n) => IoSlice::advance_slices(&mut bufs, n), Err(ref e) if e.kind() == ErrorKind::Interrupted => {} Err(e) => return Err(e), } diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 0618a03a68084..df0dc7e9d31f6 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -353,7 +353,7 @@ fn test_read_to_end_capacity() -> io::Result<()> { } #[test] -fn io_slice_mut_advance_slice() { +fn io_slice_mut_advance_slices() { let mut buf1 = [1; 8]; let mut buf2 = [2; 16]; let mut buf3 = [3; 8]; @@ -364,75 +364,75 @@ fn io_slice_mut_advance_slice() { ][..]; // Only in a single buffer.. - IoSliceMut::advance_slice(&mut bufs, 1); + IoSliceMut::advance_slices(&mut bufs, 1); assert_eq!(bufs[0].deref(), [1; 7].as_ref()); assert_eq!(bufs[1].deref(), [2; 16].as_ref()); assert_eq!(bufs[2].deref(), [3; 8].as_ref()); // Removing a buffer, leaving others as is. - IoSliceMut::advance_slice(&mut bufs, 7); + IoSliceMut::advance_slices(&mut bufs, 7); assert_eq!(bufs[0].deref(), [2; 16].as_ref()); assert_eq!(bufs[1].deref(), [3; 8].as_ref()); // Removing a buffer and removing from the next buffer. - IoSliceMut::advance_slice(&mut bufs, 18); + IoSliceMut::advance_slices(&mut bufs, 18); assert_eq!(bufs[0].deref(), [3; 6].as_ref()); } #[test] -fn io_slice_mut_advance_slice_empty_slice() { +fn io_slice_mut_advance_slices_empty_slice() { let mut empty_bufs = &mut [][..]; // Shouldn't panic. - IoSliceMut::advance_slice(&mut empty_bufs, 1); + IoSliceMut::advance_slices(&mut empty_bufs, 1); } #[test] -fn io_slice_mut_advance_slice_beyond_total_length() { +fn io_slice_mut_advance_slices_beyond_total_length() { let mut buf1 = [1; 8]; let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; // Going beyond the total length should be ok. - IoSliceMut::advance_slice(&mut bufs, 9); + IoSliceMut::advance_slices(&mut bufs, 9); assert!(bufs.is_empty()); } #[test] -fn io_slice_advance_slice() { +fn io_slice_advance_slices() { let buf1 = [1; 8]; let buf2 = [2; 16]; let buf3 = [3; 8]; let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; // Only in a single buffer.. - IoSlice::advance_slice(&mut bufs, 1); + IoSlice::advance_slices(&mut bufs, 1); assert_eq!(bufs[0].deref(), [1; 7].as_ref()); assert_eq!(bufs[1].deref(), [2; 16].as_ref()); assert_eq!(bufs[2].deref(), [3; 8].as_ref()); // Removing a buffer, leaving others as is. - IoSlice::advance_slice(&mut bufs, 7); + IoSlice::advance_slices(&mut bufs, 7); assert_eq!(bufs[0].deref(), [2; 16].as_ref()); assert_eq!(bufs[1].deref(), [3; 8].as_ref()); // Removing a buffer and removing from the next buffer. - IoSlice::advance_slice(&mut bufs, 18); + IoSlice::advance_slices(&mut bufs, 18); assert_eq!(bufs[0].deref(), [3; 6].as_ref()); } #[test] -fn io_slice_advance_slice_empty_slice() { +fn io_slice_advance_slices_empty_slice() { let mut empty_bufs = &mut [][..]; // Shouldn't panic. - IoSlice::advance_slice(&mut empty_bufs, 1); + IoSlice::advance_slices(&mut empty_bufs, 1); } #[test] -fn io_slice_advance_slice_beyond_total_length() { +fn io_slice_advance_slices_beyond_total_length() { let buf1 = [1; 8]; let mut bufs = &mut [IoSlice::new(&buf1)][..]; // Going beyond the total length should be ok. - IoSlice::advance_slice(&mut bufs, 9); + IoSlice::advance_slices(&mut bufs, 9); assert!(bufs.is_empty()); } From 2727c3b174831df54703bae1f32744550fc78b83 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 May 2021 10:07:56 +0000 Subject: [PATCH 04/19] Document Arc::from --- library/alloc/src/sync.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fdc4..9ae133d2c8c96 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2300,6 +2300,20 @@ impl Hash for Arc { #[stable(feature = "from_for_ptrs", since = "1.6.0")] impl From for Arc { + /// Converts a `T` into an `Arc` + /// + /// The conversion moves the value into a + /// newly allocated `Arc`. It is equivalent to + /// calling `Arc::new(t)`. + /// + /// # Example + /// ```rust + /// # use std::sync::Arc; + /// let x = 5; + /// let arc = Arc::new(5); + /// + /// assert_eq!(Arc::from(x), arc); + /// ``` fn from(t: T) -> Self { Arc::new(t) } From 4fe4ff95f6c459d98c2449c9993e0f7e0b8c47d3 Mon Sep 17 00:00:00 2001 From: Smitty Date: Tue, 15 Jun 2021 19:16:10 -0400 Subject: [PATCH 05/19] Use better error message for hard errors in CTFE Currently the same message is used for hard errors and soft errors. This makes hard errors use a message that indicates the reality of the situation correctly, since usage of the constant is never allowed when there was a hard error evaluating it. --- compiler/rustc_mir/src/const_eval/error.rs | 8 +-- .../rustc_mir/src/const_eval/eval_queries.rs | 5 +- src/test/ui/consts/const-eval/const_panic.rs | 20 +++---- .../ui/consts/const-eval/const_panic.stderr | 60 +++++++------------ .../const-eval/const_panic_libcore_bin.rs | 6 +- .../const-eval/const_panic_libcore_bin.stderr | 18 ++---- .../const-eval/panic-assoc-never-type.rs | 2 +- .../const-eval/panic-assoc-never-type.stderr | 6 +- .../ui/consts/const-eval/panic-never-type.rs | 2 +- .../consts/const-eval/panic-never-type.stderr | 6 +- src/test/ui/consts/const-eval/unwind-abort.rs | 2 +- .../ui/consts/const-eval/unwind-abort.stderr | 5 +- src/test/ui/consts/const-unwrap.stderr | 7 +-- .../control-flow/assert.const_panic.stderr | 6 +- src/test/ui/consts/control-flow/assert.rs | 2 +- 15 files changed, 58 insertions(+), 97 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/error.rs b/compiler/rustc_mir/src/const_eval/error.rs index fc21047ab72ff..17e8ab2a4da63 100644 --- a/compiler/rustc_mir/src/const_eval/error.rs +++ b/compiler/rustc_mir/src/const_eval/error.rs @@ -157,7 +157,7 @@ impl<'tcx> ConstEvalErr<'tcx> { tcx: TyCtxtAt<'tcx>, message: &str, emit: impl FnOnce(DiagnosticBuilder<'_>), - mut lint_root: Option, + lint_root: Option, ) -> ErrorHandled { let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option| { trace!("reporting const eval failure at {:?}", self.span); @@ -194,12 +194,6 @@ impl<'tcx> ConstEvalErr<'tcx> { _ => {} }; - // If we have a 'hard error', then set `lint_root` to `None` so that we don't - // emit a lint. - if matches!(&self.error, InterpError::MachineStop(err) if err.is_hard_err()) { - lint_root = None; - } - let err_msg = self.error.to_string(); // Regular case - emit a lint. diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 460fea37461e8..6adb6e3495883 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -2,8 +2,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr, Memory use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, - Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Scalar, - ScalarMaybeUninit, StackPopCleanup, + Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, + RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, }; use crate::util::pretty::display_allocation; @@ -315,6 +315,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let emit_as_lint = if let Some(def) = def.as_local() { // (Associated) consts only emit a lint, since they might be unused. matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) + && !matches!(&err.error, InterpError::MachineStop(err) if err.is_hard_err()) } else { // use of broken constant from other crate: always an error false diff --git a/src/test/ui/consts/const-eval/const_panic.rs b/src/test/ui/consts/const-eval/const_panic.rs index b33b1475a2221..5807c5659b615 100644 --- a/src/test/ui/consts/const-eval/const_panic.rs +++ b/src/test/ui/consts/const-eval/const_panic.rs @@ -5,31 +5,31 @@ const MSG: &str = "hello"; const Z: () = std::panic!("cheese"); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Z2: () = std::panic!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Y: () = std::unreachable!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const X: () = std::unimplemented!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed // const W: () = std::panic!(MSG); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Z_CORE: () = core::panic!("cheese"); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Z2_CORE: () = core::panic!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Y_CORE: () = core::unreachable!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const X_CORE: () = core::unimplemented!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const W_CORE: () = core::panic!(MSG); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index 3c890f78af741..c0c749ede5612 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -1,100 +1,80 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:7:15 | LL | const Z: () = std::panic!("cheese"); - | --------------^^^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:7:15 + | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:7:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:10:16 | LL | const Z2: () = std::panic!(); - | ---------------^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:10:16 + | ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:10:16 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:13:15 | LL | const Y: () = std::unreachable!(); - | --------------^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:13:15 + | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:13:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:16:15 | LL | const X: () = std::unimplemented!(); - | --------------^^^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:16:15 + | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:16:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:19:15 | LL | const W: () = std::panic!(MSG); - | --------------^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:19:15 + | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:19:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:22:20 | LL | const Z_CORE: () = core::panic!("cheese"); - | -------------------^^^^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20 + | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:25:21 | LL | const Z2_CORE: () = core::panic!(); - | --------------------^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21 + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:28:20 | LL | const Y_CORE: () = core::unreachable!(); - | -------------------^^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20 + | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:31:20 | LL | const X_CORE: () = core::unimplemented!(); - | -------------------^^^^^^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20 + | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:34:20 | LL | const W_CORE: () = core::panic!(MSG); - | -------------------^^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20 + | ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_bin.rs b/src/test/ui/consts/const-eval/const_panic_libcore_bin.rs index 6b03e847def14..1ea0845c968c6 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_bin.rs +++ b/src/test/ui/consts/const-eval/const_panic_libcore_bin.rs @@ -7,13 +7,13 @@ use core::panic::PanicInfo; const Z: () = panic!("cheese"); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const Y: () = unreachable!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed const X: () = unimplemented!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed #[lang = "eh_personality"] fn eh() {} diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr index 2a3ad3ca18060..9abf8a20b8a35 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr @@ -1,30 +1,24 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:9:15 | LL | const Z: () = panic!("cheese"); - | --------------^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_bin.rs:9:15 + | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_bin.rs:9:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:12:15 | LL | const Y: () = unreachable!(); - | --------------^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_bin.rs:12:15 + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_bin.rs:12:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:15:15 | LL | const X: () = unimplemented!(); - | --------------^^^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_bin.rs:15:15 + | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_bin.rs:15:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs index dd18a98035bca..78cf25308fff9 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs @@ -9,7 +9,7 @@ struct PrintName; impl PrintName { const VOID: ! = panic!(); - //~^ ERROR any use of this value will cause an error + //~^ ERROR evaluation of constant value failed } fn main() { diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr index e186240f53ad2..085609483098b 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -1,10 +1,8 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/panic-assoc-never-type.rs:11:21 | LL | const VOID: ! = panic!(); - | ----------------^^^^^^^^- - | | - | the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:11:21 + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:11:21 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/panic-never-type.rs b/src/test/ui/consts/const-eval/panic-never-type.rs index 71b489d828c08..dd875768b168f 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.rs +++ b/src/test/ui/consts/const-eval/panic-never-type.rs @@ -4,7 +4,7 @@ #![feature(never_type)] const VOID: ! = panic!(); -//~^ ERROR any use of this value will cause an error +//~^ ERROR evaluation of constant value failed fn main() { let _ = VOID; diff --git a/src/test/ui/consts/const-eval/panic-never-type.stderr b/src/test/ui/consts/const-eval/panic-never-type.stderr index 2254c3dcfdfb0..9b7f2181c1662 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.stderr +++ b/src/test/ui/consts/const-eval/panic-never-type.stderr @@ -1,10 +1,8 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/panic-never-type.rs:6:17 | LL | const VOID: ! = panic!(); - | ----------------^^^^^^^^- - | | - | the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:6:17 + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:6:17 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/unwind-abort.rs b/src/test/ui/consts/const-eval/unwind-abort.rs index 9bc63d9328c69..766a0c49be68a 100644 --- a/src/test/ui/consts/const-eval/unwind-abort.rs +++ b/src/test/ui/consts/const-eval/unwind-abort.rs @@ -2,7 +2,7 @@ #[unwind(aborts)] const fn foo() { - panic!() //~ ERROR any use of this value will cause an error + panic!() //~ ERROR evaluation of constant value failed } const _: () = foo(); diff --git a/src/test/ui/consts/const-eval/unwind-abort.stderr b/src/test/ui/consts/const-eval/unwind-abort.stderr index b41d786169b9e..e3b871ee529be 100644 --- a/src/test/ui/consts/const-eval/unwind-abort.stderr +++ b/src/test/ui/consts/const-eval/unwind-abort.stderr @@ -1,4 +1,4 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/unwind-abort.rs:5:5 | LL | panic!() @@ -6,10 +6,9 @@ LL | panic!() | | | the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:5:5 | inside `foo` at $SRC_DIR/std/src/panic.rs:LL:COL - | inside `_` at $DIR/unwind-abort.rs:8:15 ... LL | const _: () = foo(); - | -------------------- + | ----- inside `_` at $DIR/unwind-abort.rs:8:15 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-unwrap.stderr b/src/test/ui/consts/const-unwrap.stderr index 95f4711cb65b0..9a820ff721719 100644 --- a/src/test/ui/consts/const-unwrap.stderr +++ b/src/test/ui/consts/const-unwrap.stderr @@ -1,4 +1,4 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/option.rs:LL:COL | LL | None => panic!("called `Option::unwrap()` on a `None` value"), @@ -6,12 +6,11 @@ LL | None => panic!("called `Option::unwrap()` on a `None` value"), | | | the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:9:38 | inside `Option::::unwrap` at $SRC_DIR/core/src/panic.rs:LL:COL - | inside `BAR` at $DIR/const-unwrap.rs:9:18 | - ::: $DIR/const-unwrap.rs:9:1 + ::: $DIR/const-unwrap.rs:9:18 | LL | const BAR: i32 = Option::::None.unwrap(); - | ---------------------------------------------- + | ---------------------------- inside `BAR` at $DIR/const-unwrap.rs:9:18 | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/control-flow/assert.const_panic.stderr b/src/test/ui/consts/control-flow/assert.const_panic.stderr index 8e1a2b5eb4610..1deaa937edb37 100644 --- a/src/test/ui/consts/control-flow/assert.const_panic.stderr +++ b/src/test/ui/consts/control-flow/assert.const_panic.stderr @@ -1,10 +1,8 @@ -error[E0080]: any use of this value will cause an error +error[E0080]: evaluation of constant value failed --> $DIR/assert.rs:10:15 | LL | const _: () = assert!(false); - | --------------^^^^^^^^^^^^^^- - | | - | the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:10:15 + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:10:15 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/control-flow/assert.rs b/src/test/ui/consts/control-flow/assert.rs index 90017fee19337..b311cb140ccf6 100644 --- a/src/test/ui/consts/control-flow/assert.rs +++ b/src/test/ui/consts/control-flow/assert.rs @@ -9,6 +9,6 @@ const _: () = assert!(true); const _: () = assert!(false); //[stock]~^ ERROR panicking in constants is unstable -//[const_panic]~^^ ERROR any use of this value will cause an error +//[const_panic]~^^ ERROR evaluation of constant value failed fn main() {} From c8a8a23a31e9e4831ccab4efbc085852b7a86fa5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jun 2021 09:44:47 +0900 Subject: [PATCH 06/19] Do not emit invalid suggestions on multiple mutable borrow errors --- .../diagnostics/conflict_errors.rs | 8 ++++++ .../diagnostics/explain_borrow.rs | 26 +++++++++++++------ src/test/ui/borrowck/issue-85581.rs | 15 +++++++++++ src/test/ui/borrowck/issue-85581.stderr | 17 ++++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/borrowck/issue-85581.rs create mode 100644 src/test/ui/borrowck/issue-85581.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 8b0761889b834..a0c9b43d5afee 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -453,6 +453,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", Some(borrow_span), + None, ); err.buffer(&mut self.errors_buffer); } @@ -498,6 +499,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); err } @@ -718,6 +720,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, first_borrow_desc, None, + Some((issued_span, span)), ); err @@ -1076,6 +1079,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); } } else { @@ -1093,6 +1097,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); } @@ -1158,6 +1163,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); err.buffer(&mut self.errors_buffer); @@ -1236,6 +1242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); let within = if borrow_spans.for_generator() { " by generator" } else { "" }; @@ -1614,6 +1621,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut err, "", None, + None, ); self.explain_deref_coercion(loan, &mut err); diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index e9f1ecb9bbc81..76de010d1393b 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -66,6 +66,7 @@ impl BorrowExplanation { err: &mut DiagnosticBuilder<'_>, borrow_desc: &str, borrow_span: Option, + multiple_borrow_span: Option<(Span, Span)>, ) { match *self { BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => { @@ -192,14 +193,23 @@ impl BorrowExplanation { if let Some(info) = &local_decl.is_block_tail { if info.tail_result_is_ignored { - err.span_suggestion_verbose( - info.span.shrink_to_hi(), - "consider adding semicolon after the expression so its \ - temporaries are dropped sooner, before the local variables \ - declared by the block are dropped", - ";".to_string(), - Applicability::MaybeIncorrect, - ); + // #85581: If the first mutable borrow's scope contains + // the second borrow, this suggestion isn't helpful. + if !multiple_borrow_span + .map(|(old, new)| { + old.to(info.span.shrink_to_hi()).contains(new) + }) + .unwrap_or(false) + { + err.span_suggestion_verbose( + info.span.shrink_to_hi(), + "consider adding semicolon after the expression so its \ + temporaries are dropped sooner, before the local variables \ + declared by the block are dropped", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } } else { err.note( "the temporary is part of an expression at the end of a \ diff --git a/src/test/ui/borrowck/issue-85581.rs b/src/test/ui/borrowck/issue-85581.rs new file mode 100644 index 0000000000000..ccc120c5421f5 --- /dev/null +++ b/src/test/ui/borrowck/issue-85581.rs @@ -0,0 +1,15 @@ +// Regression test of #85581. +// Checks not to suggest to add `;` when the second mutable borrow +// is in the first's scope. + +use std::collections::BinaryHeap; + +fn foo(heap: &mut BinaryHeap) { + match heap.peek_mut() { + Some(_) => { heap.pop(); }, + //~^ ERROR: cannot borrow `*heap` as mutable more than once at a time + None => (), + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-85581.stderr b/src/test/ui/borrowck/issue-85581.stderr new file mode 100644 index 0000000000000..29c0429f2a046 --- /dev/null +++ b/src/test/ui/borrowck/issue-85581.stderr @@ -0,0 +1,17 @@ +error[E0499]: cannot borrow `*heap` as mutable more than once at a time + --> $DIR/issue-85581.rs:9:22 + | +LL | match heap.peek_mut() { + | --------------- + | | + | first mutable borrow occurs here + | a temporary with access to the first borrow is created here ... +LL | Some(_) => { heap.pop(); }, + | ^^^^ second mutable borrow occurs here +... +LL | } + | - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. From d828eadd7a29c3aed92704358f1742ba5aa225d8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jun 2021 18:47:26 +0900 Subject: [PATCH 07/19] Remove invalid suggestions for assoc consts on placeholder type error --- compiler/rustc_typeck/src/collect.rs | 26 ++++++++++++------- .../ui/typeck/type-placeholder-fn-in-const.rs | 14 ++++++++++ .../type-placeholder-fn-in-const.stderr | 21 +++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/typeck/type-placeholder-fn-in-const.rs create mode 100644 src/test/ui/typeck/type-placeholder-fn-in-const.stderr diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ee3ac3b62d9ec..05a0a5a6cc04e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -180,8 +180,7 @@ crate fn placeholder_type_error( // Suggest, but only if it is not a function in const or static if suggest { let mut is_fn = false; - let mut is_const = false; - let mut is_static = false; + let mut is_const_or_static = false; if let Some(hir_ty) = hir_ty { if let hir::TyKind::BareFn(_) = hir_ty.kind { @@ -191,19 +190,26 @@ crate fn placeholder_type_error( let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id); let parent_node = tcx.hir().get(parent_id); - if let hir::Node::Item(item) = parent_node { - if let hir::ItemKind::Const(_, _) = item.kind { - is_const = true; - } else if let hir::ItemKind::Static(_, _, _) = item.kind { - is_static = true; - } - } + is_const_or_static = match parent_node { + Node::Item(&hir::Item { + kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..), + .. + }) + | Node::TraitItem(&hir::TraitItem { + kind: hir::TraitItemKind::Const(..), + .. + }) + | Node::ImplItem(&hir::ImplItem { + kind: hir::ImplItemKind::Const(..), .. + }) => true, + _ => false, + }; } } // if function is wrapped around a const or static, // then don't show the suggestion - if !(is_fn && (is_const || is_static)) { + if !(is_fn && is_const_or_static) { err.multipart_suggestion( "use type parameters instead", sugg, diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.rs b/src/test/ui/typeck/type-placeholder-fn-in-const.rs new file mode 100644 index 0000000000000..c27edc8485b92 --- /dev/null +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.rs @@ -0,0 +1,14 @@ +struct MyStruct; + +trait Test { + const TEST: fn() -> _; + //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] + //~| ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] +} + +impl Test for MyStruct { + const TEST: fn() -> _ = 42; + //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] +} + +fn main() {} diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.stderr b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr new file mode 100644 index 0000000000000..662871779a10e --- /dev/null +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr @@ -0,0 +1,21 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/type-placeholder-fn-in-const.rs:4:25 + | +LL | const TEST: fn() -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/type-placeholder-fn-in-const.rs:4:25 + | +LL | const TEST: fn() -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/type-placeholder-fn-in-const.rs:10:25 + | +LL | const TEST: fn() -> _ = 42; + | ^ not allowed in type signatures + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0121`. From fb06d9e0cdffd8b6bcb1eb7f41f0237038611a17 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jun 2021 18:49:40 +0900 Subject: [PATCH 08/19] Move some typeck-related tests to the typeck dir --- src/test/ui/{issues => typeck}/issue-74086.rs | 0 src/test/ui/{issues => typeck}/issue-74086.stderr | 0 src/test/ui/{issues => typeck}/issue-81885.rs | 0 src/test/ui/{issues => typeck}/issue-81885.stderr | 0 src/test/ui/{ => typeck}/typeck-closure-to-unsafe-fn-ptr.rs | 0 src/test/ui/{ => typeck}/typeck-fn-to-unsafe-fn-ptr.rs | 0 src/test/ui/{ => typeck}/typeck_type_placeholder_1.rs | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{issues => typeck}/issue-74086.rs (100%) rename src/test/ui/{issues => typeck}/issue-74086.stderr (100%) rename src/test/ui/{issues => typeck}/issue-81885.rs (100%) rename src/test/ui/{issues => typeck}/issue-81885.stderr (100%) rename src/test/ui/{ => typeck}/typeck-closure-to-unsafe-fn-ptr.rs (100%) rename src/test/ui/{ => typeck}/typeck-fn-to-unsafe-fn-ptr.rs (100%) rename src/test/ui/{ => typeck}/typeck_type_placeholder_1.rs (100%) diff --git a/src/test/ui/issues/issue-74086.rs b/src/test/ui/typeck/issue-74086.rs similarity index 100% rename from src/test/ui/issues/issue-74086.rs rename to src/test/ui/typeck/issue-74086.rs diff --git a/src/test/ui/issues/issue-74086.stderr b/src/test/ui/typeck/issue-74086.stderr similarity index 100% rename from src/test/ui/issues/issue-74086.stderr rename to src/test/ui/typeck/issue-74086.stderr diff --git a/src/test/ui/issues/issue-81885.rs b/src/test/ui/typeck/issue-81885.rs similarity index 100% rename from src/test/ui/issues/issue-81885.rs rename to src/test/ui/typeck/issue-81885.rs diff --git a/src/test/ui/issues/issue-81885.stderr b/src/test/ui/typeck/issue-81885.stderr similarity index 100% rename from src/test/ui/issues/issue-81885.stderr rename to src/test/ui/typeck/issue-81885.stderr diff --git a/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs b/src/test/ui/typeck/typeck-closure-to-unsafe-fn-ptr.rs similarity index 100% rename from src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs rename to src/test/ui/typeck/typeck-closure-to-unsafe-fn-ptr.rs diff --git a/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/ui/typeck/typeck-fn-to-unsafe-fn-ptr.rs similarity index 100% rename from src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs rename to src/test/ui/typeck/typeck-fn-to-unsafe-fn-ptr.rs diff --git a/src/test/ui/typeck_type_placeholder_1.rs b/src/test/ui/typeck/typeck_type_placeholder_1.rs similarity index 100% rename from src/test/ui/typeck_type_placeholder_1.rs rename to src/test/ui/typeck/typeck_type_placeholder_1.rs From 044b3620e7f3d495e859113ecc6aa55e37ddc228 Mon Sep 17 00:00:00 2001 From: Smitty Date: Wed, 16 Jun 2021 18:23:34 -0400 Subject: [PATCH 09/19] Move some hard error logic to InterpError --- .../rustc_middle/src/mir/interpret/error.rs | 10 ++++++ .../rustc_mir/src/const_eval/eval_queries.rs | 32 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 65d9c1dd90efb..cce360713b553 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -502,4 +502,14 @@ impl InterpError<'_> { _ => false, } } + + /// Should this error be reported as a hard error, preventing compilation, or a soft error, + /// causing a deny-by-default lint? + pub fn is_hard_err(&self) -> bool { + use InterpError::*; + match *self { + MachineStop(ref err) => err.is_hard_err(), + _ => false, + } + } } diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 6adb6e3495883..536dbad4f764d 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -2,8 +2,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr, Memory use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, - Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, - RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, + Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Scalar, + ScalarMaybeUninit, StackPopCleanup, }; use crate::util::pretty::display_allocation; @@ -312,23 +312,17 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let err = ConstEvalErr::new(&ecx, error, None); // Some CTFE errors raise just a lint, not a hard error; see // . - let emit_as_lint = if let Some(def) = def.as_local() { + let is_hard_err = if let Some(def) = def.as_local() { // (Associated) consts only emit a lint, since they might be unused. - matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) - && !matches!(&err.error, InterpError::MachineStop(err) if err.is_hard_err()) + !matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) + // check if the inner InterpError is hard + || err.error.is_hard_err() } else { // use of broken constant from other crate: always an error - false + true }; - if emit_as_lint { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); - Err(err.report_as_lint( - tcx.at(tcx.def_span(def.did)), - "any use of this value will cause an error", - hir_id, - Some(err.span), - )) - } else { + + if is_hard_err { let msg = if is_static { Cow::from("could not evaluate static initializer") } else { @@ -346,6 +340,14 @@ pub fn eval_to_allocation_raw_provider<'tcx>( }; Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), &msg)) + } else { + let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); + Err(err.report_as_lint( + tcx.at(tcx.def_span(def.did)), + "any use of this value will cause an error", + hir_id, + Some(err.span), + )) } } Ok(mplace) => { From cb2f8d9b027f01fb29487e8852d2ddb1c71ea57b Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Wed, 16 Jun 2021 17:52:33 -0700 Subject: [PATCH 10/19] Make `sum()` and `product()` hyperlinks refer to `Iterator` methods. The previous linking seemed confusing: within "the sum() method on iterators", "sum()" was linked to `Sum::sum`, not `Iterator::sum`, even though the sentence is talking about the latter. I have rewritten the sentence to be, I believe, clearer, as well as changing the link destinations; applying the same change to the `Product` documentation as well as `Sum`. --- library/core/src/iter/traits/accum.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index 0a4210a78e3af..c2e837df5ff2a 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -3,12 +3,11 @@ use crate::num::Wrapping; /// Trait to represent types that can be created by summing up an iterator. /// -/// This trait is used to implement the [`sum()`] method on iterators. Types which -/// implement the trait can be generated by the [`sum()`] method. Like -/// [`FromIterator`] this trait should rarely be called directly and instead -/// interacted with through [`Iterator::sum()`]. +/// This trait is used to implement [`Iterator::sum()`]. Types which implement +/// this trait can be generated by using the [`sum()`] method on an iterator. +/// Like [`FromIterator`], this trait should rarely be called directly. /// -/// [`sum()`]: Sum::sum +/// [`sum()`]: Iterator::sum /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] pub trait Sum: Sized { @@ -21,12 +20,11 @@ pub trait Sum: Sized { /// Trait to represent types that can be created by multiplying elements of an /// iterator. /// -/// This trait is used to implement the [`product()`] method on iterators. Types -/// which implement the trait can be generated by the [`product()`] method. Like -/// [`FromIterator`] this trait should rarely be called directly and instead -/// interacted with through [`Iterator::product()`]. +/// This trait is used to implement [`Iterator::product()`]. Types which implement +/// this trait can be generated by using the [`product()`] method on an iterator. +/// Like [`FromIterator`], this trait should rarely be called directly. /// -/// [`product()`]: Product::product +/// [`product()`]: Iterator::product /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] pub trait Product: Sized { From ce6472987d2cb466345a857cb2efdd06307c5ebf Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 3 Jun 2021 10:28:43 -0700 Subject: [PATCH 11/19] Remove methods under Implementors on trait pages These were hidden by default, and duplicated information already on the page anyhow. Also remove the "Auto-hide trait implementors of a trait" setting, which is not needed anymore. --- src/librustdoc/html/render/mod.rs | 38 +++++++++++++++++------------- src/librustdoc/html/static/main.js | 5 ---- src/test/rustdoc/issue-19055.rs | 20 ---------------- 3 files changed, 21 insertions(+), 42 deletions(-) delete mode 100644 src/test/rustdoc/issue-19055.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0efa014b12748..4f3acfb8e82f7 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -490,7 +490,6 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result"); write!(w, "
"); @@ -1571,21 +1573,23 @@ fn render_impl( } } - if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { - let mut ids = cx.id_map.borrow_mut(); - write!( - w, - "
{}
", - Markdown( - &*dox, - &i.impl_item.links(cx), - &mut ids, - cx.shared.codes, - cx.shared.edition(), - &cx.shared.playground - ) - .into_string() - ); + if !on_trait_page { + if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { + let mut ids = cx.id_map.borrow_mut(); + write!( + w, + "
{}
", + Markdown( + &*dox, + &i.impl_item.links(cx), + &mut ids, + cx.shared.codes, + cx.shared.edition(), + &cx.shared.playground + ) + .into_string() + ); + } } } if !default_impl_items.is_empty() || !impl_items.is_empty() { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index e43a231d7570b..98128878999e4 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -778,7 +778,6 @@ function hideThemeButtonState() { } var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; - var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false"; var hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true"; var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; @@ -796,10 +795,6 @@ function hideThemeButtonState() { setImplementorsTogglesOpen("blanket-implementations-list", false); } - if (!hideImplementors) { - setImplementorsTogglesOpen("implementors-list", true); - } - onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function (e) { if (!hideLargeItemContents && hasClass(e, "type-contents-toggle")) { e.open = true; diff --git a/src/test/rustdoc/issue-19055.rs b/src/test/rustdoc/issue-19055.rs deleted file mode 100644 index dbaf744dc4712..0000000000000 --- a/src/test/rustdoc/issue-19055.rs +++ /dev/null @@ -1,20 +0,0 @@ -// @has issue_19055/trait.Any.html -pub trait Any {} - -impl<'any> Any + 'any { - // @has - '//*[@id="method.is"]' 'fn is' - pub fn is(&self) -> bool { loop {} } - - // @has - '//*[@id="method.downcast_ref"]' 'fn downcast_ref' - pub fn downcast_ref(&self) -> Option<&T> { loop {} } - - // @has - '//*[@id="method.downcast_mut"]' 'fn downcast_mut' - pub fn downcast_mut(&mut self) -> Option<&mut T> { loop {} } -} - -pub trait Foo { - fn foo(&self) {} -} - -// @has - '//*[@id="method.foo"]' 'fn foo' -impl Foo for Any {} From bff4f073c8bc09788c5111ef6f7aa2b74e75dc89 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Tue, 8 Jun 2021 10:39:57 -0700 Subject: [PATCH 12/19] Use render_impl_summary when rendering traits. --- src/librustdoc/html/render/mod.rs | 41 ++++++++++-------------- src/librustdoc/html/render/print_item.rs | 31 +++++++----------- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4f3acfb8e82f7..4ce14e6eb3ce8 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1542,15 +1542,10 @@ fn render_impl( } } if render_mode == RenderMode::Normal { - let on_trait_page = matches!(*parent.kind, clean::ItemKind::TraitItem(_)); - let has_impl_items = !(impl_items.is_empty() && default_impl_items.is_empty()); - let toggled = !on_trait_page && has_impl_items; - let is_implementing_trait = i.inner_impl().trait_.is_some(); + let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); if toggled { close_tags.insert_str(0, "
"); write!(w, "
"); - } - if toggled { write!(w, "") } render_impl_summary( @@ -1573,23 +1568,21 @@ fn render_impl( } } - if !on_trait_page { - if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { - let mut ids = cx.id_map.borrow_mut(); - write!( - w, - "
{}
", - Markdown( - &*dox, - &i.impl_item.links(cx), - &mut ids, - cx.shared.codes, - cx.shared.edition(), - &cx.shared.playground - ) - .into_string() - ); - } + if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { + let mut ids = cx.id_map.borrow_mut(); + write!( + w, + "
{}
", + Markdown( + &*dox, + &i.impl_item.links(cx), + &mut ids, + cx.shared.codes, + cx.shared.edition(), + &cx.shared.playground + ) + .into_string() + ); } } if !default_impl_items.is_empty() || !impl_items.is_empty() { @@ -1601,7 +1594,7 @@ fn render_impl( w.write_str(&close_tags); } -fn render_impl_summary( +pub(crate) fn render_impl_summary( w: &mut Buffer, cx: &Context<'_>, i: &Impl, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 88ec172a18bca..5be16d1ce5006 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -15,11 +15,11 @@ use rustc_span::symbol::{kw, sym, Symbol}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre, - render_impl, render_stability_since_raw, write_srclink, AssocItemLink, Context, + render_impl_summary, render_stability_since_raw, write_srclink, AssocItemLink, Context, }; use crate::clean::{self, GetDefId}; use crate::formats::item_type::ItemType; -use crate::formats::{AssocItemRender, Impl, RenderMode}; +use crate::formats::{AssocItemRender, Impl}; use crate::html::escape::Escape; use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace}; use crate::html::highlight; @@ -691,22 +691,17 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", ""); for implementor in foreign { - let provided_methods = implementor.inner_impl().provided_trait_methods(cx.tcx()); - let assoc_link = - AssocItemLink::GotoSource(implementor.impl_item.def_id, &provided_methods); - render_impl( + let outer_version = implementor.impl_item.stable_since(cx.tcx()); + let outer_const_version = implementor.impl_item.const_stable_since(cx.tcx()); + render_impl_summary( w, cx, &implementor, - it, - assoc_link, - RenderMode::Normal, - implementor.impl_item.stable_since(cx.tcx()).as_deref(), - implementor.impl_item.const_stable_since(cx.tcx()).as_deref(), + outer_version.as_deref(), + outer_const_version.as_deref(), false, None, true, - false, &[], ); } @@ -1320,19 +1315,17 @@ fn render_implementor( } => implementor_dups[&path.last()].1, _ => false, }; - render_impl( + let outer_version = trait_.stable_since(cx.tcx()); + let outer_const_version = trait_.const_stable_since(cx.tcx()); + render_impl_summary( w, cx, implementor, - trait_, - AssocItemLink::Anchor(None), - RenderMode::Normal, - trait_.stable_since(cx.tcx()).as_deref(), - trait_.const_stable_since(cx.tcx()).as_deref(), + outer_version.as_deref(), + outer_const_version.as_deref(), false, Some(use_absolute), false, - false, aliases, ); } From 910c7fa7673b80ead337c5d37259c9ff4dcf355c Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Fri, 11 Jun 2021 22:16:44 -0700 Subject: [PATCH 13/19] Add doc(hidden) to all __iterator_get_unchecked This method on the Iterator trait is doc(hidden), and about half of implementations were doc(hidden). This adds the attribute to the remaining implementations. --- library/alloc/src/collections/vec_deque/into_iter.rs | 1 + library/alloc/src/collections/vec_deque/iter.rs | 1 + library/alloc/src/collections/vec_deque/iter_mut.rs | 1 + library/alloc/src/vec/into_iter.rs | 1 + library/core/src/array/iter.rs | 1 + library/core/src/iter/adapters/cloned.rs | 1 + library/core/src/iter/adapters/copied.rs | 1 + library/core/src/iter/adapters/enumerate.rs | 1 + library/core/src/iter/adapters/fuse.rs | 1 + library/core/src/iter/adapters/map.rs | 1 + library/core/src/iter/adapters/zip.rs | 1 + library/core/src/iter/range.rs | 1 + library/core/src/slice/iter.rs | 2 ++ library/core/src/str/iter.rs | 1 + 14 files changed, 15 insertions(+) diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 1c635dd4f27fa..46a769a722a8b 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -38,6 +38,7 @@ impl Iterator for IntoIter { } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index f3eb228c9e380..ae1b03c9a4d22 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -103,6 +103,7 @@ impl<'a, T> Iterator for Iter<'a, T> { } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 9493676e66bc8..df30c38652f72 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -89,6 +89,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 8da4d995ba5c6..7a08f4c6cbaac 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -163,6 +163,7 @@ impl Iterator for IntoIter { self.len() } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index aedbeab661058..931ea77eca4dc 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -132,6 +132,7 @@ impl Iterator for IntoIter { } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 7efc155175c34..5cd65a9415fd7 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -58,6 +58,7 @@ where self.it.map(T::clone).fold(init, f) } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index def2408927589..07a3b5d245659 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -74,6 +74,7 @@ where self.it.count() } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 91722a4b62a2e..8b27bdc60a705 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -111,6 +111,7 @@ where } #[rustc_inherit_overflow_checks] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> ::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index aff48b1b220c4..0c21df4f12c60 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -114,6 +114,7 @@ where } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 0bf9f4b0327e9..dc86eccfcb82f 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -122,6 +122,7 @@ where self.iter.fold(init, map_fold(self.f, g)) } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index c95324c80ba61..8a6955060e82f 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -88,6 +88,7 @@ where } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index de5d77e96ee56..4a86d6a100abe 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -667,6 +667,7 @@ impl Iterator for ops::Range
{ } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccess, diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 1ee662c6c8e3c..b2cb2f12bbfeb 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -2148,6 +2148,7 @@ impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> { self.iter.last() } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] { // SAFETY: The safety guarantees of `__iterator_get_unchecked` are // transferred to the caller. @@ -2260,6 +2261,7 @@ impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> { self.iter.last() } + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a mut [T; N] { // SAFETY: The safety guarantees of `__iterator_get_unchecked` are transferred to // the caller. diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 6ec6b70b57119..a5774764573be 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -295,6 +295,7 @@ impl Iterator for Bytes<'_> { } #[inline] + #[doc(hidden)] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 { // SAFETY: the caller must uphold the safety contract // for `Iterator::__iterator_get_unchecked`. From 593d6d1cb15c55c88319470dabb40126c7b7f1e2 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Tue, 8 Jun 2021 11:04:53 -0700 Subject: [PATCH 14/19] Make portability part of the summary. That means it will be visible under "Implementors" on trait pages, and under "Implementations" on struct/enum pages, even when all methods are collapsed. Switch to a float layout for rightside elements. --- src/librustdoc/html/render/mod.rs | 17 ++++++++++++----- src/librustdoc/html/render/print_item.rs | 13 +++++++++---- src/librustdoc/html/static/rustdoc.css | 12 +++--------- src/test/rustdoc/src-links-auto-impls.rs | 6 +++--- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4ce14e6eb3ce8..df8cc94d3ee13 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1552,6 +1552,7 @@ fn render_impl( w, cx, i, + parent, outer_version, outer_const_version, show_def_docs, @@ -1562,11 +1563,6 @@ fn render_impl( if toggled { write!(w, "
") } - if trait_.is_some() { - if let Some(portability) = portability(&i.impl_item, Some(parent)) { - write!(w, "
{}
", portability); - } - } if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { let mut ids = cx.id_map.borrow_mut(); @@ -1598,6 +1594,7 @@ pub(crate) fn render_impl_summary( w: &mut Buffer, cx: &Context<'_>, i: &Impl, + parent: &clean::Item, outer_version: Option<&str>, outer_const_version: Option<&str>, show_def_docs: bool, @@ -1652,6 +1649,7 @@ pub(crate) fn render_impl_summary( ); } write!(w, "
", id); + write!(w, "
"); render_stability_since_raw( w, i.impl_item.stable_since(tcx).as_deref(), @@ -1660,6 +1658,15 @@ pub(crate) fn render_impl_summary( outer_const_version, ); write_srclink(cx, &i.impl_item, w); + w.write_str("
"); // end of "rightside" + + let is_trait = i.inner_impl().trait_.is_some(); + if is_trait { + if let Some(portability) = portability(&i.impl_item, Some(parent)) { + write!(w, "
{}
", portability); + } + } + w.write_str(""); } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5be16d1ce5006..8ad0a80344176 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -585,11 +585,14 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra if toggled { write!(w, "
"); } - write!(w, "
", id); - render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx); - w.write_str(""); + write!(w, "
", id); + write!(w, "
"); render_stability_since(w, m, t, cx.tcx()); write_srclink(cx, m, w); + write!(w, "
"); + write!(w, ""); + render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx); + w.write_str(""); w.write_str("
"); if toggled { write!(w, "
"); @@ -697,6 +700,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w, cx, &implementor, + it, outer_version.as_deref(), outer_const_version.as_deref(), false, @@ -1305,7 +1309,7 @@ fn render_implementor( implementor_dups: &FxHashMap, aliases: &[String], ) { - // If there's already another implementor that has the same abbridged name, use the + // If there's already another implementor that has the same abridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { clean::ResolvedPath { ref path, is_generic: false, .. } @@ -1321,6 +1325,7 @@ fn render_implementor( w, cx, implementor, + trait_, outer_version.as_deref(), outer_const_version.as_deref(), false, diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 7535145caa5c8..e084ee9ca7e34 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -581,7 +581,6 @@ nav.sub { .content .item-info { position: relative; margin-left: 33px; - margin-top: -13px; } .sub-variant > div > .item-info { @@ -852,12 +851,12 @@ body.blur > :not(#help) { } .stab { - display: table; border-width: 1px; border-style: solid; padding: 3px; margin-bottom: 5px; font-size: 90%; + font-weight: normal; } .stab p { display: inline; @@ -906,26 +905,22 @@ body.blur > :not(#help) { } .impl-items .since, .impl .since, .methods .since { - flex-grow: 0; padding-left: 12px; padding-right: 2px; position: initial; } .impl-items .srclink, .impl .srclink, .methods .srclink { - flex-grow: 0; /* Override header settings otherwise it's too bold */ font-size: 17px; font-weight: normal; } -.impl-items code, .impl code, .methods code { - flex-grow: 1; +.rightside { + float: right; } .has-srclink { - display: flex; - flex-basis: 100%; font-size: 16px; margin-bottom: 12px; /* Push the src link out to the right edge consistently */ @@ -986,7 +981,6 @@ a.test-arrow:hover{ } .since + .srclink { - display: table-cell; padding-left: 10px; } diff --git a/src/test/rustdoc/src-links-auto-impls.rs b/src/test/rustdoc/src-links-auto-impls.rs index 6f609e080d3dd..1952f723465d6 100644 --- a/src/test/rustdoc/src-links-auto-impls.rs +++ b/src/test/rustdoc/src-links-auto-impls.rs @@ -2,11 +2,11 @@ // @has foo/struct.Unsized.html // @has - '//div[@id="impl-Sized"]/code' 'impl !Sized for Unsized' -// @!has - '//div[@id="impl-Sized"]/a[@class="srclink"]' '[src]' +// @!has - '//div[@id="impl-Sized"]//a[@class="srclink"]' '[src]' // @has - '//div[@id="impl-Sync"]/code' 'impl Sync for Unsized' -// @!has - '//div[@id="impl-Sync"]/a[@class="srclink"]' '[src]' +// @!has - '//div[@id="impl-Sync"]//a[@class="srclink"]' '[src]' // @has - '//div[@id="impl-Any"]/code' 'impl Any for T' -// @has - '//div[@id="impl-Any"]/a[@class="srclink"]' '[src]' +// @has - '//div[@id="impl-Any"]//a[@class="srclink"]' '[src]' pub struct Unsized { data: [u8], } From 5de1391b88007a1d4f7b1517657a86aae352af1e Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 12 Jun 2021 00:25:26 -0700 Subject: [PATCH 15/19] Factor out render_rightside This covers rendering of stability_since and the srclink across methods and trait implementations, so their DOM representation is consistent. --- src/librustdoc/html/render/mod.rs | 73 ++++++++----------- src/librustdoc/html/static/rustdoc.css | 8 -- src/test/rustdoc-gui/hash-item-expansion.goml | 3 - 3 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index df8cc94d3ee13..a210d0c843cc6 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1294,7 +1294,6 @@ fn render_impl( ) { let item_type = item.type_(); let name = item.name.as_ref().unwrap(); - let tcx = cx.tcx(); let render_method_item = match render_mode { RenderMode::Normal => true, @@ -1363,6 +1362,7 @@ fn render_impl( "
", id, item_type, in_trait_class, ); + render_rightside(w, cx, item, outer_version, outer_const_version); w.write_str(""); render_assoc_item( w, @@ -1372,15 +1372,7 @@ fn render_impl( cx, ); w.write_str(""); - render_stability_since_raw( - w, - item.stable_since(tcx).as_deref(), - item.const_stable_since(tcx).as_deref(), - outer_version, - outer_const_version, - ); write!(w, "", id); - write_srclink(cx, item, w); w.write_str("
"); } } @@ -1413,6 +1405,7 @@ fn render_impl( "
", id, item_type, in_trait_class ); + render_rightside(w, cx, item, outer_version, outer_const_version); assoc_const( w, item, @@ -1423,15 +1416,7 @@ fn render_impl( cx, ); w.write_str(""); - render_stability_since_raw( - w, - item.stable_since(tcx).as_deref(), - item.const_stable_since(tcx).as_deref(), - outer_version, - outer_const_version, - ); write!(w, "", id); - write_srclink(cx, item, w); w.write_str("
"); } clean::AssocTypeItem(ref bounds, ref default) => { @@ -1590,6 +1575,28 @@ fn render_impl( w.write_str(&close_tags); } +fn render_rightside( + w: &mut Buffer, + cx: &Context<'_>, + item: &clean::Item, + outer_version: Option<&str>, + outer_const_version: Option<&str>, +) { + let tcx = cx.tcx(); + + write!(w, "
"); + render_stability_since_raw( + w, + item.stable_since(tcx).as_deref(), + item.const_stable_since(tcx).as_deref(), + outer_version, + outer_const_version, + ); + + write_srclink(cx, item, w); + w.write_str("
"); +} + pub(crate) fn render_impl_summary( w: &mut Buffer, cx: &Context<'_>, @@ -1604,7 +1611,6 @@ pub(crate) fn render_impl_summary( // in documentation pages for trait with automatic implementations like "Send" and "Sync". aliases: &[String], ) { - let tcx = cx.tcx(); let id = cx.derive_id(match i.inner_impl().trait_ { Some(ref t) => { if is_on_foreign_type { @@ -1620,13 +1626,11 @@ pub(crate) fn render_impl_summary( } else { format!(" data-aliases=\"{}\"", aliases.join(",")) }; + write!(w, "
", id, aliases); + render_rightside(w, cx, &i.impl_item, outer_version, outer_const_version); + write!(w, ""); + if let Some(use_absolute) = use_absolute { - write!( - w, - "
\ - ", - id, aliases - ); write!(w, "{}", i.inner_impl().print(use_absolute, cx)); if show_def_docs { for it in &i.inner_impl().items { @@ -1637,28 +1641,11 @@ pub(crate) fn render_impl_summary( } } } - w.write_str(""); } else { - write!( - w, - "
\ - {}", - id, - aliases, - i.inner_impl().print(false, cx) - ); + write!(w, "{}", i.inner_impl().print(false, cx)); } + write!(w, ""); write!(w, "", id); - write!(w, "
"); - render_stability_since_raw( - w, - i.impl_item.stable_since(tcx).as_deref(), - i.impl_item.const_stable_since(tcx).as_deref(), - outer_version, - outer_const_version, - ); - write_srclink(cx, &i.impl_item, w); - w.write_str("
"); // end of "rightside" let is_trait = i.inner_impl().trait_.is_some(); if is_trait { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index e084ee9ca7e34..e6646586c4125 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -899,9 +899,6 @@ body.blur > :not(#help) { .since { font-weight: normal; font-size: initial; - position: absolute; - right: 0; - top: 0; } .impl-items .since, .impl .since, .methods .since { @@ -1606,11 +1603,6 @@ details.undocumented[open] > summary::before { margin-left: 0; } - .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant, - .impl-items > .associatedtype { - display: flex; - } - .anchor { display: none !important; } diff --git a/src/test/rustdoc-gui/hash-item-expansion.goml b/src/test/rustdoc-gui/hash-item-expansion.goml index 1248d11200e6c..d5f9d4fc58b8c 100644 --- a/src/test/rustdoc-gui/hash-item-expansion.goml +++ b/src/test/rustdoc-gui/hash-item-expansion.goml @@ -2,9 +2,6 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.borrow // In the blanket implementations list, "Borrow" is the second one, hence the ":nth(2)". assert: ("#blanket-implementations-list > details:nth-child(2)", "open", "") -// Please note the "\" below is needed because otherwise ".borrow" would be interpreted as -// a class selector. -assert: ("#method\.borrow", {"display": "flex"}) // We first check that the impl block is open by default. assert: ("#implementations + details", "open", "") // We collapse it. From c4fa6d58276c5a4a76c36fca6d4689db415c2817 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 16 Jun 2021 22:47:46 -0700 Subject: [PATCH 16/19] Move anchor earlier in the DOM for easier layout --- src/librustdoc/html/render/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a210d0c843cc6..521464b7b920c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1363,6 +1363,7 @@ fn render_impl( id, item_type, in_trait_class, ); render_rightside(w, cx, item, outer_version, outer_const_version); + write!(w, "", id); w.write_str(""); render_assoc_item( w, @@ -1372,7 +1373,6 @@ fn render_impl( cx, ); w.write_str(""); - write!(w, "", id); w.write_str("
"); } } @@ -1381,9 +1381,11 @@ fn render_impl( let id = cx.derive_id(source_id.clone()); write!( w, - "
", + "
", id, item_type, in_trait_class ); + write!(w, "", id); + w.write_str(""); assoc_type( w, item, @@ -1394,7 +1396,6 @@ fn render_impl( cx, ); w.write_str(""); - write!(w, "", id); w.write_str("
"); } clean::AssocConstItem(ref ty, ref default) => { @@ -1402,10 +1403,12 @@ fn render_impl( let id = cx.derive_id(source_id.clone()); write!( w, - "
", + "
", id, item_type, in_trait_class ); render_rightside(w, cx, item, outer_version, outer_const_version); + write!(w, "", id); + w.write_str(""); assoc_const( w, item, @@ -1416,13 +1419,14 @@ fn render_impl( cx, ); w.write_str(""); - write!(w, "", id); w.write_str("
"); } clean::AssocTypeItem(ref bounds, ref default) => { let source_id = format!("{}.{}", item_type, name); let id = cx.derive_id(source_id.clone()); - write!(w, "
", id, item_type, in_trait_class,); + write!(w, "
", id, item_type, in_trait_class,); + write!(w, "", id); + w.write_str(""); assoc_type( w, item, @@ -1433,7 +1437,6 @@ fn render_impl( cx, ); w.write_str(""); - write!(w, "", id); w.write_str("
"); } clean::StrippedItem(..) => return, @@ -1628,6 +1631,7 @@ pub(crate) fn render_impl_summary( }; write!(w, "
", id, aliases); render_rightside(w, cx, &i.impl_item, outer_version, outer_const_version); + write!(w, "", id); write!(w, ""); if let Some(use_absolute) = use_absolute { @@ -1645,7 +1649,6 @@ pub(crate) fn render_impl_summary( write!(w, "{}", i.inner_impl().print(false, cx)); } write!(w, ""); - write!(w, "", id); let is_trait = i.inner_impl().trait_.is_some(); if is_trait { From 2ac5c1721a523c77831a2efbbadb21921b8c8c96 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 16 Jun 2021 22:48:23 -0700 Subject: [PATCH 17/19] Fix target highlighting in rustdoc. Also factor out outer_version and const_outer_version into render_rightside. --- src/librustdoc/html/render/mod.rs | 47 ++++++++----------- src/librustdoc/html/render/print_item.rs | 10 +--- src/librustdoc/html/static/rustdoc.css | 4 ++ src/librustdoc/html/static/themes/ayu.css | 5 +- src/librustdoc/html/static/themes/dark.css | 5 +- src/librustdoc/html/static/themes/light.css | 5 +- src/test/rustdoc/ensure-src-link.rs | 2 +- .../trait-impl-items-links-and-anchors.rs | 8 ---- 8 files changed, 38 insertions(+), 48 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 521464b7b920c..499f33f14f562 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -723,6 +723,8 @@ fn short_item_info( extra_info } +// Render the list of items inside one of the sections "Trait Implementations", +// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages). fn render_impls( cx: &Context<'_>, w: &mut Buffer, @@ -745,8 +747,6 @@ fn render_impls( containing_item, assoc_link, RenderMode::Normal, - containing_item.stable_since(tcx).as_deref(), - containing_item.const_stable_since(tcx).as_deref(), true, None, false, @@ -1024,7 +1024,6 @@ fn render_assoc_items( Some(v) => v, None => return, }; - let tcx = cx.tcx(); let cache = cx.cache(); let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { @@ -1058,8 +1057,6 @@ fn render_assoc_items( containing_item, AssocItemLink::Anchor(None), render_mode, - containing_item.stable_since(tcx).as_deref(), - containing_item.const_stable_since(tcx).as_deref(), true, None, false, @@ -1260,8 +1257,6 @@ fn render_impl( parent: &clean::Item, link: AssocItemLink<'_>, render_mode: RenderMode, - outer_version: Option<&str>, - outer_const_version: Option<&str>, show_def_docs: bool, use_absolute: Option, is_on_foreign_type: bool, @@ -1278,17 +1273,18 @@ fn render_impl( // For trait implementations, the `interesting` output contains all methods that have doc // comments, and the `boring` output contains all methods that do not. The distinction is // used to allow hiding the boring methods. + // `containing_item` is used for rendering stability info. If the parent is a trait impl, + // `containing_item` will the grandparent, since trait impls can't have stability attached. fn doc_impl_item( boring: &mut Buffer, interesting: &mut Buffer, cx: &Context<'_>, item: &clean::Item, parent: &clean::Item, + containing_item: &clean::Item, link: AssocItemLink<'_>, render_mode: RenderMode, is_default_item: bool, - outer_version: Option<&str>, - outer_const_version: Option<&str>, trait_: Option<&clean::Trait>, show_def_docs: bool, ) { @@ -1362,7 +1358,7 @@ fn render_impl( "
", id, item_type, in_trait_class, ); - render_rightside(w, cx, item, outer_version, outer_const_version); + render_rightside(w, cx, item, containing_item); write!(w, "", id); w.write_str(""); render_assoc_item( @@ -1406,7 +1402,7 @@ fn render_impl( "
", id, item_type, in_trait_class ); - render_rightside(w, cx, item, outer_version, outer_const_version); + render_rightside(w, cx, item, containing_item); write!(w, "", id); w.write_str(""); assoc_const( @@ -1461,11 +1457,10 @@ fn render_impl( cx, trait_item, if trait_.is_some() { &i.impl_item } else { parent }, + parent, link, render_mode, false, - outer_version, - outer_const_version, trait_.map(|t| &t.trait_), show_def_docs, ); @@ -1478,9 +1473,8 @@ fn render_impl( t: &clean::Trait, i: &clean::Impl, parent: &clean::Item, + containing_item: &clean::Item, render_mode: RenderMode, - outer_version: Option<&str>, - outer_const_version: Option<&str>, show_def_docs: bool, ) { for trait_item in &t.items { @@ -1498,11 +1492,10 @@ fn render_impl( cx, trait_item, parent, + containing_item, assoc_link, render_mode, true, - outer_version, - outer_const_version, Some(t), show_def_docs, ); @@ -1522,9 +1515,8 @@ fn render_impl( &t.trait_, &i.inner_impl(), &i.impl_item, + parent, render_mode, - outer_version, - outer_const_version, show_def_docs, ); } @@ -1541,8 +1533,7 @@ fn render_impl( cx, i, parent, - outer_version, - outer_const_version, + parent, show_def_docs, use_absolute, is_on_foreign_type, @@ -1578,12 +1569,13 @@ fn render_impl( w.write_str(&close_tags); } +// Render the items that appear on the right side of methods, impls, and +// associated types. For example "1.0.0 (const: 1.39.0) [src]". fn render_rightside( w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, - outer_version: Option<&str>, - outer_const_version: Option<&str>, + containing_item: &clean::Item, ) { let tcx = cx.tcx(); @@ -1592,8 +1584,8 @@ fn render_rightside( w, item.stable_since(tcx).as_deref(), item.const_stable_since(tcx).as_deref(), - outer_version, - outer_const_version, + containing_item.stable_since(tcx).as_deref(), + containing_item.const_stable_since(tcx).as_deref(), ); write_srclink(cx, item, w); @@ -1605,8 +1597,7 @@ pub(crate) fn render_impl_summary( cx: &Context<'_>, i: &Impl, parent: &clean::Item, - outer_version: Option<&str>, - outer_const_version: Option<&str>, + containing_item: &clean::Item, show_def_docs: bool, use_absolute: Option, is_on_foreign_type: bool, @@ -1630,7 +1621,7 @@ pub(crate) fn render_impl_summary( format!(" data-aliases=\"{}\"", aliases.join(",")) }; write!(w, "
", id, aliases); - render_rightside(w, cx, &i.impl_item, outer_version, outer_const_version); + render_rightside(w, cx, &i.impl_item, containing_item); write!(w, "", id); write!(w, ""); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 8ad0a80344176..6eff452a13bdd 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -694,15 +694,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", ""); for implementor in foreign { - let outer_version = implementor.impl_item.stable_since(cx.tcx()); - let outer_const_version = implementor.impl_item.const_stable_since(cx.tcx()); render_impl_summary( w, cx, &implementor, it, - outer_version.as_deref(), - outer_const_version.as_deref(), + &implementor.impl_item, false, None, true, @@ -1319,15 +1316,12 @@ fn render_implementor( } => implementor_dups[&path.last()].1, _ => false, }; - let outer_version = trait_.stable_since(cx.tcx()); - let outer_const_version = trait_.const_stable_since(cx.tcx()); render_impl_summary( w, cx, implementor, trait_, - outer_version.as_deref(), - outer_const_version.as_deref(), + trait_, false, Some(use_absolute), false, diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index e6646586c4125..9a59ee528a0c9 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1037,6 +1037,10 @@ a.test-arrow:hover{ opacity: 1; } +:target { + padding-right: 3px; +} + .information { position: absolute; left: -25px; diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index d220d8708a123..171d06c0a3667 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -334,8 +334,11 @@ a.test-arrow:hover { color: #999; } -:target > code, :target > .in-band { +:target, :target * { background: rgba(255, 236, 164, 0.06); +} + +:target { border-right: 3px solid rgba(255, 180, 76, 0.85); } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 6385a763f2ef7..d9ea28058ad99 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -282,8 +282,11 @@ a.test-arrow:hover{ color: #999; } -:target > code, :target > .in-band { +:target, :target * { background-color: #494a3d; +} + +:target { border-right: 3px solid #bb7410; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index c19d5bfc317f7..a2dfb89820b01 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -275,8 +275,11 @@ a.test-arrow:hover{ color: #999; } -:target > code, :target > .in-band { +:target, :target * { background: #FDFFD3; +} + +:target { border-right: 3px solid #ffb44c; } diff --git a/src/test/rustdoc/ensure-src-link.rs b/src/test/rustdoc/ensure-src-link.rs index 4b6270b26da27..6189acb72542a 100644 --- a/src/test/rustdoc/ensure-src-link.rs +++ b/src/test/rustdoc/ensure-src-link.rs @@ -2,5 +2,5 @@ // This test ensures that the [src] link is present on traits items. -// @has foo/trait.Iterator.html '//div[@id="method.zip"]/a[@class="srclink"]' "[src]" +// @has foo/trait.Iterator.html '//div[@id="method.zip"]//a[@class="srclink"]' "[src]" pub use std::iter::Iterator; diff --git a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs index 5b7c04c0d4445..ddbe93febdc25 100644 --- a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs +++ b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs @@ -38,23 +38,15 @@ impl MyTrait for Vec { } impl MyTrait for MyStruct { - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3 // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedtype.Assoc"]//a[@class="type"]/@href' trait.MyTrait.html#associatedtype.Assoc // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc type Assoc = bool; - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3 // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' trait.MyTrait.html#associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE const VALUE: u32 = 20; - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2 // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="method.trait_function"]//a[@class="fnname"]/@href' trait.MyTrait.html#tymethod.trait_function // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function fn trait_function(&self) {} - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3 // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="method.defaulted_override"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted_override // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//div[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override fn defaulted_override(&self) {} From bf81e139af3605144121d736c0314d103466507c Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 16 Jun 2021 14:50:25 -0700 Subject: [PATCH 18/19] Restore details for Impls on Foreign Types These were previously removed along with the details in the "Implementors" section of trait pages. But for "Implementations on Foreign Types," we need to include the details because they will not be documented anywhere else. --- src/librustdoc/html/render/print_item.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6eff452a13bdd..8fd5353891221 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -15,11 +15,12 @@ use rustc_span::symbol::{kw, sym, Symbol}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre, - render_impl_summary, render_stability_since_raw, write_srclink, AssocItemLink, Context, + render_impl, render_impl_summary, render_stability_since_raw, write_srclink, AssocItemLink, + Context, }; use crate::clean::{self, GetDefId}; use crate::formats::item_type::ItemType; -use crate::formats::{AssocItemRender, Impl}; +use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace}; use crate::html::highlight; @@ -694,15 +695,20 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", ""); for implementor in foreign { - render_impl_summary( + let provided_methods = implementor.inner_impl().provided_trait_methods(cx.tcx()); + let assoc_link = + AssocItemLink::GotoSource(implementor.impl_item.def_id, &provided_methods); + render_impl( w, cx, &implementor, it, - &implementor.impl_item, + assoc_link, + RenderMode::Normal, false, None, true, + false, &[], ); } From 5e7a8c6eb12e1fb84cf2538cf87db32c54b938a2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Jun 2021 12:13:06 +0200 Subject: [PATCH 19/19] Fix typos in code examples. --- library/std/src/io/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 7187ec71bc9e3..f57529767a91a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1059,7 +1059,7 @@ impl<'a> IoSliceMut<'a> { /// let mut data = [1; 8]; /// let mut buf = IoSliceMut::new(&mut data); /// - /// // Mark 10 bytes as read. + /// // Mark 3 bytes as read. /// buf.advance(3); /// assert_eq!(buf.deref(), [1; 5].as_ref()); /// ``` @@ -1193,7 +1193,7 @@ impl<'a> IoSlice<'a> { /// let mut data = [1; 8]; /// let mut buf = IoSlice::new(&mut data); /// - /// // Mark 10 bytes as read. + /// // Mark 3 bytes as read. /// buf.advance(3); /// assert_eq!(buf.deref(), [1; 5].as_ref()); /// ```