Skip to content

Commit 5fae569

Browse files
committed
Auto merge of #76781 - RalfJung:rollup-ve66o2j, r=RalfJung
Rollup of 10 pull requests Successful merges: - #76056 (Add more info for Vec Drain doc) - #76062 (Vec slice example fix style and show type elision) - #76262 (Use inline(never) instead of cold) - #76335 (Make all methods of `Duration` unstably const) - #76366 (Add Arith Tests in Library) - #76369 (Move Various str tests in library) - #76534 (Add doc comments for From impls) - #76622 (Update bootstrap readme) - #76641 (Some cleanup changes and commenting) - #76662 (Fix liballoc test suite for Miri) Failed merges: r? `@ghost`
2 parents 1e11660 + 9d0a265 commit 5fae569

File tree

26 files changed

+292
-274
lines changed

26 files changed

+292
-274
lines changed

compiler/rustc_middle/src/ty/sty.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2280,6 +2280,12 @@ impl<'tcx> TyS<'tcx> {
22802280
///
22812281
/// Returning true means the type is known to be sized. Returning
22822282
/// `false` means nothing -- could be sized, might not be.
2283+
///
2284+
/// Note that we could never rely on the fact that a type such as `[_]` is
2285+
/// trivially `!Sized` because we could be in a type environment with a
2286+
/// bound such as `[_]: Copy`. A function with such a bound obviously never
2287+
/// can be called, but that doesn't mean it shouldn't typecheck. This is why
2288+
/// this method doesn't return `Option<bool>`.
22832289
pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
22842290
match self.kind() {
22852291
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1512,12 +1512,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15121512
// avoid inundating the user with unnecessary errors, but we now
15131513
// check upstream for type errors and don't add the obligations to
15141514
// begin with in those cases.
1515-
if self
1516-
.tcx
1517-
.lang_items()
1518-
.sized_trait()
1519-
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
1520-
{
1515+
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
15211516
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
15221517
return;
15231518
}

compiler/rustc_traits/src/chalk/db.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,15 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
110110
.map(|i| chalk_ir::AssocTypeId(i.def_id))
111111
.collect();
112112

113-
let well_known = if self
114-
.interner
115-
.tcx
116-
.lang_items()
117-
.sized_trait()
118-
.map(|t| def_id == t)
119-
.unwrap_or(false)
120-
{
113+
let well_known = if self.interner.tcx.lang_items().sized_trait() == Some(def_id) {
121114
Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
122-
} else if self.interner.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false)
123-
{
115+
} else if self.interner.tcx.lang_items().copy_trait() == Some(def_id) {
124116
Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
125-
} else if self.interner.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false)
126-
{
117+
} else if self.interner.tcx.lang_items().clone_trait() == Some(def_id) {
127118
Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
128-
} else if self.interner.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false)
129-
{
119+
} else if self.interner.tcx.lang_items().drop_trait() == Some(def_id) {
130120
Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
131-
} else if self.interner.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) {
121+
} else if self.interner.tcx.lang_items().fn_trait() == Some(def_id) {
132122
Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
133123
} else if self
134124
.interner

library/alloc/src/collections/binary_heap.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,10 @@ impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
13431343

13441344
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
13451345
impl<T> From<BinaryHeap<T>> for Vec<T> {
1346+
/// Converts a `BinaryHeap<T>` into a `Vec<T>`.
1347+
///
1348+
/// This conversion requires no data movement or allocation, and has
1349+
/// constant time complexity.
13461350
fn from(heap: BinaryHeap<T>) -> Vec<T> {
13471351
heap.data
13481352
}

library/alloc/src/collections/vec_deque.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1089,11 +1089,7 @@ impl<T> VecDeque<T> {
10891089
where
10901090
R: RangeBounds<usize>,
10911091
{
1092-
// SAFETY: This buffer is only used to check the range. It might be partially
1093-
// uninitialized, but `check_range` needs a contiguous slice.
1094-
// https://github.com/rust-lang/rust/pull/75207#discussion_r471193682
1095-
let buffer = unsafe { slice::from_raw_parts(self.ptr(), self.len()) };
1096-
let Range { start, end } = buffer.check_range(range);
1092+
let Range { start, end } = slice::check_range(self.len(), range);
10971093
let tail = self.wrap_add(self.tail, start);
10981094
let head = self.wrap_add(self.tail, end);
10991095
(tail, head)

library/alloc/src/slice.rs

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ use crate::borrow::ToOwned;
9191
use crate::boxed::Box;
9292
use crate::vec::Vec;
9393

94+
#[unstable(feature = "slice_check_range", issue = "76393")]
95+
pub use core::slice::check_range;
9496
#[unstable(feature = "array_chunks", issue = "74985")]
9597
pub use core::slice::ArrayChunks;
9698
#[unstable(feature = "array_chunks", issue = "74985")]

library/alloc/src/string.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use core::iter::{FromIterator, FusedIterator};
4949
use core::ops::Bound::{Excluded, Included, Unbounded};
5050
use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds};
5151
use core::ptr;
52+
use core::slice;
5253
use core::str::{lossy, pattern::Pattern};
5354

5455
use crate::borrow::{Cow, ToOwned};
@@ -1506,7 +1507,7 @@ impl String {
15061507
// of the vector version. The data is just plain bytes.
15071508
// Because the range removal happens in Drop, if the Drain iterator is leaked,
15081509
// the removal will not happen.
1509-
let Range { start, end } = self.as_bytes().check_range(range);
1510+
let Range { start, end } = slice::check_range(self.len(), range);
15101511
assert!(self.is_char_boundary(start));
15111512
assert!(self.is_char_boundary(end));
15121513

library/alloc/src/vec.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ use crate::raw_vec::RawVec;
174174
///
175175
/// // ... and that's all!
176176
/// // you can also do it like this:
177-
/// let x : &[usize] = &v;
177+
/// let u: &[usize] = &v;
178+
/// // or like this:
179+
/// let u: &[_] = &v;
178180
/// ```
179181
///
180182
/// In Rust, it's more common to pass slices as arguments rather than vectors
@@ -1310,7 +1312,7 @@ impl<T> Vec<T> {
13101312
// the hole, and the vector length is restored to the new length.
13111313
//
13121314
let len = self.len();
1313-
let Range { start, end } = self.check_range(range);
1315+
let Range { start, end } = slice::check_range(len, range);
13141316

13151317
unsafe {
13161318
// set self.vec length's to start, to be safe in case Drain is leaked
@@ -3037,6 +3039,7 @@ impl<T> AsIntoIter for IntoIter<T> {
30373039
/// A draining iterator for `Vec<T>`.
30383040
///
30393041
/// This `struct` is created by [`Vec::drain`].
3042+
/// See its documentation for more.
30403043
#[stable(feature = "drain", since = "1.6.0")]
30413044
pub struct Drain<'a, T: 'a> {
30423045
/// Index of tail to preserve

library/alloc/tests/str.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1921,3 +1921,24 @@ fn different_str_pattern_forwarding_lifetimes() {
19211921

19221922
foo::<&str>("x");
19231923
}
1924+
1925+
#[test]
1926+
fn test_str_multiline() {
1927+
let a: String = "this \
1928+
is a test"
1929+
.to_string();
1930+
let b: String = "this \
1931+
is \
1932+
another \
1933+
test"
1934+
.to_string();
1935+
assert_eq!(a, "this is a test".to_string());
1936+
assert_eq!(b, "this is another test".to_string());
1937+
}
1938+
1939+
#[test]
1940+
fn test_str_escapes() {
1941+
let x = "\\\\\
1942+
";
1943+
assert_eq!(x, r"\\"); // extraneous whitespace stripped
1944+
}

library/alloc/tests/vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ fn test_from_iter_partially_drained_in_place_specialization() {
919919
#[test]
920920
fn test_from_iter_specialization_with_iterator_adapters() {
921921
fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {};
922-
let src: Vec<usize> = vec![0usize; 65535];
922+
let src: Vec<usize> = vec![0usize; 256];
923923
let srcptr = src.as_ptr();
924924
let iter = src
925925
.into_iter()

library/core/src/slice/index.rs

+74-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Indexing implementations for `[T]`.
22
3-
use crate::ops;
3+
use crate::ops::{self, Bound, Range, RangeBounds};
44
use crate::ptr;
55

66
#[stable(feature = "rust1", since = "1.0.0")]
@@ -62,6 +62,79 @@ pub(super) fn slice_end_index_overflow_fail() -> ! {
6262
panic!("attempted to index slice up to maximum usize");
6363
}
6464

65+
/// Performs bounds-checking of the given range.
66+
/// The returned [`Range`] is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]
67+
/// for slices of the given length.
68+
///
69+
/// [`get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
70+
/// [`get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
71+
///
72+
/// # Panics
73+
///
74+
/// Panics if the range is out of bounds.
75+
///
76+
/// # Examples
77+
///
78+
/// ```
79+
/// #![feature(slice_check_range)]
80+
/// use std::slice;
81+
///
82+
/// let v = [10, 40, 30];
83+
/// assert_eq!(1..2, slice::check_range(v.len(), 1..2));
84+
/// assert_eq!(0..2, slice::check_range(v.len(), ..2));
85+
/// assert_eq!(1..3, slice::check_range(v.len(), 1..));
86+
/// ```
87+
///
88+
/// Panics when [`Index::index`] would panic:
89+
///
90+
/// ```should_panic
91+
/// #![feature(slice_check_range)]
92+
///
93+
/// std::slice::check_range(3, 2..1);
94+
/// ```
95+
///
96+
/// ```should_panic
97+
/// #![feature(slice_check_range)]
98+
///
99+
/// std::slice::check_range(3, 1..4);
100+
/// ```
101+
///
102+
/// ```should_panic
103+
/// #![feature(slice_check_range)]
104+
///
105+
/// std::slice::check_range(3, 1..=usize::MAX);
106+
/// ```
107+
///
108+
/// [`Index::index`]: ops::Index::index
109+
#[track_caller]
110+
#[unstable(feature = "slice_check_range", issue = "76393")]
111+
pub fn check_range<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> {
112+
let start = match range.start_bound() {
113+
Bound::Included(&start) => start,
114+
Bound::Excluded(start) => {
115+
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
116+
}
117+
Bound::Unbounded => 0,
118+
};
119+
120+
let end = match range.end_bound() {
121+
Bound::Included(end) => {
122+
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
123+
}
124+
Bound::Excluded(&end) => end,
125+
Bound::Unbounded => len,
126+
};
127+
128+
if start > end {
129+
slice_index_order_fail(start, end);
130+
}
131+
if end > len {
132+
slice_end_index_len_fail(end, len);
133+
}
134+
135+
Range { start, end }
136+
}
137+
65138
mod private_slice_index {
66139
use super::ops;
67140
#[stable(feature = "slice_get_slice", since = "1.28.0")]

library/core/src/slice/mod.rs

+4-77
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less};
1212
use crate::intrinsics::assume;
1313
use crate::marker::{self, Copy};
1414
use crate::mem;
15-
use crate::ops::{Bound, FnMut, Range, RangeBounds};
15+
use crate::ops::{FnMut, Range, RangeBounds};
1616
use crate::option::Option;
1717
use crate::option::Option::{None, Some};
1818
use crate::ptr::{self, NonNull};
@@ -72,8 +72,8 @@ pub use sort::heapsort;
7272
#[stable(feature = "slice_get_slice", since = "1.28.0")]
7373
pub use index::SliceIndex;
7474

75-
use index::{slice_end_index_len_fail, slice_index_order_fail};
76-
use index::{slice_end_index_overflow_fail, slice_start_index_overflow_fail};
75+
#[unstable(feature = "slice_check_range", issue = "76393")]
76+
pub use index::check_range;
7777

7878
#[lang = "slice"]
7979
#[cfg(not(test))]
@@ -378,79 +378,6 @@ impl<T> [T] {
378378
unsafe { &mut *index.get_unchecked_mut(self) }
379379
}
380380

381-
/// Converts a range over this slice to [`Range`].
382-
///
383-
/// The returned range is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`].
384-
///
385-
/// [`get_unchecked`]: #method.get_unchecked
386-
/// [`get_unchecked_mut`]: #method.get_unchecked_mut
387-
///
388-
/// # Panics
389-
///
390-
/// Panics if the range is out of bounds.
391-
///
392-
/// # Examples
393-
///
394-
/// ```
395-
/// #![feature(slice_check_range)]
396-
///
397-
/// let v = [10, 40, 30];
398-
/// assert_eq!(1..2, v.check_range(1..2));
399-
/// assert_eq!(0..2, v.check_range(..2));
400-
/// assert_eq!(1..3, v.check_range(1..));
401-
/// ```
402-
///
403-
/// Panics when [`Index::index`] would panic:
404-
///
405-
/// ```should_panic
406-
/// #![feature(slice_check_range)]
407-
///
408-
/// [10, 40, 30].check_range(2..1);
409-
/// ```
410-
///
411-
/// ```should_panic
412-
/// #![feature(slice_check_range)]
413-
///
414-
/// [10, 40, 30].check_range(1..4);
415-
/// ```
416-
///
417-
/// ```should_panic
418-
/// #![feature(slice_check_range)]
419-
///
420-
/// [10, 40, 30].check_range(1..=usize::MAX);
421-
/// ```
422-
///
423-
/// [`Index::index`]: crate::ops::Index::index
424-
#[track_caller]
425-
#[unstable(feature = "slice_check_range", issue = "76393")]
426-
pub fn check_range<R: RangeBounds<usize>>(&self, range: R) -> Range<usize> {
427-
let start = match range.start_bound() {
428-
Bound::Included(&start) => start,
429-
Bound::Excluded(start) => {
430-
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
431-
}
432-
Bound::Unbounded => 0,
433-
};
434-
435-
let len = self.len();
436-
let end = match range.end_bound() {
437-
Bound::Included(end) => {
438-
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
439-
}
440-
Bound::Excluded(&end) => end,
441-
Bound::Unbounded => len,
442-
};
443-
444-
if start > end {
445-
slice_index_order_fail(start, end);
446-
}
447-
if end > len {
448-
slice_end_index_len_fail(end, len);
449-
}
450-
451-
Range { start, end }
452-
}
453-
454381
/// Returns a raw pointer to the slice's buffer.
455382
///
456383
/// The caller must ensure that the slice outlives the pointer this
@@ -2794,7 +2721,7 @@ impl<T> [T] {
27942721
where
27952722
T: Copy,
27962723
{
2797-
let Range { start: src_start, end: src_end } = self.check_range(src);
2724+
let Range { start: src_start, end: src_end } = check_range(self.len(), src);
27982725
let count = src_end - src_start;
27992726
assert!(dest <= self.len() - count, "dest is out of bounds");
28002727
// SAFETY: the conditions for `ptr::copy` have all been checked above,

library/core/src/task/poll.rs

+8
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ impl<T, E> Poll<Option<Result<T, E>>> {
112112

113113
#[stable(feature = "futures_api", since = "1.36.0")]
114114
impl<T> From<T> for Poll<T> {
115+
/// Convert to a `Ready` variant.
116+
///
117+
/// # Example
118+
///
119+
/// ```
120+
/// # use core::task::Poll;
121+
/// assert_eq!(Poll::from(true), Poll::Ready(true));
122+
/// ```
115123
fn from(t: T) -> Poll<T> {
116124
Poll::Ready(t)
117125
}

0 commit comments

Comments
 (0)