diff --git a/core/src/iter/sources/repeat.rs b/core/src/iter/sources/repeat.rs index 4bcd5b16aea6a..7fcd6f8963a48 100644 --- a/core/src/iter/sources/repeat.rs +++ b/core/src/iter/sources/repeat.rs @@ -8,6 +8,9 @@ use crate::num::NonZero; /// Infinite iterators like `repeat()` are often used with adapters like /// [`Iterator::take()`], in order to make them finite. /// +/// If you know the number of repetitions in advance, consider using [`repeat_n()`] +/// instead, as it is more efficient and conveys the intent more clearly. +/// /// Use [`str::repeat()`] instead of this function if you just want to repeat /// a char/string `n` times. /// @@ -15,6 +18,7 @@ use crate::num::NonZero; /// or if you do not want to keep the repeated element in memory, you can /// instead use the [`repeat_with()`] function. /// +/// [`repeat_n()`]: crate::iter::repeat_n /// [`repeat_with()`]: crate::iter::repeat_with /// [`str::repeat()`]: ../../std/primitive.str.html#method.repeat /// diff --git a/core/src/num/f128.rs b/core/src/num/f128.rs index 4fe4735e304c9..e7101537b298f 100644 --- a/core/src/num/f128.rs +++ b/core/src/num/f128.rs @@ -18,6 +18,7 @@ use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f128", issue = "116909")] +#[rustc_diagnostic_item = "f128_consts_mod"] pub mod consts { // FIXME: replace with mathematical constants from cmath. diff --git a/core/src/num/f16.rs b/core/src/num/f16.rs index 0bea6bc8801d8..aa8342a22ad58 100644 --- a/core/src/num/f16.rs +++ b/core/src/num/f16.rs @@ -20,6 +20,7 @@ use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f16", issue = "116909")] +#[rustc_diagnostic_item = "f16_consts_mod"] pub mod consts { // FIXME: replace with mathematical constants from cmath. diff --git a/core/src/num/f32.rs b/core/src/num/f32.rs index e380cc698f574..3070e1dedbe43 100644 --- a/core/src/num/f32.rs +++ b/core/src/num/f32.rs @@ -277,6 +277,7 @@ pub const NEG_INFINITY: f32 = f32::NEG_INFINITY; /// Basic mathematical constants. #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "f32_consts_mod"] pub mod consts { // FIXME: replace with mathematical constants from cmath. diff --git a/core/src/num/f64.rs b/core/src/num/f64.rs index ff7449fd996ce..dc8ccc551b2da 100644 --- a/core/src/num/f64.rs +++ b/core/src/num/f64.rs @@ -277,6 +277,7 @@ pub const NEG_INFINITY: f64 = f64::NEG_INFINITY; /// Basic mathematical constants. #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "f64_consts_mod"] pub mod consts { // FIXME: replace with mathematical constants from cmath. diff --git a/core/src/panicking.rs b/core/src/panicking.rs index b5150837e6a94..448f4ffc3dae0 100644 --- a/core/src/panicking.rs +++ b/core/src/panicking.rs @@ -36,7 +36,8 @@ use crate::panic::{Location, PanicInfo}; compile_error!( "panic_immediate_abort is now a real panic strategy! \ Enable it with `panic = \"immediate-abort\"` in Cargo.toml, \ - or with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`" + or with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`. \ + In both cases, you still need to build core, e.g. with `-Zbuild-std`" ); // First we define the two main entry points that all panics go through. diff --git a/core/src/slice/specialize.rs b/core/src/slice/specialize.rs index 80eb590587f99..17436395fee69 100644 --- a/core/src/slice/specialize.rs +++ b/core/src/slice/specialize.rs @@ -15,9 +15,54 @@ impl SpecFill for [T] { } impl SpecFill for [T] { - fn spec_fill(&mut self, value: T) { + default fn spec_fill(&mut self, value: T) { for item in self.iter_mut() { *item = value; } } } + +impl SpecFill for [u8] { + fn spec_fill(&mut self, value: u8) { + // SAFETY: The pointer is derived from a reference, so it's writable. + unsafe { + crate::intrinsics::write_bytes(self.as_mut_ptr(), value, self.len()); + } + } +} + +impl SpecFill for [i8] { + fn spec_fill(&mut self, value: i8) { + // SAFETY: The pointer is derived from a reference, so it's writable. + unsafe { + crate::intrinsics::write_bytes(self.as_mut_ptr(), value.cast_unsigned(), self.len()); + } + } +} + +macro spec_fill_int { + ($($type:ty)*) => {$( + impl SpecFill<$type> for [$type] { + #[inline] + fn spec_fill(&mut self, value: $type) { + // We always take this fastpath in Miri for long slices as the manual `for` + // loop can be prohibitively slow. + if (cfg!(miri) && self.len() > 32) || crate::intrinsics::is_val_statically_known(value) { + let bytes = value.to_ne_bytes(); + if value == <$type>::from_ne_bytes([bytes[0]; size_of::<$type>()]) { + // SAFETY: The pointer is derived from a reference, so it's writable. + unsafe { + crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0], self.len()); + } + return; + } + } + for item in self.iter_mut() { + *item = value; + } + } + } + )*} +} + +spec_fill_int! { u16 i16 u32 i32 u64 i64 u128 i128 usize isize } diff --git a/std/src/lib.rs b/std/src/lib.rs index da41c1216c4d5..46eb120d65de3 100644 --- a/std/src/lib.rs +++ b/std/src/lib.rs @@ -63,10 +63,10 @@ //! type, but not the all-important methods. //! //! So for example there is a [page for the primitive type -//! `i32`](primitive::i32) that lists all the methods that can be called on -//! 32-bit integers (very useful), and there is a [page for the module -//! `std::i32`] that documents the constant values [`MIN`] and [`MAX`] (rarely -//! useful). +//! `char`](primitive::char) that lists all the methods that can be called on +//! characters (very useful), and there is a [page for the module +//! `std::char`] that documents iterator and error types created by these methods +//! (rarely useful). //! //! Note the documentation for the primitives [`str`] and [`[T]`][prim@slice] (also //! called 'slice'). Many method calls on [`String`] and [`Vec`] are actually