Skip to content

Commit a293a60

Browse files
committed
Merge from rustc
2 parents fa65ad2 + 07a7bec commit a293a60

File tree

27 files changed

+945
-735
lines changed

27 files changed

+945
-735
lines changed

alloc/src/boxed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl<T> Box<T> {
214214
#[inline(always)]
215215
#[stable(feature = "rust1", since = "1.0.0")]
216216
#[must_use]
217+
#[rustc_diagnostic_item = "box_new"]
217218
pub fn new(x: T) -> Self {
218219
#[rustc_box]
219220
Box::new(x)

alloc/src/collections/vec_deque/drain.rs

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,36 +52,22 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
5252
}
5353
}
5454

55-
// Only returns pointers to the slices, as that's
56-
// all we need to drop them. May only be called if `self.remaining != 0`.
55+
// Only returns pointers to the slices, as that's all we need
56+
// to drop them. May only be called if `self.remaining != 0`.
5757
unsafe fn as_slices(&self) -> (*mut [T], *mut [T]) {
5858
unsafe {
5959
let deque = self.deque.as_ref();
60-
// FIXME: This is doing almost exactly the same thing as the else branch in `VecDeque::slice_ranges`.
61-
// Unfortunately, we can't just call `slice_ranges` here, as the deque's `len` is currently
62-
// just `drain_start`, so the range check would (almost) always panic. Between temporarily
63-
// adjusting the deques `len` to call `slice_ranges`, and just copy pasting the `slice_ranges`
64-
// implementation, this seemed like the less hacky solution, though it might be good to
65-
// find a better one in the future.
66-
67-
// because `self.remaining != 0`, we know that `self.idx < deque.original_len`, so it's a valid
68-
// logical index.
69-
let wrapped_start = deque.to_physical_idx(self.idx);
70-
71-
let head_len = deque.capacity() - wrapped_start;
72-
73-
let (a_range, b_range) = if head_len >= self.remaining {
74-
(wrapped_start..wrapped_start + self.remaining, 0..0)
75-
} else {
76-
let tail_len = self.remaining - head_len;
77-
(wrapped_start..deque.capacity(), 0..tail_len)
78-
};
79-
80-
// SAFETY: the range `self.idx..self.idx+self.remaining` lies strictly inside
81-
// the range `0..deque.original_len`. because of this, and because of the fact
82-
// that we acquire `a_range` and `b_range` exactly like `slice_ranges` would,
83-
// it's guaranteed that `a_range` and `b_range` represent valid ranges into
84-
// the deques buffer.
60+
61+
// We know that `self.idx + self.remaining <= deque.len <= usize::MAX`, so this won't overflow.
62+
let logical_remaining_range = self.idx..self.idx + self.remaining;
63+
64+
// SAFETY: `logical_remaining_range` represents the
65+
// range into the logical buffer of elements that
66+
// haven't been drained yet, so they're all initialized,
67+
// and `slice::range(start..end, end) == start..end`,
68+
// so the preconditions for `slice_ranges` are met.
69+
let (a_range, b_range) =
70+
deque.slice_ranges(logical_remaining_range.clone(), logical_remaining_range.end);
8571
(deque.buffer_range(a_range), deque.buffer_range(b_range))
8672
}
8773
}

alloc/src/collections/vec_deque/mod.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
11561156
#[inline]
11571157
#[stable(feature = "deque_extras_15", since = "1.5.0")]
11581158
pub fn as_slices(&self) -> (&[T], &[T]) {
1159-
let (a_range, b_range) = self.slice_ranges(..);
1159+
let (a_range, b_range) = self.slice_ranges(.., self.len);
11601160
// SAFETY: `slice_ranges` always returns valid ranges into
11611161
// the physical buffer.
11621162
unsafe { (&*self.buffer_range(a_range), &*self.buffer_range(b_range)) }
@@ -1190,7 +1190,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
11901190
#[inline]
11911191
#[stable(feature = "deque_extras_15", since = "1.5.0")]
11921192
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
1193-
let (a_range, b_range) = self.slice_ranges(..);
1193+
let (a_range, b_range) = self.slice_ranges(.., self.len);
11941194
// SAFETY: `slice_ranges` always returns valid ranges into
11951195
// the physical buffer.
11961196
unsafe { (&mut *self.buffer_range(a_range), &mut *self.buffer_range(b_range)) }
@@ -1232,19 +1232,28 @@ impl<T, A: Allocator> VecDeque<T, A> {
12321232

12331233
/// Given a range into the logical buffer of the deque, this function
12341234
/// return two ranges into the physical buffer that correspond to
1235-
/// the given range.
1236-
fn slice_ranges<R>(&self, range: R) -> (Range<usize>, Range<usize>)
1235+
/// the given range. The `len` parameter should usually just be `self.len`;
1236+
/// the reason it's passed explicitly is that if the deque is wrapped in
1237+
/// a `Drain`, then `self.len` is not actually the length of the deque.
1238+
///
1239+
/// # Safety
1240+
///
1241+
/// This function is always safe to call. For the resulting ranges to be valid
1242+
/// ranges into the physical buffer, the caller must ensure that the result of
1243+
/// calling `slice::range(range, ..len)` represents a valid range into the
1244+
/// logical buffer, and that all elements in that range are initialized.
1245+
fn slice_ranges<R>(&self, range: R, len: usize) -> (Range<usize>, Range<usize>)
12371246
where
12381247
R: RangeBounds<usize>,
12391248
{
1240-
let Range { start, end } = slice::range(range, ..self.len);
1249+
let Range { start, end } = slice::range(range, ..len);
12411250
let len = end - start;
12421251

12431252
if len == 0 {
12441253
(0..0, 0..0)
12451254
} else {
1246-
// `slice::range` guarantees that `start <= end <= self.len`.
1247-
// because `len != 0`, we know that `start < end`, so `start < self.len`
1255+
// `slice::range` guarantees that `start <= end <= len`.
1256+
// because `len != 0`, we know that `start < end`, so `start < len`
12481257
// and the indexing is valid.
12491258
let wrapped_start = self.to_physical_idx(start);
12501259

@@ -1290,7 +1299,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
12901299
where
12911300
R: RangeBounds<usize>,
12921301
{
1293-
let (a_range, b_range) = self.slice_ranges(range);
1302+
let (a_range, b_range) = self.slice_ranges(range, self.len);
12941303
// SAFETY: The ranges returned by `slice_ranges`
12951304
// are valid ranges into the physical buffer, so
12961305
// it's ok to pass them to `buffer_range` and
@@ -1330,7 +1339,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
13301339
where
13311340
R: RangeBounds<usize>,
13321341
{
1333-
let (a_range, b_range) = self.slice_ranges(range);
1342+
let (a_range, b_range) = self.slice_ranges(range, self.len);
13341343
// SAFETY: The ranges returned by `slice_ranges`
13351344
// are valid ranges into the physical buffer, so
13361345
// it's ok to pass them to `buffer_range` and

alloc/src/rc.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,24 @@ impl<T> Rc<T> {
681681
Err(this)
682682
}
683683
}
684+
685+
/// Returns the inner value, if the `Rc` has exactly one strong reference.
686+
///
687+
/// Otherwise, [`None`] is returned and the `Rc` is dropped.
688+
///
689+
/// This will succeed even if there are outstanding weak references.
690+
///
691+
/// If `Rc::into_inner` is called on every clone of this `Rc`,
692+
/// it is guaranteed that exactly one of the calls returns the inner value.
693+
/// This means in particular that the inner value is not dropped.
694+
///
695+
/// This is equivalent to `Rc::try_unwrap(...).ok()`. (Note that these are not equivalent for
696+
/// `Arc`, due to race conditions that do not apply to `Rc`.)
697+
#[inline]
698+
#[unstable(feature = "rc_into_inner", issue = "106894")]
699+
pub fn into_inner(this: Self) -> Option<T> {
700+
Rc::try_unwrap(this).ok()
701+
}
684702
}
685703

686704
impl<T> Rc<[T]> {

alloc/src/rc/tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ fn try_unwrap() {
151151
assert_eq!(Rc::try_unwrap(x), Ok(5));
152152
}
153153

154+
#[test]
155+
fn into_inner() {
156+
let x = Rc::new(3);
157+
assert_eq!(Rc::into_inner(x), Some(3));
158+
159+
let x = Rc::new(4);
160+
let y = Rc::clone(&x);
161+
assert_eq!(Rc::into_inner(x), None);
162+
assert_eq!(Rc::into_inner(y), Some(4));
163+
164+
let x = Rc::new(5);
165+
let _w = Rc::downgrade(&x);
166+
assert_eq!(Rc::into_inner(x), Some(5));
167+
}
168+
154169
#[test]
155170
fn into_from_raw() {
156171
let x = Rc::new(Box::new("hello"));

alloc/src/sync.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,16 @@ mod tests;
5151
///
5252
/// Going above this limit will abort your program (although not
5353
/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
54+
/// Trying to go above it might call a `panic` (if not actually going above it).
55+
///
56+
/// This is a global invariant, and also applies when using a compare-exchange loop.
57+
///
58+
/// See comment in `Arc::clone`.
5459
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
5560

61+
/// The error in case either counter reaches above `MAX_REFCOUNT`, and we can `panic` safely.
62+
const INTERNAL_OVERFLOW_ERROR: &str = "Arc counter overflow";
63+
5664
#[cfg(not(sanitize = "thread"))]
5765
macro_rules! acquire {
5866
($x:expr) => {
@@ -1104,6 +1112,9 @@ impl<T: ?Sized> Arc<T> {
11041112
continue;
11051113
}
11061114

1115+
// We can't allow the refcount to increase much past `MAX_REFCOUNT`.
1116+
assert!(cur <= MAX_REFCOUNT, "{}", INTERNAL_OVERFLOW_ERROR);
1117+
11071118
// NOTE: this code currently ignores the possibility of overflow
11081119
// into usize::MAX; in general both Rc and Arc need to be adjusted
11091120
// to deal with overflow.
@@ -1519,6 +1530,11 @@ impl<T: ?Sized> Clone for Arc<T> {
15191530
// the worst already happened and we actually do overflow the `usize` counter. However, that
15201531
// requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment
15211532
// above and the `abort` below, which seems exceedingly unlikely.
1533+
//
1534+
// This is a global invariant, and also applies when using a compare-exchange loop to increment
1535+
// counters in other methods.
1536+
// Otherwise, the counter could be brought to an almost-overflow using a compare-exchange loop,
1537+
// and then overflow using a few `fetch_add`s.
15221538
if old_size > MAX_REFCOUNT {
15231539
abort();
15241540
}
@@ -2180,9 +2196,7 @@ impl<T: ?Sized> Weak<T> {
21802196
return None;
21812197
}
21822198
// See comments in `Arc::clone` for why we do this (for `mem::forget`).
2183-
if n > MAX_REFCOUNT {
2184-
abort();
2185-
}
2199+
assert!(n <= MAX_REFCOUNT, "{}", INTERNAL_OVERFLOW_ERROR);
21862200
Some(n + 1)
21872201
})
21882202
.ok()

alloc/src/tests.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use core::any::Any;
44
use core::clone::Clone;
55
use core::convert::TryInto;
66
use core::ops::Deref;
7-
use core::result::Result::{Err, Ok};
87

98
use std::boxed::Box;
109

@@ -15,32 +14,25 @@ fn test_owned_clone() {
1514
assert!(a == b);
1615
}
1716

18-
#[derive(PartialEq, Eq)]
17+
#[derive(Debug, PartialEq, Eq)]
1918
struct Test;
2019

2120
#[test]
2221
fn any_move() {
2322
let a = Box::new(8) as Box<dyn Any>;
2423
let b = Box::new(Test) as Box<dyn Any>;
2524

26-
match a.downcast::<i32>() {
27-
Ok(a) => {
28-
assert!(a == Box::new(8));
29-
}
30-
Err(..) => panic!(),
31-
}
32-
match b.downcast::<Test>() {
33-
Ok(a) => {
34-
assert!(a == Box::new(Test));
35-
}
36-
Err(..) => panic!(),
37-
}
25+
let a: Box<i32> = a.downcast::<i32>().unwrap();
26+
assert_eq!(*a, 8);
27+
28+
let b: Box<Test> = b.downcast::<Test>().unwrap();
29+
assert_eq!(*b, Test);
3830

3931
let a = Box::new(8) as Box<dyn Any>;
4032
let b = Box::new(Test) as Box<dyn Any>;
4133

42-
assert!(a.downcast::<Box<Test>>().is_err());
43-
assert!(b.downcast::<Box<i32>>().is_err());
34+
assert!(a.downcast::<Box<i32>>().is_err());
35+
assert!(b.downcast::<Box<Test>>().is_err());
4436
}
4537

4638
#[test]

core/src/cell.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ pub use once::OnceCell;
209209

210210
/// A mutable memory location.
211211
///
212+
/// # Memory layout
213+
///
214+
/// `Cell<T>` has the same [memory layout and caveats as
215+
/// `UnsafeCell<T>`](UnsafeCell#memory-layout). In particular, this means that
216+
/// `Cell<T>` has the same in-memory representation as its inner type `T`.
217+
///
212218
/// # Examples
213219
///
214220
/// In this example, you can see that `Cell<T>` enables mutation inside an

core/src/convert/num.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,18 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
172172
#[stable(feature = "float_from_bool", since = "1.68.0")]
173173
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
174174
impl const From<bool> for f32 {
175-
/// Converts `bool` to `f32` losslessly.
175+
/// Converts `bool` to `f32` losslessly. The resulting value is positive
176+
/// `0.0` for `false` and `1.0` for `true` values.
177+
///
178+
/// # Examples
179+
/// ```
180+
/// let x: f32 = false.into();
181+
/// assert_eq!(x, 0.0);
182+
/// assert!(x.is_sign_positive());
183+
///
184+
/// let y: f32 = true.into();
185+
/// assert_eq!(y, 1.0);
186+
/// ```
176187
#[inline]
177188
fn from(small: bool) -> Self {
178189
small as u8 as Self
@@ -181,7 +192,18 @@ impl const From<bool> for f32 {
181192
#[stable(feature = "float_from_bool", since = "1.68.0")]
182193
#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
183194
impl const From<bool> for f64 {
184-
/// Converts `bool` to `f64` losslessly.
195+
/// Converts `bool` to `f64` losslessly. The resulting value is positive
196+
/// `0.0` for `false` and `1.0` for `true` values.
197+
///
198+
/// # Examples
199+
/// ```
200+
/// let x: f64 = false.into();
201+
/// assert_eq!(x, 0.0);
202+
/// assert!(x.is_sign_positive());
203+
///
204+
/// let y: f64 = true.into();
205+
/// assert_eq!(y, 1.0);
206+
/// ```
185207
#[inline]
186208
fn from(small: bool) -> Self {
187209
small as u8 as Self

core/src/future/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,10 @@ pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
6767
unsafe { &mut *cx.0.as_ptr().cast() }
6868
}
6969

70-
// FIXME(swatinem): This fn is currently needed to work around shortcomings
71-
// in type and lifetime inference.
72-
// See the comment at the bottom of `LoweringContext::make_async_expr` and
73-
// <https://github.com/rust-lang/rust/issues/104826>.
7470
#[doc(hidden)]
7571
#[unstable(feature = "gen_future", issue = "50547")]
7672
#[inline]
77-
#[lang = "identity_future"]
73+
#[cfg_attr(bootstrap, lang = "identity_future")]
7874
pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
7975
f
8076
}

0 commit comments

Comments
 (0)