diff --git a/.mailmap b/.mailmap index 680aa04078f97..da17344c2085e 100644 --- a/.mailmap +++ b/.mailmap @@ -70,6 +70,8 @@ David Manescu David Ross Derek Chiang Derek Chiang (Enchi Jiang) Diggory Hardy Diggory Hardy +Donough Liu +Donough Liu DingMing Liu Dustin Bensing Dylan Braithwaite Dzmitry Malyshau diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8ef6090c743a9..8cc6f04c0653a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -865,6 +865,25 @@ impl From> for Box<[u8]> { } } +#[stable(feature = "box_from_array", since = "1.45.0")] +impl From<[T; N]> for Box<[T]> +where + [T; N]: LengthAtMost32, +{ + /// Converts a `[T; N]` into a `Box<[T]>` + /// + /// This conversion moves the array to newly heap-allocated memory. + /// + /// # Examples + /// ```rust + /// let boxed: Box<[u8]> = Box::from([4, 2]); + /// println!("{:?}", boxed); + /// ``` + fn from(array: [T; N]) -> Box<[T]> { + box array + } +} + #[stable(feature = "boxed_slice_try_from", since = "1.43.0")] impl TryFrom> for Box<[T; N]> where diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index ad96a138d7e55..4edbc2ff3ac9b 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -580,8 +580,6 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::rc::Rc; /// /// let x = Rc::new("hello".to_owned()); @@ -590,7 +588,7 @@ impl Rc { /// assert_eq!(x_ptr, Rc::as_ptr(&y)); /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn as_ptr(this: &Self) -> *const T { let ptr: *mut RcBox = NonNull::as_ptr(this.ptr); let fake_ptr = ptr as *mut T; @@ -1681,8 +1679,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::rc::Rc; /// use std::ptr; /// @@ -1700,7 +1696,7 @@ impl Weak { /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn as_ptr(&self) -> *const T { let offset = data_offset_sized::(); let ptr = self.ptr.cast::().as_ptr().wrapping_offset(offset); @@ -1718,8 +1714,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::rc::{Rc, Weak}; /// /// let strong = Rc::new("hello".to_owned()); @@ -1735,7 +1729,7 @@ impl Weak { /// /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_ptr`]: struct.Weak.html#method.as_ptr - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn into_raw(self) -> *const T { let result = self.as_ptr(); mem::forget(self); @@ -1762,8 +1756,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::rc::{Rc, Weak}; /// /// let strong = Rc::new("hello".to_owned()); @@ -1788,7 +1780,7 @@ impl Weak { /// [`Weak`]: struct.Weak.html /// [`new`]: struct.Weak.html#method.new /// [`forget`]: ../../std/mem/fn.forget.html - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { if ptr.is_null() { Self::new() diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 8a45715e89c91..5de3cac9d5382 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -579,8 +579,6 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::sync::Arc; /// /// let x = Arc::new("hello".to_owned()); @@ -589,7 +587,7 @@ impl Arc { /// assert_eq!(x_ptr, Arc::as_ptr(&y)); /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn as_ptr(this: &Self) -> *const T { let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); let fake_ptr = ptr as *mut T; @@ -1449,8 +1447,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::sync::Arc; /// use std::ptr; /// @@ -1468,7 +1464,7 @@ impl Weak { /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn as_ptr(&self) -> *const T { let offset = data_offset_sized::(); let ptr = self.ptr.cast::().as_ptr().wrapping_offset(offset); @@ -1486,8 +1482,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::sync::{Arc, Weak}; /// /// let strong = Arc::new("hello".to_owned()); @@ -1503,7 +1497,7 @@ impl Weak { /// /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_ptr`]: struct.Weak.html#method.as_ptr - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn into_raw(self) -> *const T { let result = self.as_ptr(); mem::forget(self); @@ -1531,8 +1525,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_into_raw)] - /// /// use std::sync::{Arc, Weak}; /// /// let strong = Arc::new("hello".to_owned()); @@ -1557,7 +1549,7 @@ impl Weak { /// [`Weak`]: struct.Weak.html /// [`Arc`]: struct.Arc.html /// [`forget`]: ../../std/mem/fn.forget.html - #[unstable(feature = "weak_into_raw", issue = "60728")] + #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { if ptr.is_null() { Self::new() diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3d90fe1fa2f21..9c5dbb5e6f356 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1618,7 +1618,8 @@ impl<'a> Formatter<'a> { self.width } - /// Optionally specified precision for numeric types. + /// Optionally specified precision for numeric types. Alternatively, the + /// maximum width for string types. /// /// # Examples /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index c517286d49898..b514e0f6d9cff 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -4052,15 +4052,13 @@ impl str { /// # Examples /// /// ``` - /// #![feature(str_strip)] - /// /// assert_eq!("foo:bar".strip_prefix("foo:"), Some("bar")); /// assert_eq!("foo:bar".strip_prefix("bar"), None); /// assert_eq!("foofoo".strip_prefix("foo"), Some("foo")); /// ``` #[must_use = "this returns the remaining substring as a new slice, \ without modifying the original"] - #[unstable(feature = "str_strip", reason = "newly added", issue = "67302")] + #[stable(feature = "str_strip", since = "1.45.0")] pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> { prefix.strip_prefix_of(self) } @@ -4082,14 +4080,13 @@ impl str { /// # Examples /// /// ``` - /// #![feature(str_strip)] /// assert_eq!("bar:foo".strip_suffix(":foo"), Some("bar")); /// assert_eq!("bar:foo".strip_suffix("bar"), None); /// assert_eq!("foofoo".strip_suffix("foo"), Some("foo")); /// ``` #[must_use = "this returns the remaining substring as a new slice, \ without modifying the original"] - #[unstable(feature = "str_strip", reason = "newly added", issue = "67302")] + #[stable(feature = "str_strip", since = "1.45.0")] pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str> where P: Pattern<'a>, diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 220f221cdd36d..449aac85bc773 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1807,13 +1807,12 @@ new value. Returns a `Result` of `Ok(previous_value)` if the function returned ` Note: This may call the function multiple times if the value has been changed from other threads in the meantime, as long as the function returns `Some(_)`, but the function will have been applied -but once to the stored value. +only once to the stored value. -`fetch_update` takes two [`Ordering`] arguments to describe the memory -ordering of this operation. The first describes the required ordering for loads -and failed updates while the second describes the required ordering when the -operation finally succeeds. Beware that this is different from the two -modes in [`compare_exchange`]! +`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation. +The first describes the required ordering for when the operation finally succeeds while the second +describes the required ordering for loads. These correspond to the success and failure orderings of +[`compare_exchange`] respectively. Using [`Acquire`] as success ordering makes the store part of this operation [`Relaxed`], and using [`Release`] makes the final successful load @@ -1831,24 +1830,21 @@ and must be equivalent to or weaker than the success ordering. # Examples ```rust -#![feature(no_more_cas)] ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; let x = ", stringify!($atomic_type), "::new(7); -assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7)); -assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7)); -assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8)); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7)); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7)); +assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8)); assert_eq!(x.load(Ordering::SeqCst), 9); ```"), #[inline] - #[unstable(feature = "no_more_cas", - reason = "no more CAS loops in user code", - issue = "48655")] + #[stable(feature = "no_more_cas", since = "1.45.0")] #[$cfg_cas] pub fn fetch_update(&self, - mut f: F, + set_order: Ordering, fetch_order: Ordering, - set_order: Ordering) -> Result<$int_type, $int_type> + mut f: F) -> Result<$int_type, $int_type> where F: FnMut($int_type) -> Option<$int_type> { let mut prev = self.load(fetch_order); while let Some(next) = f(prev) { @@ -1882,7 +1878,6 @@ using [`Release`] makes the load part [`Relaxed`]. # Examples ``` -#![feature(atomic_min_max)] ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; let foo = ", stringify!($atomic_type), "::new(23); @@ -1893,7 +1888,6 @@ assert_eq!(foo.load(Ordering::SeqCst), 42); If you want to obtain the maximum value in one step, you can use the following: ``` -#![feature(atomic_min_max)] ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; let foo = ", stringify!($atomic_type), "::new(23); @@ -1902,9 +1896,7 @@ let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar); assert!(max_foo == 42); ```"), #[inline] - #[unstable(feature = "atomic_min_max", - reason = "easier and faster min/max than writing manual CAS loop", - issue = "48655")] + #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. @@ -1933,7 +1925,6 @@ using [`Release`] makes the load part [`Relaxed`]. # Examples ``` -#![feature(atomic_min_max)] ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; let foo = ", stringify!($atomic_type), "::new(23); @@ -1946,7 +1937,6 @@ assert_eq!(foo.load(Ordering::Relaxed), 22); If you want to obtain the minimum value in one step, you can use the following: ``` -#![feature(atomic_min_max)] ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; let foo = ", stringify!($atomic_type), "::new(23); @@ -1955,9 +1945,7 @@ let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar); assert_eq!(min_foo, 12); ```"), #[inline] - #[unstable(feature = "atomic_min_max", - reason = "easier and faster min/max than writing manual CAS loop", - issue = "48655")] + #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. diff --git a/src/librustc_trait_selection/lib.rs b/src/librustc_trait_selection/lib.rs index 4796b431d8dca..044239b047a4e 100644 --- a/src/librustc_trait_selection/lib.rs +++ b/src/librustc_trait_selection/lib.rs @@ -16,7 +16,6 @@ #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] #![feature(or_patterns)] -#![feature(str_strip)] #![feature(option_zip)] #![recursion_limit = "512"] // For rustdoc diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 24b57f12e8df4..3b4cb859dd425 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -14,6 +14,7 @@ // reconsider what crate these items belong in. use core::array; +use core::convert::Infallible; use crate::alloc::{AllocErr, LayoutErr}; use crate::any::TypeId; @@ -474,7 +475,7 @@ impl Error for string::FromUtf16Error { } #[stable(feature = "str_parse_error2", since = "1.8.0")] -impl Error for string::ParseError { +impl Error for Infallible { fn description(&self) -> &str { match *self {} } diff --git a/src/test/codegen/integer-overflow.rs b/src/test/codegen/integer-overflow.rs new file mode 100644 index 0000000000000..183de56db9685 --- /dev/null +++ b/src/test/codegen/integer-overflow.rs @@ -0,0 +1,26 @@ +// no-system-llvm +// compile-flags: -O -C overflow-checks=on + +#![crate_type = "lib"] + + +pub struct S1<'a> { + data: &'a [u8], + position: usize, +} + +// CHECK-LABEL: @slice_no_index_order +#[no_mangle] +pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] { + // CHECK-NOT: slice_index_order_fail + let d = &s.data[s.position..s.position+n]; + s.position += n; + return d; +} + +// CHECK-LABEL: @test_check +#[no_mangle] +pub fn test_check<'a>(s: &'a mut S1, x: usize, y: usize) -> &'a [u8] { + // CHECK: slice_index_order_fail + &s.data[x..y] +} diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs index 0d0765e971d50..b4a083636b64f 100644 --- a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs +++ b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs @@ -18,6 +18,10 @@ pub fn yes_array_into_vec() -> Vec { [].into() } +pub fn yes_array_into_box() -> Box<[T]> { + [].into() +} + use std::collections::VecDeque; pub fn yes_vecdeque_partial_eq_array() -> impl PartialEq<[B; 32]> diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs index 4b195f3a06edc..48cf21d489ada 100644 --- a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs @@ -12,6 +12,8 @@ pub fn no_box() { let boxed_array = >::try_from(boxed_slice); //~^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From>` is not satisfied //~^^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied + let boxed_slice = >::from([0; 33]); + //~^ 15:42: 15:49: arrays only have std trait implementations for lengths 0..=32 [E0277] } pub fn no_rc() { diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr index ce1c9ae551ea5..5c01603ab881c 100644 --- a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr @@ -18,10 +18,23 @@ LL | let boxed_array = >::try_from(boxed_slice); as std::convert::From<&str>> as std::convert::From>> as std::convert::From> - and 21 others + and 22 others = note: required because of the requirements on the impl of `std::convert::Into>` for `std::boxed::Box<[i32]>` = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::boxed::Box<[i32; 33]>` +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-types-no-impls-length-33.rs:15:42 + | +LL | let boxed_slice = >::from([0; 33]); + | ^^^^^^^ + | | + | expected an implementor of trait `std::convert::From<[{integer}; 33]>` + | help: consider borrowing here: `&[0; 33]` + | + = note: the trait bound `[i32; 33]: std::convert::From<[{integer}; 33]>` is not satisfied + = note: required because of the requirements on the impl of `std::convert::From<[i32; 33]>` for `std::boxed::Box<[i32]>` + = note: required by `std::convert::From::from` + error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied --> $DIR/alloc-types-no-impls-length-33.rs:12:23 | @@ -32,7 +45,7 @@ LL | let boxed_array = >::try_from(boxed_slice); as std::convert::TryFrom>> error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From>` is not satisfied - --> $DIR/alloc-types-no-impls-length-33.rs:19:23 + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 | LL | let boxed_array = >::try_from(boxed_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::rc::Rc<[i32; 33]>` @@ -47,7 +60,7 @@ LL | let boxed_array = >::try_from(boxed_slice); = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::rc::Rc<[i32; 33]>` error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom>` is not satisfied - --> $DIR/alloc-types-no-impls-length-33.rs:19:23 + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 | LL | let boxed_array = >::try_from(boxed_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::rc::Rc<[i32; 33]>` @@ -56,7 +69,7 @@ LL | let boxed_array = >::try_from(boxed_slice); as std::convert::TryFrom>> error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From>` is not satisfied - --> $DIR/alloc-types-no-impls-length-33.rs:26:23 + --> $DIR/alloc-types-no-impls-length-33.rs:28:23 | LL | let boxed_array = >::try_from(boxed_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::sync::Arc<[i32; 33]>` @@ -71,7 +84,7 @@ LL | let boxed_array = >::try_from(boxed_slice); = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::sync::Arc<[i32; 33]>` error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom>` is not satisfied - --> $DIR/alloc-types-no-impls-length-33.rs:26:23 + --> $DIR/alloc-types-no-impls-length-33.rs:28:23 | LL | let boxed_array = >::try_from(boxed_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::sync::Arc<[i32; 33]>` @@ -79,6 +92,6 @@ LL | let boxed_array = >::try_from(boxed_slice); = help: the following implementations were found: as std::convert::TryFrom>> -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index d3a7e24937f95..3e1f423865b1d 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -1,6 +1,5 @@ #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![feature(rustc_private)] -#![feature(str_strip)] // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.)