From fe2880ac43c71e0fffbd6a62fc10700d01231449 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Tue, 15 Dec 2020 12:59:31 +0000 Subject: [PATCH 01/23] stabilise --include-ignored --- library/test/src/cli.rs | 2 +- library/test/src/tests.rs | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs index 97a659f22d757..02c529252e029 100644 --- a/library/test/src/cli.rs +++ b/library/test/src/cli.rs @@ -230,9 +230,9 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes { // Unstable flags let force_run_in_process = unstable_optflag!(matches, allow_unstable, "force-run-in-process"); let exclude_should_panic = unstable_optflag!(matches, allow_unstable, "exclude-should-panic"); - let include_ignored = unstable_optflag!(matches, allow_unstable, "include-ignored"); let time_options = get_time_options(&matches, allow_unstable)?; + let include_ignored = matches.opt_present("include-ignored"); let quiet = matches.opt_present("quiet"); let exact = matches.opt_present("exact"); let list = matches.opt_present("list"); diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 85a0705f69c0a..1e0e61b4ef5c7 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -382,12 +382,7 @@ fn parse_show_output_flag() { #[test] fn parse_include_ignored_flag() { - let args = vec![ - "progname".to_string(), - "filter".to_string(), - "-Zunstable-options".to_string(), - "--include-ignored".to_string(), - ]; + let args = vec!["progname".to_string(), "filter".to_string(), "--include-ignored".to_string()]; let opts = parse_opts(&args).unwrap().unwrap(); assert_eq!(opts.run_ignored, RunIgnored::Yes); } From a55039df84f53a4a3060e2a7ae84dee1dc9006ef Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Sun, 22 Nov 2020 01:04:02 +0100 Subject: [PATCH 02/23] Stabilize Arc::{incr,decr}_strong_count --- library/alloc/src/sync.rs | 18 +++++++----------- library/alloc/src/task.rs | 4 ++-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9d478a302e96c..1ff30ca610dbb 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -870,15 +870,13 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(arc_mutate_strong_count)] - /// /// use std::sync::Arc; /// /// let five = Arc::new(5); /// /// unsafe { /// let ptr = Arc::into_raw(five); - /// Arc::incr_strong_count(ptr); + /// Arc::increment_strong_count(ptr); /// /// // This assertion is deterministic because we haven't shared /// // the `Arc` between threads. @@ -887,8 +885,8 @@ impl Arc { /// } /// ``` #[inline] - #[unstable(feature = "arc_mutate_strong_count", issue = "71983")] - pub unsafe fn incr_strong_count(ptr: *const T) { + #[stable(feature = "arc_mutate_strong_count", since = "1.50.0")] + pub unsafe fn increment_strong_count(ptr: *const T) { // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop let arc = unsafe { mem::ManuallyDrop::new(Arc::::from_raw(ptr)) }; // Now increase refcount, but don't drop new refcount either @@ -909,27 +907,25 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(arc_mutate_strong_count)] - /// /// use std::sync::Arc; /// /// let five = Arc::new(5); /// /// unsafe { /// let ptr = Arc::into_raw(five); - /// Arc::incr_strong_count(ptr); + /// Arc::increment_strong_count(ptr); /// /// // Those assertions are deterministic because we haven't shared /// // the `Arc` between threads. /// let five = Arc::from_raw(ptr); /// assert_eq!(2, Arc::strong_count(&five)); - /// Arc::decr_strong_count(ptr); + /// Arc::decrement_strong_count(ptr); /// assert_eq!(1, Arc::strong_count(&five)); /// } /// ``` #[inline] - #[unstable(feature = "arc_mutate_strong_count", issue = "71983")] - pub unsafe fn decr_strong_count(ptr: *const T) { + #[stable(feature = "arc_mutate_strong_count", since = "1.50.0")] + pub unsafe fn decrement_strong_count(ptr: *const T) { unsafe { mem::drop(Arc::from_raw(ptr)) }; } diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index fcab3fd0badce..4ee79dae3f1a3 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -60,7 +60,7 @@ impl From> for RawWaker { fn raw_waker(waker: Arc) -> RawWaker { // Increment the reference count of the arc to clone it. unsafe fn clone_waker(waker: *const ()) -> RawWaker { - unsafe { Arc::incr_strong_count(waker as *const W) }; + unsafe { Arc::increment_strong_count(waker as *const W) }; RawWaker::new( waker as *const (), &RawWakerVTable::new(clone_waker::, wake::, wake_by_ref::, drop_waker::), @@ -81,7 +81,7 @@ fn raw_waker(waker: Arc) -> RawWaker { // Decrement the reference count of the Arc on drop unsafe fn drop_waker(waker: *const ()) { - unsafe { Arc::decr_strong_count(waker as *const W) }; + unsafe { Arc::decrement_strong_count(waker as *const W) }; } RawWaker::new( From 05af4213b593de5e6b73d8dda0eedf54b4568266 Mon Sep 17 00:00:00 2001 From: Yaulendil Date: Mon, 21 Dec 2020 18:42:29 -0500 Subject: [PATCH 03/23] Implement `AsMut` for `str` --- library/core/src/convert/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 3f7110b34cc67..d8c2e0b2a3bfe 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -623,6 +623,14 @@ impl AsRef for str { } } +#[stable(feature = "as_mut_str_for_str", since = "1.50.0")] +impl AsMut for str { + #[inline] + fn as_mut(&mut self) -> &mut str { + self + } +} + //////////////////////////////////////////////////////////////////////////////// // THE NO-ERROR ERROR TYPE //////////////////////////////////////////////////////////////////////////////// From 61c49d4042af6d392784925cc53afdc830740cd4 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 29 Dec 2020 09:16:46 +0100 Subject: [PATCH 04/23] Stabilize by-value `[T; N]` iterator `core::array::IntoIter` Tracking issue: https://github.com/rust-lang/rust/issues/65798 This is unblocked now that `min_const_generics` has been stabilized in https://github.com/rust-lang/rust/pull/79135. This PR does *not* include the corresponding `IntoIterator` impl, which is https://github.com/rust-lang/rust/pull/65819. Instead, an iterator can be constructed through the `new` method. `new` would become unnecessary when `IntoIterator` is implemented and might be deprecated then, although it will stay stable. --- compiler/rustc_arena/src/lib.rs | 2 -- compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_trait_selection/src/lib.rs | 1 - compiler/rustc_typeck/src/lib.rs | 1 - library/alloc/src/lib.rs | 1 - library/core/src/array/iter.rs | 15 ++++++++------- library/core/src/array/mod.rs | 2 +- library/core/tests/lib.rs | 1 - .../array-impls/into-iter-impls-length-32.rs | 1 - .../array-impls/into-iter-impls-length-33.rs | 1 - 11 files changed, 9 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a0493056b816b..6f8db824efa4e 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -11,11 +11,9 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(no_crate_inject, attr(deny(warnings))) )] -#![feature(array_value_iter_slice)] #![feature(dropck_eyepatch)] #![feature(new_uninit)] #![feature(maybe_uninit_slice)] -#![feature(array_value_iter)] #![cfg_attr(bootstrap, feature(min_const_generics))] #![feature(min_specialization)] #![cfg_attr(test, feature(test))] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2e1b5a74a7b7e..a02135af8d28e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -30,7 +30,6 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. -#![feature(array_value_iter)] #![feature(crate_visibility_modifier)] #![feature(or_patterns)] #![recursion_limit = "256"] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 9d931b3a9e1e5..c69a9b063aeca 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -2,7 +2,6 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html -#![feature(array_value_iter)] #![feature(crate_visibility_modifier)] #![feature(const_fn)] // For the unsizing cast on `&[]` #![feature(const_panic)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 42509cd897582..e1f8d59991f21 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,7 +11,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(array_value_iter)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(drain_filter)] diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index dde4a62ffbf3d..dc7f015e77ced 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -56,7 +56,6 @@ This API is completely unstable and subject to change. */ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(array_value_iter)] #![feature(bool_to_option)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 3ac34c9ae28af..10eaa31c9e4fa 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -79,7 +79,6 @@ #![feature(allocator_api)] #![feature(array_chunks)] #![feature(array_methods)] -#![feature(array_value_iter)] #![feature(array_windows)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 706f865b4d14f..0fd8815570bd7 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -11,7 +11,7 @@ use crate::{ /// A by-value [array] iterator. /// /// [array]: ../../std/primitive.array.html -#[unstable(feature = "array_value_iter", issue = "65798")] +#[stable(feature = "array_value_iter", since = "1.51.0")] pub struct IntoIter { /// This is the array we are iterating over. /// @@ -38,10 +38,11 @@ pub struct IntoIter { impl IntoIter { /// Creates a new iterator over the given `array`. /// - /// *Note*: this method might never get stabilized and/or removed in the - /// future as there will likely be another, preferred way of obtaining this - /// iterator (either via `IntoIterator` for arrays or via another way). - #[unstable(feature = "array_value_iter", issue = "65798")] + /// *Note*: this method might be deprecated in the future, + /// after [`IntoIterator` is implemented for arrays][array-into-iter]. + /// + /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819 + #[stable(feature = "array_value_iter", since = "1.51.0")] pub fn new(array: [T; N]) -> Self { // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit` // promise: @@ -69,7 +70,7 @@ impl IntoIter { /// Returns an immutable slice of all elements that have not been yielded /// yet. - #[unstable(feature = "array_value_iter_slice", issue = "65798")] + #[stable(feature = "array_value_iter", since = "1.51.0")] pub fn as_slice(&self) -> &[T] { // SAFETY: We know that all elements within `alive` are properly initialized. unsafe { @@ -79,7 +80,7 @@ impl IntoIter { } /// Returns a mutable slice of all elements that have not been yielded yet. - #[unstable(feature = "array_value_iter_slice", issue = "65798")] + #[stable(feature = "array_value_iter", since = "1.51.0")] pub fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: We know that all elements within `alive` are properly initialized. unsafe { diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 71548bec7aaee..0c333ab2dca2b 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -17,7 +17,7 @@ use crate::slice::{Iter, IterMut}; mod iter; -#[unstable(feature = "array_value_iter", issue = "65798")] +#[stable(feature = "array_value_iter", since = "1.51.0")] pub use iter::IntoIter; /// Converts a reference to `T` into a reference to an array of length 1 (without copying). diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 2828235c3e38d..50a12b4bd1cd2 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -45,7 +45,6 @@ #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(int_error_matching)] -#![feature(array_value_iter)] #![feature(iter_advance_by)] #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] diff --git a/src/test/ui/const-generics/array-impls/into-iter-impls-length-32.rs b/src/test/ui/const-generics/array-impls/into-iter-impls-length-32.rs index 0aeba8607e818..6ba1b2813a177 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-impls-length-32.rs +++ b/src/test/ui/const-generics/array-impls/into-iter-impls-length-32.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(array_value_iter)] #![feature(trusted_len)] use std::{ diff --git a/src/test/ui/const-generics/array-impls/into-iter-impls-length-33.rs b/src/test/ui/const-generics/array-impls/into-iter-impls-length-33.rs index 5503813c7aa3e..deafde2912bb7 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-impls-length-33.rs +++ b/src/test/ui/const-generics/array-impls/into-iter-impls-length-33.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(array_value_iter)] #![feature(trusted_len)] use std::{ From 12014d29b89557836a22fa46d74101371d81daf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Jan 2021 16:03:29 +0200 Subject: [PATCH 05/23] Add Box::downcast() for dyn Any + Send + Sync --- library/alloc/src/boxed.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 33b812ec59ff9..b4dd5d92c6a13 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1364,6 +1364,39 @@ impl Box { } } +impl Box { + #[inline] + #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")] + /// Attempt to downcast the box to a concrete type. + /// + /// # Examples + /// + /// ``` + /// use std::any::Any; + /// + /// fn print_if_string(value: Box) { + /// if let Ok(string) = value.downcast::() { + /// println!("String ({}): {}", string.len(), string); + /// } + /// } + /// + /// let my_string = "Hello World".to_string(); + /// print_if_string(Box::new(my_string)); + /// print_if_string(Box::new(0i8)); + /// ``` + pub fn downcast(self) -> Result, Self> { + if self.is::() { + unsafe { + let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = + Box::into_raw_with_allocator(self); + Ok(Box::from_raw_in(raw as *mut T, alloc)) + } + } else { + Err(self) + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Box { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { From b50df6d31c0590f0e7033814973315ca878ab4ad Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Fri, 15 Jan 2021 18:51:09 +0100 Subject: [PATCH 06/23] Stabilize `core::slice::fill_with` --- library/core/src/slice/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 6de2714059480..4a03214d846e5 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2706,13 +2706,12 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_fill_with)] - /// /// let mut buf = vec![1; 10]; /// buf.fill_with(Default::default); /// assert_eq!(buf, vec![0; 10]); /// ``` - #[unstable(feature = "slice_fill_with", issue = "79221")] + #[doc(alias = "memset")] + #[stable(feature = "slice_fill_with", since = "1.51.0")] pub fn fill_with(&mut self, mut f: F) where F: FnMut() -> T, From 8758083aad5d455e83fc3ea630d991195b0c588c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 19 Jan 2021 14:26:02 -0800 Subject: [PATCH 07/23] Remove requirement that forces symmetric and transitive PartialEq impls to exist --- library/core/src/cmp.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b983f49eb1782..4a15b185a83e7 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -31,14 +31,18 @@ use self::Ordering::*; /// equivalence relation. For example, in floating point numbers `NaN != NaN`, /// so floating point types implement `PartialEq` but not [`trait@Eq`]. /// -/// Formally, the equality must be (for all `a`, `b` and `c`): +/// Formally, the equality must be (for all `a`, `b`, `c` of type `A`, `B`, +/// `C`): /// -/// - symmetric: `a == b` implies `b == a`; and -/// - transitive: `a == b` and `b == c` implies `a == c`. +/// - **Symmetric**: if `A: PartialEq` and `B: PartialEq`, then **`a == b` +/// implies `b == a`**; and +/// +/// - **Transitive**: if `A: PartialEq` and `B: PartialEq` and `A: +/// PartialEq`, then **`a == b` and `b == c` implies `a == c`**. /// -/// Note that these requirements mean that the trait itself must be implemented -/// symmetrically and transitively: if `T: PartialEq` and `U: PartialEq` -/// then `U: PartialEq` and `T: PartialEq`. +/// Note that the `B: PartialEq` (symmetric) and `A: PartialEq` +/// (transitive) impls are not forced to exist, but these requirements apply +/// whenever they do exist. /// /// ## Derivable /// From 83d32b0a27350fd640cb29d0514598e4630874bb Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 21 Jan 2021 15:52:53 +0100 Subject: [PATCH 08/23] =?UTF-8?q?Add=20example=20to=20array::IntoIter::new?= =?UTF-8?q?=E2=80=99s=20doc-comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ashley Mannix --- library/core/src/array/iter.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 0fd8815570bd7..535291471b1d0 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -41,6 +41,16 @@ impl IntoIter { /// *Note*: this method might be deprecated in the future, /// after [`IntoIterator` is implemented for arrays][array-into-iter]. /// + /// # Examples + /// + /// ``` + /// use std::array; + /// + /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) { + /// // The type of `value` is a `i32` here, instead of `&i32` + /// let _: i32 = value; + /// } + /// ``` /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819 #[stable(feature = "array_value_iter", since = "1.51.0")] pub fn new(array: [T; N]) -> Self { From a398994cb214c9ba022cb8e6cd97c3fee4bca6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Jan 2021 16:53:56 -0800 Subject: [PATCH 09/23] Account for existing `_` field pattern when suggesting `..` Follow up to #80017. --- compiler/rustc_typeck/src/check/pat.rs | 22 +++++++++++++------ .../ui/pattern/pat-tuple-underfield.stderr | 4 ++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 79234f076acd1..12256058b8715 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1041,12 +1041,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(left, "(".to_string()), (right.shrink_to_hi(), ")".to_string())], Applicability::MachineApplicable, ); - } else if fields.len() > subpats.len() { - let after_fields_span = if pat_span == DUMMY_SP { - pat_span - } else { - pat_span.with_hi(pat_span.hi() - BytePos(1)).shrink_to_hi() - }; + } else if fields.len() > subpats.len() && pat_span != DUMMY_SP { + let after_fields_span = pat_span.with_hi(pat_span.hi() - BytePos(1)).shrink_to_hi(); let all_fields_span = match subpats { [] => after_fields_span, [field] => field.span, @@ -1055,7 +1051,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if all the fields in the pattern are wildcards. let all_wildcards = subpats.iter().all(|pat| matches!(pat.kind, PatKind::Wild)); + let first_tail_wildcard = + subpats.iter().enumerate().fold(None, |acc, (pos, pat)| match (acc, &pat.kind) { + (None, PatKind::Wild) => Some(pos), + (Some(_), PatKind::Wild) => acc, + _ => None, + }); + let tail_span = match first_tail_wildcard { + None => after_fields_span, + Some(0) => subpats[0].span.to(after_fields_span), + Some(pos) => subpats[pos - 1].span.shrink_to_hi().to(after_fields_span), + }; + // FIXME: heuristic-based suggestion to check current types for where to add `_`. let mut wildcard_sugg = vec!["_"; fields.len() - subpats.len()].join(", "); if !subpats.is_empty() { wildcard_sugg = String::from(", ") + &wildcard_sugg; @@ -1080,7 +1088,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } else { err.span_suggestion_verbose( - after_fields_span, + tail_span, "use `..` to ignore the rest of the fields", String::from(", .."), Applicability::MaybeIncorrect, diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr index 76323d9a7bf56..70c21dbafe9fc 100644 --- a/src/test/ui/pattern/pat-tuple-underfield.stderr +++ b/src/test/ui/pattern/pat-tuple-underfield.stderr @@ -122,8 +122,8 @@ LL | Point4( a , _ , _, _) => {} | ^^^^^^ help: use `..` to ignore the rest of the fields | -LL | Point4( a , _ , ..) => {} - | ^^^^ +LL | Point4( a, ..) => {} + | ^^^^ error: aborting due to 8 previous errors From 5d739180cde7f7350b7a90e8a7542bd9c4cd6783 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Jan 2021 09:47:59 -0500 Subject: [PATCH 10/23] Clone entire `TokenCursor` when collecting tokens Reverts PR #80830 Fixes taiki-e/pin-project#312 We can have an arbitrary number of `None`-delimited group frames pushed on the stack due to proc-macro invocations, which can legally be exited. Attempting to account for this would add a lot of complexity for a tiny performance gain, so let's just use the original strategy. --- compiler/rustc_parse/src/parser/mod.rs | 10 +------- .../auxiliary/nonterminal-recollect-attr.rs | 23 +++++++++++++++++++ .../proc-macro/nonterminal-recollect-attr.rs | 17 ++++++++++++++ 3 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs create mode 100644 src/test/ui/proc-macro/nonterminal-recollect-attr.rs diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index c575c8219641c..e2af63d1744ec 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1254,15 +1254,7 @@ impl<'a> Parser<'a> { f: impl FnOnce(&mut Self) -> PResult<'a, (R, TrailingToken)>, ) -> PResult<'a, R> { let start_token = (self.token.clone(), self.token_spacing); - let cursor_snapshot = TokenCursor { - frame: self.token_cursor.frame.clone(), - // We only ever capture tokens within our current frame, - // so we can just use an empty frame stack - stack: vec![], - desugar_doc_comments: self.token_cursor.desugar_doc_comments, - num_next_calls: self.token_cursor.num_next_calls, - append_unglued_token: self.token_cursor.append_unglued_token.clone(), - }; + let cursor_snapshot = self.token_cursor.clone(); let (mut ret, trailing_token) = f(self)?; diff --git a/src/test/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs b/src/test/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs new file mode 100644 index 0000000000000..a6903283aa108 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/nonterminal-recollect-attr.rs @@ -0,0 +1,23 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_quote)] + +extern crate proc_macro; +use proc_macro::{TokenStream, quote}; + +#[proc_macro_attribute] +pub fn first_attr(_: TokenStream, input: TokenStream) -> TokenStream { + let recollected: TokenStream = input.into_iter().collect(); + quote! { + #[second_attr] + $recollected + } +} + +#[proc_macro_attribute] +pub fn second_attr(_: TokenStream, input: TokenStream) -> TokenStream { + let _recollected: TokenStream = input.into_iter().collect(); + TokenStream::new() +} diff --git a/src/test/ui/proc-macro/nonterminal-recollect-attr.rs b/src/test/ui/proc-macro/nonterminal-recollect-attr.rs new file mode 100644 index 0000000000000..5d4649b78c270 --- /dev/null +++ b/src/test/ui/proc-macro/nonterminal-recollect-attr.rs @@ -0,0 +1,17 @@ +// check-pass +// aux-build:nonterminal-recollect-attr.rs + +extern crate nonterminal_recollect_attr; +use nonterminal_recollect_attr::*; + +macro_rules! my_macro { + ($v:ident) => { + #[first_attr] + $v struct Foo { + field: u8 + } + } +} + +my_macro!(pub); +fn main() {} From ada714d9ce80748d6820565135397e46662ace9b Mon Sep 17 00:00:00 2001 From: Kogia-sima Date: Fri, 29 Jan 2021 02:27:20 +0900 Subject: [PATCH 11/23] Optimize udiv_1e19() function --- library/core/src/fmt/num.rs | 55 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 7a98210995ec7..cdd731fdd4d4e 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -643,25 +643,42 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R } /// Partition of `n` into n > 1e19 and rem <= 1e19 +/// +/// Integer division algorithm is based on the following paper: +/// +/// T. Granlund and P. Montgomery, “Division by Invariant Integers Using Multiplication” +/// in Proc. of the SIGPLAN94 Conference on Programming Language Design and +/// Implementation, 1994, pp. 61–72 +/// fn udiv_1e19(n: u128) -> (u128, u64) { const DIV: u64 = 1e19 as u64; - let high = (n >> 64) as u64; - if high == 0 { - let low = n as u64; - return ((low / DIV) as u128, low % DIV); - } - let sr = 65 - high.leading_zeros(); - let mut q = n << (128 - sr); - let mut r = n >> sr; - let mut carry = 0; - - for _ in 0..sr { - r = (r << 1) | (q >> 127); - q = (q << 1) | carry as u128; - - let s = (DIV as u128).wrapping_sub(r).wrapping_sub(1) as i128 >> 127; - carry = (s & 1) as u64; - r -= (DIV as u128) & s as u128; - } - ((q << 1) | carry as u128, r as u64) + const FACTOR: u128 = 156927543384667019095894735580191660403; + + let quot = if n < 1 << 83 { + ((n >> 19) as u64 / (DIV >> 19)) as u128 + } else { + u128_mulhi(n, FACTOR) >> 62 + }; + + let rem = (n - quot * DIV as u128) as u64; + (quot, rem) +} + +/// Multiply unsigned 128 bit integers, return upper 128 bits of the result +#[inline] +fn u128_mulhi(x: u128, y: u128) -> u128 { + let x_lo = x as u64; + let x_hi = (x >> 64) as u64; + let y_lo = y as u64; + let y_hi = (y >> 64) as u64; + + // handle possibility of overflow + let carry = (x_lo as u128 * y_lo as u128) >> 64; + let m = x_lo as u128 * y_hi as u128 + carry; + let high1 = m >> 64; + + let m_lo = m as u64; + let high2 = (x_hi as u128 * y_lo as u128 + m_lo as u128) >> 64; + + x_hi as u128 * y_hi as u128 + high1 + high2 } From 81ed4cfd0138e68d370873281f53f4e63e5a223f Mon Sep 17 00:00:00 2001 From: 0yoyoyo <60439919+0yoyoyo@users.noreply.github.com> Date: Fri, 29 Jan 2021 19:23:04 +0900 Subject: [PATCH 12/23] Add a regression test --- .../typeck_type_placeholder_item_help.rs | 13 ++++++++----- .../typeck_type_placeholder_item_help.stderr | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs index 905fc35350ed0..0c890f88c60dc 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs @@ -10,15 +10,18 @@ const TEST2: _ = 42u32; const TEST3: _ = Some(42); //~^ ERROR the type placeholder `_` is not allowed within types on item signatures -trait Test4 { - const TEST4: _ = 42; +const TEST4: fn() -> _ = 42; +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +trait Test5 { + const TEST5: _ = 42; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } -struct Test5; +struct Test6; -impl Test5 { - const TEST5: _ = 13; +impl Test6 { + const TEST6: _ = 13; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr index 88133814d2978..0121e18631676 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -26,23 +26,32 @@ LL | const TEST3: _ = Some(42); | help: replace `_` with the correct type: `Option` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item_help.rs:14:18 + --> $DIR/typeck_type_placeholder_item_help.rs:13:22 | -LL | const TEST4: _ = 42; +LL | const TEST4: fn() -> _ = 42; + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:17:18 + | +LL | const TEST5: _ = 42; | ^ | | | not allowed in type signatures | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item_help.rs:21:18 + --> $DIR/typeck_type_placeholder_item_help.rs:24:18 | -LL | const TEST5: _ = 13; +LL | const TEST6: _ = 13; | ^ | | | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0121`. From 56c27360b1f1eb56a12d00586f716aba4b414848 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 30 Jan 2021 14:24:00 +0100 Subject: [PATCH 13/23] Replace predecessor with range in collections documentation Fixes #81548. --- library/std/src/collections/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index a1aab767eb26f..80a13d52a2a27 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -110,10 +110,10 @@ //! //! For Sets, all operations have the cost of the equivalent Map operation. //! -//! | | get | insert | remove | predecessor | append | -//! |--------------|-----------|-----------|-----------|-------------|--------| -//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | -//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) | +//! | | get | insert | remove | range | append | +//! |--------------|-----------|-----------|-----------|-----------|--------| +//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | +//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) | //! //! # Correct and Efficient Usage of Collections //! From 7e3217845dc5dea331b26efb2bf51b60afae2082 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 28 Jan 2021 22:03:20 +0000 Subject: [PATCH 14/23] Balance sidebar `Deref` cycle check with main content The `Deref` cycle checks added as part of #80653 were "unbalanced" in the sense that the main content code path checks for cycles _before_ descending, while the sidebar checks _after_. Checking _before_ is correct, so this changes the sidebar path to match the main content path. --- src/librustdoc/html/render/mod.rs | 18 +++++++++++------- src/test/rustdoc-ui/deref-generic.rs | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 src/test/rustdoc-ui/deref-generic.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index daaa2c719b0e6..6909ab870db61 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -3510,6 +3510,7 @@ fn render_assoc_items( "deref-methods-{:#}", type_.print(cx.cache()) ))); + debug!("Adding {} to deref id map", type_.print(cx.cache())); cx.deref_id_map .borrow_mut() .insert(type_.def_id_full(cx.cache()).unwrap(), id.clone()); @@ -3626,6 +3627,7 @@ fn render_deref_methods( _ => None, }) .expect("Expected associated type binding"); + debug!("Render deref methods for {:#?}, target {:#?}", impl_.inner_impl().for_, target); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; if let Some(did) = target.def_id_full(cx.cache()) { @@ -4416,6 +4418,15 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V }) { debug!("found target, real_target: {:?} {:?}", target, real_target); + if let Some(did) = target.def_id_full(cx.cache()) { + if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { + // `impl Deref for S` + if did == type_did { + // Avoid infinite cycles + return; + } + } + } let deref_mut = v .iter() .filter(|i| i.inner_impl().trait_.is_some()) @@ -4464,13 +4475,6 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id_full(cx.cache()) == c.deref_trait_did) { - if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { - // `impl Deref for S` - if target_did == type_did { - // Avoid infinite cycles - return; - } - } sidebar_deref_methods(cx, out, target_deref_impl, target_impls); } } diff --git a/src/test/rustdoc-ui/deref-generic.rs b/src/test/rustdoc-ui/deref-generic.rs new file mode 100644 index 0000000000000..bc64beb1b939d --- /dev/null +++ b/src/test/rustdoc-ui/deref-generic.rs @@ -0,0 +1,15 @@ +// check-pass +// #81395: Fix ICE when recursing into Deref target only differing in type args + +pub struct Generic(T); + +impl<'a> std::ops::Deref for Generic<&'a mut ()> { + type Target = Generic<&'a ()>; + fn deref(&self) -> &Self::Target { + unimplemented!() + } +} + +impl<'a> Generic<&'a ()> { + pub fn some_method(&self) {} +} From 4a2a5f078000f3040fd155dce036a553a2af0a27 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 31 Jan 2021 00:45:19 +0800 Subject: [PATCH 15/23] Fix ascii art text wrapping in mobile Fix #81377 --- src/librustdoc/html/static/rustdoc.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8dad26dced956..e938d84f75fcc 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -156,6 +156,7 @@ code, pre, a.test-arrow { } .docblock pre code, .docblock-short pre code, .docblock code.spotlight { padding: 0; + padding-right: 1ex; } .docblock code.spotlight :last-child { padding-bottom: 0.6em; @@ -404,9 +405,6 @@ nav.sub { text-overflow: ellipsis; margin: 0; } -.docblock code, .docblock-short code { - white-space: pre-wrap; -} .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { border-bottom: 1px solid; From 55d6247f52051e897938e8f65a34c3cc661f5e24 Mon Sep 17 00:00:00 2001 From: The8472 Date: Sat, 30 Jan 2021 18:07:48 +0100 Subject: [PATCH 16/23] Clarify that guarantees extend to other advancing iterator methods. --- library/core/src/iter/traits/marker.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs index ed8eea672f80b..c4e21b84863df 100644 --- a/library/core/src/iter/traits/marker.rs +++ b/library/core/src/iter/traits/marker.rs @@ -43,12 +43,14 @@ unsafe impl TrustedLen for &mut I {} /// An iterator that when yielding an item will have taken at least one element /// from its underlying [`SourceIter`]. /// -/// Calling [`next()`] guarantees that at least one value of the iterator's underlying source -/// has been moved out and the result of the iterator chain could be inserted in its place, -/// assuming structural constraints of the source allow such an insertion. +/// Calling any method that advances the iterator, e.g. [`next()`] or [`try_fold()`], +/// guarantees that for each step at least one value of the iterator's underlying source +/// has been moved out and the result of the iterator chain could be inserted +/// in its place, assuming structural constraints of the source allow such an insertion. /// In other words this trait indicates that an iterator pipeline can be collected in place. /// /// [`SourceIter`]: crate::iter::SourceIter /// [`next()`]: Iterator::next +/// [`try_fold()`]: Iterator::try_fold #[unstable(issue = "none", feature = "inplace_iteration")] pub unsafe trait InPlaceIterable: Iterator {} From d3048eea3cd212f7d8eba54d016c98e12a969a07 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 31 Jan 2021 01:19:29 +0800 Subject: [PATCH 17/23] Improve docblock readability on small screen --- src/librustdoc/html/static/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8dad26dced956..0a0e2605893e3 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1624,6 +1624,10 @@ h4 > .notable-traits { #settings-menu { top: 7px; } + + .docblock { + margin-left: 12px; + } } h3.notable { From 6d7ef10b4662fcd76cac9ca81568fcd26136b4db Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 31 Jan 2021 01:27:21 +0800 Subject: [PATCH 18/23] Fix docblock short code missing end whitespaces --- src/librustdoc/html/static/rustdoc.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index e938d84f75fcc..644a186ff1697 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -405,6 +405,9 @@ nav.sub { text-overflow: ellipsis; margin: 0; } +.docblock-short code { + white-space: pre-wrap; +} .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { border-bottom: 1px solid; From 131ee0784401937fb2af57ec90163722a7de135f Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 31 Jan 2021 01:36:15 +0800 Subject: [PATCH 19/23] Remove extra trailing spaces --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 0a0e2605893e3..503731f3ed401 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1624,7 +1624,7 @@ h4 > .notable-traits { #settings-menu { top: 7px; } - + .docblock { margin-left: 12px; } From adfb04fc4e9742ab9cce34e8c1989029c92eca48 Mon Sep 17 00:00:00 2001 From: pierwill Date: Fri, 29 Jan 2021 23:03:35 -0800 Subject: [PATCH 20/23] Edit rustc_typeck top-level docs Edit punctuation and wording in note on type variables vs. type parameters. Also add missing punctuation and two inter-doc links. --- compiler/rustc_typeck/src/check/mod.rs | 8 ++++---- compiler/rustc_typeck/src/lib.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index c8c6fa12fae08..dc3e3b4e73839 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -52,13 +52,13 @@ The types of top-level items, which never contain unbound type variables, are stored directly into the `tcx` typeck_results. N.B., a type variable is not the same thing as a type parameter. A -type variable is rather an "instance" of a type parameter: that is, -given a generic function `fn foo(t: T)`: while checking the +type variable is an instance of a type parameter. That is, +given a generic function `fn foo(t: T)`, while checking the function `foo`, the type `ty_param(0)` refers to the type `T`, which -is treated in abstract. When `foo()` is called, however, `T` will be +is treated in abstract. However, when `foo()` is called, `T` will be substituted for a fresh type variable `N`. This variable will eventually be resolved to some concrete type (which might itself be -type parameter). +a type parameter). */ diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index ad92d816c9836..a5bdfb573628c 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -7,9 +7,9 @@ The type checker is responsible for: 1. Determining the type of each expression. 2. Resolving methods and traits. 3. Guaranteeing that most type rules are met. ("Most?", you say, "why most?" - Well, dear reader, read on) + Well, dear reader, read on.) -The main entry point is `check_crate()`. Type checking operates in +The main entry point is [`check_crate()`]. Type checking operates in several major phases: 1. The collect phase first passes over all items and determines their @@ -25,7 +25,7 @@ several major phases: containing function). Inference is used to supply types wherever they are unknown. The actual checking of a function itself has several phases (check, regionck, writeback), as discussed in the - documentation for the `check` module. + documentation for the [`check`] module. The type checker is defined into various submodules which are documented independently: From fe4ac95cb858a7a26c94c2c236fe380448675a82 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 30 Jan 2021 21:08:30 +0100 Subject: [PATCH 21/23] Bump stable version of arc_mutate_strong_count --- library/alloc/src/sync.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 1ff30ca610dbb..bfb3a8858ed3a 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -885,7 +885,7 @@ impl Arc { /// } /// ``` #[inline] - #[stable(feature = "arc_mutate_strong_count", since = "1.50.0")] + #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn increment_strong_count(ptr: *const T) { // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop let arc = unsafe { mem::ManuallyDrop::new(Arc::::from_raw(ptr)) }; @@ -924,7 +924,7 @@ impl Arc { /// } /// ``` #[inline] - #[stable(feature = "arc_mutate_strong_count", since = "1.50.0")] + #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { unsafe { mem::drop(Arc::from_raw(ptr)) }; } From bef4ec2fc51aa020fe6bf81257459f096763f3b7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 30 Jan 2021 22:10:25 +0100 Subject: [PATCH 22/23] Bump as_mut_str_for_str stable version. --- library/core/src/convert/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index d8c2e0b2a3bfe..ea8070534ebcd 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -623,7 +623,7 @@ impl AsRef for str { } } -#[stable(feature = "as_mut_str_for_str", since = "1.50.0")] +#[stable(feature = "as_mut_str_for_str", since = "1.51.0")] impl AsMut for str { #[inline] fn as_mut(&mut self) -> &mut str { From f1cd17961ccaac4bfaeeab81969cf36c56eec4a5 Mon Sep 17 00:00:00 2001 From: oberien Date: Sat, 17 Oct 2020 12:08:59 +0200 Subject: [PATCH 23/23] impl Seek for Empty Fix #78029 --- library/std/src/io/util.rs | 17 ++++++++++++++++- library/std/src/io/util/tests.rs | 22 +++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index db845457c9672..e43ce4cdb4b8e 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -4,7 +4,7 @@ mod tests; use crate::fmt; -use crate::io::{self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Write}; +use crate::io::{self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; /// A reader which is always at EOF. /// @@ -58,6 +58,21 @@ impl BufRead for Empty { fn consume(&mut self, _n: usize) {} } +#[stable(feature = "empty_seek", since = "1.51.0")] +impl Seek for Empty { + fn seek(&mut self, _pos: SeekFrom) -> io::Result { + Ok(0) + } + + fn stream_len(&mut self) -> io::Result { + Ok(0) + } + + fn stream_position(&mut self) -> io::Result { + Ok(0) + } +} + #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for Empty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index 9450b1ee1240c..df34e27d1361b 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -1,5 +1,5 @@ use crate::io::prelude::*; -use crate::io::{copy, empty, repeat, sink, Empty, Repeat, Sink}; +use crate::io::{copy, empty, repeat, sink, Empty, Repeat, SeekFrom, Sink}; #[test] fn copy_copies() { @@ -29,6 +29,26 @@ fn empty_reads() { assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); } +#[test] +fn empty_seeks() { + let mut e = empty(); + assert!(matches!(e.seek(SeekFrom::Start(0)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Start(1)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Start(u64::MAX)), Ok(0))); + + assert!(matches!(e.seek(SeekFrom::End(i64::MIN)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::End(-1)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::End(0)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::End(1)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::End(i64::MAX)), Ok(0))); + + assert!(matches!(e.seek(SeekFrom::Current(i64::MIN)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Current(-1)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Current(0)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Current(1)), Ok(0))); + assert!(matches!(e.seek(SeekFrom::Current(i64::MAX)), Ok(0))); +} + #[test] fn repeat_repeats() { let mut r = repeat(4);