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/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 1c3d95cbb8c35..7f081f732fd58 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1180,6 +1180,17 @@ pub trait Iterator { /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` + /// + /// If less than `n` elements are available, + /// `take` will limit itself to the size of the underlying iterator: + /// + /// ``` + /// let v = vec![1, 2]; + /// let mut iter = v.into_iter().take(5); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take(self, n: usize) -> Take 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_error_codes/error_codes/E0601.md b/src/librustc_error_codes/error_codes/E0601.md index 8180c5db46fba..7194b7971d38f 100644 --- a/src/librustc_error_codes/error_codes/E0601.md +++ b/src/librustc_error_codes/error_codes/E0601.md @@ -1,5 +1,6 @@ -No `main` function was found in a binary crate. To fix this error, add a -`main` function. For example: +No `main` function was found in a binary crate. + +To fix this error, add a `main` function: ``` fn main() { diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index 44971a98cc32f..524a357971029 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -366,7 +366,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // FIXME(#14407) ungated!(rustc_const_stable, Whitelisted, template!(List: r#"feature = "name""#)), gated!( - allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), + allow_internal_unstable, Whitelisted, template!(Word, List: "feat1, feat2, ..."), "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index f69343f4d7500..92000e6411354 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -606,7 +606,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: self.tcx.mk_const(*ty::Const::from_scalar(self.tcx, scalar, ty)), + literal: ty::Const::from_scalar(self.tcx, scalar, ty), })) } diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index b21524cb9bdd2..c00b608482933 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -672,6 +672,26 @@ impl<'a> Parser<'a> { } } + // If this was a missing `@` in a binding pattern + // bail with a suggestion + // https://github.com/rust-lang/rust/issues/72373 + if self.prev_token.is_ident() && &self.token.kind == &token::DotDot { + let msg = format!( + "if you meant to bind the contents of \ + the rest of the array pattern into `{}`, use `@`", + pprust::token_to_string(&self.prev_token) + ); + expect_err + .span_suggestion_verbose( + self.prev_token.span.shrink_to_hi().until(self.token.span), + &msg, + " @ ".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(); + break; + } + // Attempt to keep parsing if it was an omitted separator. match f(self) { Ok(t) => { 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/issues/issue-72373.rs b/src/test/ui/issues/issue-72373.rs new file mode 100644 index 0000000000000..4da6061c27fe8 --- /dev/null +++ b/src/test/ui/issues/issue-72373.rs @@ -0,0 +1,9 @@ +fn foo(c: &[u32], n: u32) -> u32 { + match *c { + [h, ..] if h > n => 0, + [h, ..] if h == n => 1, + [h, ref ts..] => foo(c, n - h) + foo(ts, n), + //~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..` + [] => 0, + } +} diff --git a/src/test/ui/issues/issue-72373.stderr b/src/test/ui/issues/issue-72373.stderr new file mode 100644 index 0000000000000..dfde8624814f8 --- /dev/null +++ b/src/test/ui/issues/issue-72373.stderr @@ -0,0 +1,13 @@ +error: expected one of `,`, `@`, `]`, or `|`, found `..` + --> $DIR/issue-72373.rs:5:19 + | +LL | [h, ref ts..] => foo(c, n - h) + foo(ts, n), + | ^^ expected one of `,`, `@`, `]`, or `|` + | +help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@` + | +LL | [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n), + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr index 60c2582b11eae..3bd85b083d002 100644 --- a/src/test/ui/json-short.stderr +++ b/src/test/ui/json-short.stderr @@ -1,5 +1,6 @@ -{"message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":"No `main` function was found in a binary crate. To fix this error, add a -`main` function. For example: +{"message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":"No `main` function was found in a binary crate. + +To fix this error, add a `main` function: ``` fn main() {