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:
commit
77f95a89a1
14 changed files with 112 additions and 57 deletions
|
@ -580,8 +580,6 @@ impl<T: ?Sized> Rc<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// 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!(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<T> = NonNull::as_ptr(this.ptr);
|
||||
let fake_ptr = ptr as *mut T;
|
||||
|
@ -1681,8 +1679,6 @@ impl<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::rc::Rc;
|
||||
/// use std::ptr;
|
||||
///
|
||||
|
@ -1700,7 +1696,7 @@ impl<T> Weak<T> {
|
|||
/// ```
|
||||
///
|
||||
/// [`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::<T>();
|
||||
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
|
||||
|
@ -1718,8 +1714,6 @@ impl<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::rc::{Rc, Weak};
|
||||
///
|
||||
/// let strong = Rc::new("hello".to_owned());
|
||||
|
@ -1735,7 +1729,7 @@ impl<T> Weak<T> {
|
|||
///
|
||||
/// [`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<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::rc::{Rc, Weak};
|
||||
///
|
||||
/// let strong = Rc::new("hello".to_owned());
|
||||
|
@ -1788,7 +1780,7 @@ impl<T> Weak<T> {
|
|||
/// [`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()
|
||||
|
|
|
@ -579,8 +579,6 @@ impl<T: ?Sized> Arc<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::sync::Arc;
|
||||
///
|
||||
/// 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!(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<T> = NonNull::as_ptr(this.ptr);
|
||||
let fake_ptr = ptr as *mut T;
|
||||
|
@ -1449,8 +1447,6 @@ impl<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::sync::Arc;
|
||||
/// use std::ptr;
|
||||
///
|
||||
|
@ -1468,7 +1464,7 @@ impl<T> Weak<T> {
|
|||
/// ```
|
||||
///
|
||||
/// [`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::<T>();
|
||||
let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
|
||||
|
@ -1486,8 +1482,6 @@ impl<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::sync::{Arc, Weak};
|
||||
///
|
||||
/// let strong = Arc::new("hello".to_owned());
|
||||
|
@ -1503,7 +1497,7 @@ impl<T> Weak<T> {
|
|||
///
|
||||
/// [`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<T> Weak<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(weak_into_raw)]
|
||||
///
|
||||
/// use std::sync::{Arc, Weak};
|
||||
///
|
||||
/// let strong = Arc::new("hello".to_owned());
|
||||
|
@ -1557,7 +1549,7 @@ impl<T> Weak<T> {
|
|||
/// [`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()
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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<Self>
|
||||
|
|
|
@ -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<F>(&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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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),
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
|
|
26
src/test/codegen/integer-overflow.rs
Normal file
26
src/test/codegen/integer-overflow.rs
Normal 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]
|
||||
}
|
9
src/test/ui/issues/issue-72373.rs
Normal file
9
src/test/ui/issues/issue-72373.rs
Normal 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,
|
||||
}
|
||||
}
|
13
src/test/ui/issues/issue-72373.stderr
Normal file
13
src/test/ui/issues/issue-72373.stderr
Normal 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
|
||||
|
|
@ -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() {
|
||||
|
|
Loading…
Add table
Reference in a new issue