Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5430,9 +5430,9 @@ dependencies = [

[[package]]
name = "sysinfo"
version = "0.39.0"
version = "0.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd9f9fe3d2b7b75cf4f2805e5b9926e8ac47146667b16b86298c4a8bf08cc469"
checksum = "14311e7e9a03114cd4b65eedd54e8fed2945e17f08586ae97ef53bc0669f9581"
dependencies = [
"libc",
"objc2-core-foundation",
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/array/drain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ impl<'l, 'f, T, U, F: FnMut(T) -> U> Drain<'l, 'f, T, F> {
/// This function returns a function that lets you index the given array in const.
/// As implemented it can optimize better than iterators, and can be constified.
/// It acts like a sort of guard (owns the array) and iterator combined, which can be implemented
/// as it is a struct that implements const fn;
/// in that regard it is somewhat similar to an array::Iter implementing `UncheckedIterator`.
/// as it is a struct that implements const fn.
/// The only method you're really allowed to call is `next()`,
/// anything else is more or less UB, hence this function being unsafe.
/// Moved elements will not be dropped.
Expand Down
50 changes: 14 additions & 36 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::convert::Infallible;
use crate::error::Error;
use crate::hash::{self, Hash};
use crate::intrinsics::transmute_unchecked;
use crate::iter::{TrustedLen, UncheckedIterator, repeat_n};
use crate::iter::{TrustedLen, repeat_n};
use crate::marker::Destruct;
use crate::mem::{self, ManuallyDrop, MaybeUninit};
use crate::ops::{
Expand Down Expand Up @@ -52,7 +52,10 @@ pub use iter::IntoIter;
#[must_use = "cloning is often expensive and is not expected to have side effects"]
#[stable(feature = "array_repeat", since = "1.91.0")]
pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
from_trusted_iterator(repeat_n(val, N))
let mut iter = repeat_n(val, N);
// SAFETY: Unless a panic occurs, from_fn will call the closure N times,
// and repeat_n's next() will return Some for N times.
from_fn(move |_| unsafe { iter.next().unwrap_unchecked() })
}

/// Creates an array where each element is produced by calling `f` with
Expand Down Expand Up @@ -464,7 +467,15 @@ trait SpecArrayClone: Clone {
impl<T: Clone> SpecArrayClone for T {
#[inline]
default fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
from_trusted_iterator(array.iter().cloned())
let mut ptr: *const T = array.as_ptr();
// SAFETY: Unless a panic occurs, from_fn will call the closure N times,
// so our pointer arithmetic will be in bounds for the N-element array.
// This works even for ZSTs, since in that case, add() is a no-op.
from_fn(move |_| unsafe {
let old = ptr;
ptr = ptr.add(1);
(&*old).clone()
})
}
}

Expand Down Expand Up @@ -877,39 +888,6 @@ impl<T, const N: usize> [T; N] {
}
}

/// Populate an array from the first `N` elements of `iter`
///
/// # Panics
///
/// If the iterator doesn't actually have enough items.
///
/// By depending on `TrustedLen`, however, we can do that check up-front (where
/// it easily optimizes away) so it doesn't impact the loop that fills the array.
#[inline]
fn from_trusted_iterator<T, const N: usize>(iter: impl UncheckedIterator<Item = T>) -> [T; N] {
try_from_trusted_iterator(iter.map(NeverShortCircuit)).0
}

#[inline]
fn try_from_trusted_iterator<T, R, const N: usize>(
iter: impl UncheckedIterator<Item = R>,
) -> ChangeOutputType<R, [T; N]>
where
R: Try<Output = T>,
R::Residual: Residual<[T; N]>,
{
assert!(iter.size_hint().0 >= N);
fn next<T>(mut iter: impl UncheckedIterator<Item = T>) -> impl FnMut(usize) -> T {
move |_| {
// SAFETY: We know that `from_fn` will call this at most N times,
// and we checked to ensure that we have at least that many items.
unsafe { iter.next_unchecked() }
}
}

try_from_fn(next(iter))
}

/// Version of [`try_from_fn`] using a passed-in slice in order to avoid
/// needing to monomorphize for every array length.
///
Expand Down
15 changes: 1 addition & 14 deletions library/core/src/iter/adapters/cloned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::num::NonZero;

use crate::iter::adapters::zip::try_get_unchecked;
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::Try;

/// An iterator that clones the elements of an underlying iterator.
Expand Down Expand Up @@ -142,19 +142,6 @@ where
{
}

impl<'a, I, T: 'a> UncheckedIterator for Cloned<I>
where
I: UncheckedIterator<Item = &'a T>,
T: Clone,
{
unsafe fn next_unchecked(&mut self) -> T {
// SAFETY: `Cloned` is 1:1 with the inner iterator, so if the caller promised
// that there's an element left, the inner iterator has one too.
let item = unsafe { self.it.next_unchecked() };
item.clone()
}
}

#[stable(feature = "default_iters", since = "1.70.0")]
impl<I: Default> Default for Cloned<I> {
/// Creates a `Cloned` iterator from the default value of `I`
Expand Down
15 changes: 1 addition & 14 deletions library/core/src/iter/adapters/map.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::fmt;
use crate::iter::adapters::zip::try_get_unchecked;
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen, UncheckedIterator};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen};
use crate::num::NonZero;
use crate::ops::Try;

Expand Down Expand Up @@ -194,19 +194,6 @@ where
{
}

impl<B, I, F> UncheckedIterator for Map<I, F>
where
I: UncheckedIterator,
F: FnMut(I::Item) -> B,
{
unsafe fn next_unchecked(&mut self) -> B {
// SAFETY: `Map` is 1:1 with the inner iterator, so if the caller promised
// that there's an element left, the inner iterator has one too.
let item = unsafe { self.iter.next_unchecked() };
(self.f)(item)
}
}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I, F> TrustedRandomAccess for Map<I, F> where I: TrustedRandomAccess {}
Expand Down
11 changes: 1 addition & 10 deletions library/core/src/iter/adapters/zip.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::cmp;
use crate::fmt::{self, Debug};
use crate::iter::{
FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen, UncheckedIterator,
};
use crate::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen};
use crate::num::NonZero;

/// An iterator that iterates two other iterators simultaneously.
Expand Down Expand Up @@ -456,13 +454,6 @@ where
{
}

impl<A, B> UncheckedIterator for Zip<A, B>
where
A: UncheckedIterator,
B: UncheckedIterator,
{
}

// Arbitrarily selects the left side of the zip iteration as extractable "source"
// it would require negative trait bounds to be able to try both
#[unstable(issue = "none", feature = "inplace_iteration")]
Expand Down
1 change: 0 additions & 1 deletion library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,6 @@ pub use self::traits::TrustedFused;
pub use self::traits::TrustedLen;
#[unstable(feature = "trusted_step", issue = "85731")]
pub use self::traits::TrustedStep;
pub(crate) use self::traits::UncheckedIterator;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
Expand Down
4 changes: 1 addition & 3 deletions library/core/src/iter/sources/repeat_n.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::fmt;
use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
use crate::iter::{FusedIterator, TrustedLen};
use crate::num::NonZero;
use crate::ops::Try;

Expand Down Expand Up @@ -211,5 +211,3 @@ impl<A: Clone> FusedIterator for RepeatN<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
#[stable(feature = "iter_repeat_n", since = "1.82.0")]
impl<A: Clone> UncheckedIterator for RepeatN<A> {}
2 changes: 0 additions & 2 deletions library/core/src/iter/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ mod double_ended;
mod exact_size;
mod iterator;
mod marker;
mod unchecked_iterator;

#[unstable(issue = "none", feature = "inplace_iteration")]
pub use self::marker::InPlaceIterable;
#[unstable(issue = "none", feature = "trusted_fused")]
pub use self::marker::TrustedFused;
#[unstable(feature = "trusted_step", issue = "85731")]
pub use self::marker::TrustedStep;
pub(crate) use self::unchecked_iterator::UncheckedIterator;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::{
accum::{Product, Sum},
Expand Down
36 changes: 0 additions & 36 deletions library/core/src/iter/traits/unchecked_iterator.rs

This file was deleted.

2 changes: 2 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ macro_rules! uint_impl {
/// assert_eq!(n.extract_bits(0b0010_0100), 0b0000_0011);
/// assert_eq!(n.extract_bits(0xF0), 0b0000_1011);
/// ```
#[doc(alias = "pext")]
#[unstable(feature = "uint_gather_scatter_bits", issue = "149069")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand All @@ -727,6 +728,7 @@ macro_rules! uint_impl {
/// assert_eq!(n.deposit_bits(0b0101_0101), 0b0101_0001);
/// assert_eq!(n.deposit_bits(0xF0), 0b1101_0000);
/// ```
#[doc(alias = "pdep")]
#[unstable(feature = "uint_gather_scatter_bits", issue = "149069")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand Down
4 changes: 1 addition & 3 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ mod macros;

use super::{from_raw_parts, from_raw_parts_mut};
use crate::hint::assert_unchecked;
use crate::iter::{
FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator,
};
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
use crate::marker::PhantomData;
use crate::mem::{self, SizedTypeProperties};
use crate::num::NonZero;
Expand Down
12 changes: 1 addition & 11 deletions library/core/src/slice/iter/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ macro_rules! iterator {
// SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
unsafe {
self.post_inc_start(n);
Some(self.next_unchecked())
Some(self.post_inc_start(1).$into_ref())
}
}

Expand Down Expand Up @@ -481,16 +481,6 @@ macro_rules! iterator {
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for $name<'_, T> {}

impl<'a, T> UncheckedIterator for $name<'a, T> {
#[inline]
unsafe fn next_unchecked(&mut self) -> $elem {
// SAFETY: The caller promised there's at least one more item.
unsafe {
self.post_inc_start(1).$into_ref()
}
}
}

#[stable(feature = "default_iters", since = "1.70.0")]
impl<T> Default for $name<'_, T> {
/// Creates an empty slice iterator.
Expand Down
37 changes: 31 additions & 6 deletions library/core/src/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,25 +454,50 @@ impl Wtf8 {
#[track_caller]
#[inline]
pub fn check_utf8_boundary(&self, index: usize) {
let Err(err) = self.try_check_utf8_boundary(index) else { return };
match err {
Utf8BoundaryError::NotABoundary => {
panic!("byte index {index} is not a codepoint boundary")
}
Utf8BoundaryError::OutOfBounds => panic!("byte index {index} is out of bounds"),
Utf8BoundaryError::BetweenSurrogates => {
panic!("byte index {index} lies between surrogate codepoints")
}
}
}

#[track_caller]
#[inline]
pub fn try_check_utf8_boundary(&self, index: usize) -> Result<(), Utf8BoundaryError> {
if index == 0 {
return;
return Ok(());
}
match self.bytes.get(index) {
Some(0xED) => (), // Might be a surrogate
Some(&b) if (b as i8) >= -0x40 => return,
Some(_) => panic!("byte index {index} is not a codepoint boundary"),
None if index == self.len() => return,
None => panic!("byte index {index} is out of bounds"),
Some(&b) if (b as i8) >= -0x40 => return Ok(()),
Some(_) => return Err(Utf8BoundaryError::NotABoundary),
None if index == self.len() => return Ok(()),
None => return Err(Utf8BoundaryError::OutOfBounds),
}
if self.bytes[index + 1] >= 0xA0 {
// There's a surrogate after index. Now check before index.
if index >= 3 && self.bytes[index - 3] == 0xED && self.bytes[index - 2] >= 0xA0 {
panic!("byte index {index} lies between surrogate codepoints");
return Err(Utf8BoundaryError::BetweenSurrogates);
}
}
Ok(())
}
}

// This error type is only used temporarily to provide better panic messages
// It does not implement Error.
#[derive(Debug)]
pub enum Utf8BoundaryError {
NotABoundary,
OutOfBounds,
BetweenSurrogates,
}

/// Copied from core::str::raw::slice_unchecked
#[inline]
unsafe fn slice_unchecked(s: &Wtf8, begin: usize, end: usize) -> &Wtf8 {
Expand Down
Loading
Loading