Auto merge of #72727 - JohnTitor:rollup-nni16m2, r=JohnTitor

Rollup of 11 pull requests

Successful merges:

 - #71633 (Impl Error for Infallible)
 - #71843 (Tweak and stabilize AtomicN::fetch_update)
 - #72288 (Stabilization of weak-into-raw)
 - #72324 (Stabilize AtomicN::fetch_min and AtomicN::fetch_max)
 - #72452 (Clarified the documentation for Formatter::precision)
 - #72495 (Improve E0601 explanation)
 - #72534 (Improve missing `@` in slice binding pattern diagnostics)
 - #72547 (Added a codegen test for a recent optimization for overflow-checks=on)
 - #72711 (remove redundant `mk_const`)
 - #72713 (Whitelist #[allow_internal_unstable])
 - #72720 (Clarify the documentation of `take`)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-05-29 07:52:06 +00:00
commit 77f95a89a1
14 changed files with 112 additions and 57 deletions

View File

@ -580,8 +580,6 @@ impl<T: ?Sized> Rc<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::Rc; /// use std::rc::Rc;
/// ///
/// let x = Rc::new("hello".to_owned()); /// let x = Rc::new("hello".to_owned());
@ -590,7 +588,7 @@ impl<T: ?Sized> Rc<T> {
/// assert_eq!(x_ptr, Rc::as_ptr(&y)); /// assert_eq!(x_ptr, Rc::as_ptr(&y));
/// assert_eq!(unsafe { &*x_ptr }, "hello"); /// 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 { pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr); let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T; let fake_ptr = ptr as *mut T;
@ -1681,8 +1679,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::Rc; /// use std::rc::Rc;
/// use std::ptr; /// use std::ptr;
/// ///
@ -1700,7 +1696,7 @@ impl<T> Weak<T> {
/// ``` /// ```
/// ///
/// [`null`]: ../../std/ptr/fn.null.html /// [`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 { pub fn as_ptr(&self) -> *const T {
let offset = data_offset_sized::<T>(); let offset = data_offset_sized::<T>();
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset); let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
@ -1718,8 +1714,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::{Rc, Weak}; /// use std::rc::{Rc, Weak};
/// ///
/// let strong = Rc::new("hello".to_owned()); /// let strong = Rc::new("hello".to_owned());
@ -1735,7 +1729,7 @@ impl<T> Weak<T> {
/// ///
/// [`from_raw`]: struct.Weak.html#method.from_raw /// [`from_raw`]: struct.Weak.html#method.from_raw
/// [`as_ptr`]: struct.Weak.html#method.as_ptr /// [`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 { pub fn into_raw(self) -> *const T {
let result = self.as_ptr(); let result = self.as_ptr();
mem::forget(self); mem::forget(self);
@ -1762,8 +1756,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::{Rc, Weak}; /// use std::rc::{Rc, Weak};
/// ///
/// let strong = Rc::new("hello".to_owned()); /// let strong = Rc::new("hello".to_owned());
@ -1788,7 +1780,7 @@ impl<T> Weak<T> {
/// [`Weak`]: struct.Weak.html /// [`Weak`]: struct.Weak.html
/// [`new`]: struct.Weak.html#method.new /// [`new`]: struct.Weak.html#method.new
/// [`forget`]: ../../std/mem/fn.forget.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 { pub unsafe fn from_raw(ptr: *const T) -> Self {
if ptr.is_null() { if ptr.is_null() {
Self::new() Self::new()

View File

@ -579,8 +579,6 @@ impl<T: ?Sized> Arc<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::sync::Arc; /// use std::sync::Arc;
/// ///
/// let x = Arc::new("hello".to_owned()); /// let x = Arc::new("hello".to_owned());
@ -589,7 +587,7 @@ impl<T: ?Sized> Arc<T> {
/// assert_eq!(x_ptr, Arc::as_ptr(&y)); /// assert_eq!(x_ptr, Arc::as_ptr(&y));
/// assert_eq!(unsafe { &*x_ptr }, "hello"); /// 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 { pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr); let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T; let fake_ptr = ptr as *mut T;
@ -1449,8 +1447,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::sync::Arc; /// use std::sync::Arc;
/// use std::ptr; /// use std::ptr;
/// ///
@ -1468,7 +1464,7 @@ impl<T> Weak<T> {
/// ``` /// ```
/// ///
/// [`null`]: ../../std/ptr/fn.null.html /// [`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 { pub fn as_ptr(&self) -> *const T {
let offset = data_offset_sized::<T>(); let offset = data_offset_sized::<T>();
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset); let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
@ -1486,8 +1482,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::sync::{Arc, Weak}; /// use std::sync::{Arc, Weak};
/// ///
/// let strong = Arc::new("hello".to_owned()); /// let strong = Arc::new("hello".to_owned());
@ -1503,7 +1497,7 @@ impl<T> Weak<T> {
/// ///
/// [`from_raw`]: struct.Weak.html#method.from_raw /// [`from_raw`]: struct.Weak.html#method.from_raw
/// [`as_ptr`]: struct.Weak.html#method.as_ptr /// [`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 { pub fn into_raw(self) -> *const T {
let result = self.as_ptr(); let result = self.as_ptr();
mem::forget(self); mem::forget(self);
@ -1531,8 +1525,6 @@ impl<T> Weak<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(weak_into_raw)]
///
/// use std::sync::{Arc, Weak}; /// use std::sync::{Arc, Weak};
/// ///
/// let strong = Arc::new("hello".to_owned()); /// let strong = Arc::new("hello".to_owned());
@ -1557,7 +1549,7 @@ impl<T> Weak<T> {
/// [`Weak`]: struct.Weak.html /// [`Weak`]: struct.Weak.html
/// [`Arc`]: struct.Arc.html /// [`Arc`]: struct.Arc.html
/// [`forget`]: ../../std/mem/fn.forget.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 { pub unsafe fn from_raw(ptr: *const T) -> Self {
if ptr.is_null() { if ptr.is_null() {
Self::new() Self::new()

View File

@ -1618,7 +1618,8 @@ impl<'a> Formatter<'a> {
self.width self.width
} }
/// Optionally specified precision for numeric types. /// Optionally specified precision for numeric types. Alternatively, the
/// maximum width for string types.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -1180,6 +1180,17 @@ pub trait Iterator {
/// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), Some(2));
/// assert_eq!(iter.next(), None); /// 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] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn take(self, n: usize) -> Take<Self> fn take(self, n: usize) -> Take<Self>

View File

@ -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 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 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 `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
ordering of this operation. The first describes the required ordering for loads The first describes the required ordering for when the operation finally succeeds while the second
and failed updates while the second describes the required ordering when the describes the required ordering for loads. These correspond to the success and failure orderings of
operation finally succeeds. Beware that this is different from the two [`compare_exchange`] respectively.
modes in [`compare_exchange`]!
Using [`Acquire`] as success ordering makes the store part Using [`Acquire`] as success ordering makes the store part
of this operation [`Relaxed`], and using [`Release`] makes the final successful load 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 # Examples
```rust ```rust
#![feature(no_more_cas)]
", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
let x = ", stringify!($atomic_type), "::new(7); let x = ", stringify!($atomic_type), "::new(7);
assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7)); assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7)); assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), 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, |x| Some(x + 1)), Ok(8));
assert_eq!(x.load(Ordering::SeqCst), 9); assert_eq!(x.load(Ordering::SeqCst), 9);
```"), ```"),
#[inline] #[inline]
#[unstable(feature = "no_more_cas", #[stable(feature = "no_more_cas", since = "1.45.0")]
reason = "no more CAS loops in user code",
issue = "48655")]
#[$cfg_cas] #[$cfg_cas]
pub fn fetch_update<F>(&self, pub fn fetch_update<F>(&self,
mut f: F, set_order: Ordering,
fetch_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> { where F: FnMut($int_type) -> Option<$int_type> {
let mut prev = self.load(fetch_order); let mut prev = self.load(fetch_order);
while let Some(next) = f(prev) { while let Some(next) = f(prev) {
@ -1882,7 +1878,6 @@ using [`Release`] makes the load part [`Relaxed`].
# Examples # Examples
``` ```
#![feature(atomic_min_max)]
", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
let foo = ", stringify!($atomic_type), "::new(23); 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: 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}; ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
let foo = ", stringify!($atomic_type), "::new(23); 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); assert!(max_foo == 42);
```"), ```"),
#[inline] #[inline]
#[unstable(feature = "atomic_min_max", #[stable(feature = "atomic_min_max", since = "1.45.0")]
reason = "easier and faster min/max than writing manual CAS loop",
issue = "48655")]
#[$cfg_cas] #[$cfg_cas]
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
// SAFETY: data races are prevented by atomic intrinsics. // SAFETY: data races are prevented by atomic intrinsics.
@ -1933,7 +1925,6 @@ using [`Release`] makes the load part [`Relaxed`].
# Examples # Examples
``` ```
#![feature(atomic_min_max)]
", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
let foo = ", stringify!($atomic_type), "::new(23); 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: 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}; ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
let foo = ", stringify!($atomic_type), "::new(23); 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); assert_eq!(min_foo, 12);
```"), ```"),
#[inline] #[inline]
#[unstable(feature = "atomic_min_max", #[stable(feature = "atomic_min_max", since = "1.45.0")]
reason = "easier and faster min/max than writing manual CAS loop",
issue = "48655")]
#[$cfg_cas] #[$cfg_cas]
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
// SAFETY: data races are prevented by atomic intrinsics. // SAFETY: data races are prevented by atomic intrinsics.

View File

@ -1,5 +1,6 @@
No `main` function was found in a binary crate. To fix this error, add a No `main` function was found in a binary crate.
`main` function. For example:
To fix this error, add a `main` function:
``` ```
fn main() { fn main() {

View File

@ -366,7 +366,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// FIXME(#14407) // FIXME(#14407)
ungated!(rustc_const_stable, Whitelisted, template!(List: r#"feature = "name""#)), ungated!(rustc_const_stable, Whitelisted, template!(List: r#"feature = "name""#)),
gated!( 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", "allow_internal_unstable side-steps feature gating and stability checks",
), ),
gated!( gated!(

View File

@ -606,7 +606,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Operand::Constant(Box::new(Constant { Operand::Constant(Box::new(Constant {
span, span,
user_ty: None, 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),
})) }))
} }

View File

@ -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. // Attempt to keep parsing if it was an omitted separator.
match f(self) { match f(self) {
Ok(t) => { Ok(t) => {

View File

@ -14,6 +14,7 @@
// reconsider what crate these items belong in. // reconsider what crate these items belong in.
use core::array; use core::array;
use core::convert::Infallible;
use crate::alloc::{AllocErr, LayoutErr}; use crate::alloc::{AllocErr, LayoutErr};
use crate::any::TypeId; use crate::any::TypeId;
@ -474,7 +475,7 @@ impl Error for string::FromUtf16Error {
} }
#[stable(feature = "str_parse_error2", since = "1.8.0")] #[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError { impl Error for Infallible {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self {} match *self {}
} }

View File

@ -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]
}

View File

@ -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,
}
}

View File

@ -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

View File

@ -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 {"message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":"No `main` function was found in a binary crate.
`main` function. For example:
To fix this error, add a `main` function:
``` ```
fn main() { fn main() {