Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 12 pull requests #122229

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
709ea74
Add Read Impl for &Stdin
Dajamante Jul 11, 2022
1ea6cd7
Add std::ffi::c_str modules
clarfonthey Aug 19, 2023
b921a34
Fix stable feature name and stabilization version of Read for &Stdin
dtolnay Feb 26, 2024
b18280f
Fill in Read::read_buf for &Stdin
dtolnay Feb 26, 2024
f27a22c
try_with_capacity for RawVec
kornelski Jan 30, 2024
78fb977
try_with_capacity for Vec, VecDeque, String
kornelski Jan 30, 2024
784e6a1
Move capacity_overflow function to make ui tests change less
kornelski Jan 31, 2024
c3954b3
Add a tidy check that checks whether the fluent slugs only appear once
mu001999 Mar 2, 2024
d88c7ff
Remove unused fluent messages
mu001999 Mar 2, 2024
0a00749
Implement MaybeUninit::fill{,_with,_from}
ajwock Feb 18, 2024
5c87ca2
Add some weird test cases to the non_local_definitions lint tests
Urgau Feb 29, 2024
20200f6
Remove useless smallvec dependency in rustc_lint::non_local_def
Urgau Feb 29, 2024
6c4eadd
Add early-return when checking if a path is local
Urgau Feb 29, 2024
98dbe9a
Use was_invoked_from_cargo method instead of hand-written one
Urgau Feb 29, 2024
1195518
Helper function for resolve_path
kornelski Mar 1, 2024
25ab1c7
Suggest correct path in include_bytes!
kornelski Mar 1, 2024
4663fbb
Eagerly translate HelpUseLatestEdition in parser diagnostics
jieyouxu Mar 7, 2024
bef1cd8
ci: add a runner for vanilla LLVM 18
cuviper Mar 8, 2024
446708b
Remove a workaround for a bug
bjorn3 Sep 19, 2021
87ab9e8
Some tweaks to the parallel query cycle handler
Zoxc Mar 8, 2024
564837e
Fix typo in `VisitorResult`
Jarcho Mar 9, 2024
286e813
Rollup merge of #99153 - Dajamante:issue/95622, r=dtolnay
jhpratt Mar 9, 2024
6eaab82
Rollup merge of #112136 - clarfonthey:ffi-c_str, r=cuviper
jhpratt Mar 9, 2024
05b67c6
Rollup merge of #120504 - kornelski:try_with_capacity, r=Amanieu
jhpratt Mar 9, 2024
3c6b895
Rollup merge of #121280 - ajwock:maybeuninit_fill, r=Amanieu
jhpratt Mar 9, 2024
32b2e63
Rollup merge of #121813 - Urgau:misc-non_local_defs-lint, r=cjgillot
jhpratt Mar 9, 2024
936c182
Rollup merge of #121833 - kornelski:parent_include, r=estebank
jhpratt Mar 9, 2024
9aff53d
Rollup merge of #121860 - mu001999:master, r=Nilstrieb
jhpratt Mar 9, 2024
d16fd38
Rollup merge of #122160 - jieyouxu:eager-translate-help-use-latest-ed…
jhpratt Mar 9, 2024
74f17ea
Rollup merge of #122178 - cuviper:ci-llvm-18, r=Kobzol
jhpratt Mar 9, 2024
437ba6a
Rollup merge of #122186 - bjorn3:remove_bug_workaround, r=petrochenkov
jhpratt Mar 9, 2024
6a582de
Rollup merge of #122215 - Zoxc:cycle-detect-names, r=oli-obk
jhpratt Mar 9, 2024
d5956a9
Rollup merge of #122223 - Jarcho:visit_fix, r=oli-obk
jhpratt Mar 9, 2024
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
202 changes: 186 additions & 16 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1125,22 +1125,6 @@ impl<T> MaybeUninit<T> {
// unlike copy_from_slice this does not call clone_from_slice on the slice
// this is because `MaybeUninit<T: Clone>` does not implement Clone.

struct Guard<'a, T> {
slice: &'a mut [MaybeUninit<T>],
initialized: usize,
}

impl<'a, T> Drop for Guard<'a, T> {
fn drop(&mut self) {
let initialized_part = &mut self.slice[..self.initialized];
// SAFETY: this raw slice will contain only initialized objects
// that's why, it is allowed to drop it.
unsafe {
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(initialized_part));
}
}
}

assert_eq!(this.len(), src.len(), "destination and source slices have different lengths");
// NOTE: We need to explicitly slice them to the same length
// for bounds checking to be elided, and the optimizer will
Expand All @@ -1162,6 +1146,151 @@ impl<T> MaybeUninit<T> {
unsafe { MaybeUninit::slice_assume_init_mut(this) }
}

/// Fills `this` with elements by cloning `value`, returning a mutable reference to the now
/// initialized contents of `this`.
/// Any previously initialized elements will not be dropped.
///
/// This is similar to [`slice::fill`].
///
/// # Panics
///
/// This function will panic if any call to `Clone` panics.
///
/// If such a panic occurs, any elements previously initialized during this operation will be
/// dropped.
///
/// # Examples
///
/// Fill an uninit vec with 1.
/// ```
/// #![feature(maybe_uninit_fill)]
/// use std::mem::MaybeUninit;
///
/// let mut buf = vec![MaybeUninit::uninit(); 10];
/// let initialized = MaybeUninit::fill(buf.as_mut_slice(), 1);
/// assert_eq!(initialized, &mut [1; 10]);
/// ```
#[doc(alias = "memset")]
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
where
T: Clone,
{
SpecFill::spec_fill(this, value);
// SAFETY: Valid elements have just been filled into `this` so it is initialized
unsafe { MaybeUninit::slice_assume_init_mut(this) }
}

/// Fills `this` with elements returned by calling a closure repeatedly.
///
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
/// pass [`Default::default`] as the argument.
///
/// # Panics
///
/// This function will panic if any call to the provided closure panics.
///
/// If such a panic occurs, any elements previously initialized during this operation will be
/// dropped.
///
/// # Examples
///
/// Fill an uninit vec with the default value.
/// ```
/// #![feature(maybe_uninit_fill)]
/// use std::mem::MaybeUninit;
///
/// let mut buf = vec![MaybeUninit::<i32>::uninit(); 10];
/// let initialized = MaybeUninit::fill_with(buf.as_mut_slice(), Default::default);
/// assert_eq!(initialized, &mut [0; 10]);
/// ```
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T]
where
F: FnMut() -> T,
{
let mut guard = Guard { slice: this, initialized: 0 };

for element in guard.slice.iter_mut() {
element.write(f());
guard.initialized += 1;
}

super::forget(guard);

// SAFETY: Valid elements have just been written into `this` so it is initialized
unsafe { MaybeUninit::slice_assume_init_mut(this) }
}

/// Fills `this` with elements yielded by an iterator until either all elements have been
/// initialized or the iterator is empty.
///
/// Returns two slices. The first slice contains the initialized portion of the original slice.
/// The second slice is the still-uninitialized remainder of the original slice.
///
/// # Panics
///
/// This function panics if the iterator's `next` function panics.
///
/// If such a panic occurs, any elements previously initialized during this operation will be
/// dropped.
///
/// # Examples
///
/// Fill an uninit vec with a cycling iterator.
/// ```
/// #![feature(maybe_uninit_fill)]
/// use std::mem::MaybeUninit;
///
/// let mut buf = vec![MaybeUninit::uninit(); 5];
///
/// let iter = [1, 2, 3].into_iter().cycle();
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
///
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
/// assert_eq!(0, remainder.len());
/// ```
///
/// Fill an uninit vec, but not completely.
/// ```
/// #![feature(maybe_uninit_fill)]
/// use std::mem::MaybeUninit;
///
/// let mut buf = vec![MaybeUninit::uninit(); 5];
/// let iter = [1, 2];
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
///
/// assert_eq!(initialized, &mut [1, 2]);
/// assert_eq!(remainder.len(), 3);
/// ```
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
pub fn fill_from<'a, I>(
this: &'a mut [MaybeUninit<T>],
it: I,
) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
where
I: IntoIterator<Item = T>,
{
let iter = it.into_iter();
let mut guard = Guard { slice: this, initialized: 0 };

for (element, val) in guard.slice.iter_mut().zip(iter) {
element.write(val);
guard.initialized += 1;
}

let initialized_len = guard.initialized;
super::forget(guard);

// SAFETY: guard.initialized <= this.len()
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };

// SAFETY: Valid elements have just been written into `init`, so that portion
// of `this` is initialized.
(unsafe { MaybeUninit::slice_assume_init_mut(initted) }, remainder)
}

/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
///
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
Expand Down Expand Up @@ -1315,3 +1444,44 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
unsafe { intrinsics::transmute_unchecked(self) }
}
}

struct Guard<'a, T> {
slice: &'a mut [MaybeUninit<T>],
initialized: usize,
}

impl<'a, T> Drop for Guard<'a, T> {
fn drop(&mut self) {
let initialized_part = &mut self.slice[..self.initialized];
// SAFETY: this raw sub-slice will contain only initialized objects.
unsafe {
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(initialized_part));
}
}
}

trait SpecFill<T> {
fn spec_fill(&mut self, value: T);
}

impl<T: Clone> SpecFill<T> for [MaybeUninit<T>] {
default fn spec_fill(&mut self, value: T) {
let mut guard = Guard { slice: self, initialized: 0 };

if let Some((last, elems)) = guard.slice.split_last_mut() {
for el in elems {
el.write(value.clone());
guard.initialized += 1;
}

last.write(value);
}
super::forget(guard);
}
}

impl<T: Copy> SpecFill<T> for [MaybeUninit<T>] {
fn spec_fill(&mut self, value: T) {
self.fill(MaybeUninit::new(value));
}
}
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#![feature(slice_from_ptr_range)]
#![feature(slice_split_once)]
#![feature(split_as_slice)]
#![feature(maybe_uninit_fill)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
Expand Down
Loading