Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fa0164e

Browse files
committedMar 8, 2025
Add inherent versions of MaybeUninit::fill methods for slices
1 parent cdd8af2 commit fa0164e

File tree

2 files changed

+208
-166
lines changed

2 files changed

+208
-166
lines changed
 

‎library/core/src/mem/maybe_uninit.rs

+181-139
Original file line numberDiff line numberDiff line change
@@ -1065,161 +1065,46 @@ impl<T> MaybeUninit<T> {
10651065
this.write_clone_of_slice(src)
10661066
}
10671067

1068-
/// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1069-
/// initialized contents of the slice.
1070-
/// Any previously initialized elements will not be dropped.
1071-
///
1072-
/// This is similar to [`slice::fill`].
1073-
///
1074-
/// # Panics
1075-
///
1076-
/// This function will panic if any call to `Clone` panics.
1077-
///
1078-
/// If such a panic occurs, any elements previously initialized during this operation will be
1079-
/// dropped.
1080-
///
1081-
/// # Examples
1082-
///
1083-
/// ```
1084-
/// #![feature(maybe_uninit_fill)]
1085-
/// use std::mem::MaybeUninit;
1086-
///
1087-
/// let mut buf = [const { MaybeUninit::uninit() }; 10];
1088-
/// let initialized = MaybeUninit::fill(&mut buf, 1);
1089-
/// assert_eq!(initialized, &mut [1; 10]);
1090-
/// ```
1091-
#[doc(alias = "memset")]
1068+
/// Deprecated version of [`slice::write_filled`].
10921069
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1093-
pub fn fill(this: &mut [MaybeUninit<T>], value: T) -> &mut [T]
1070+
#[deprecated(
1071+
note = "replaced by inherent write_filled method; will eventually be removed",
1072+
since = "1.83.0"
1073+
)]
1074+
pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
10941075
where
10951076
T: Clone,
10961077
{
1097-
SpecFill::spec_fill(this, value);
1098-
// SAFETY: Valid elements have just been filled into `this` so it is initialized
1099-
unsafe { this.assume_init_mut() }
1078+
this.write_filled(value)
11001079
}
11011080

1102-
/// Fills a slice with elements returned by calling a closure repeatedly.
1103-
///
1104-
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1105-
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
1106-
/// pass [`Default::default`] as the argument.
1107-
///
1108-
/// # Panics
1109-
///
1110-
/// This function will panic if any call to the provided closure panics.
1111-
///
1112-
/// If such a panic occurs, any elements previously initialized during this operation will be
1113-
/// dropped.
1114-
///
1115-
/// # Examples
1116-
///
1117-
/// ```
1118-
/// #![feature(maybe_uninit_fill)]
1119-
/// use std::mem::MaybeUninit;
1120-
///
1121-
/// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10];
1122-
/// let initialized = MaybeUninit::fill_with(&mut buf, Default::default);
1123-
/// assert_eq!(initialized, &mut [0; 10]);
1124-
/// ```
1081+
/// Deprecated version of [`slice::write_with`].
11251082
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1126-
pub fn fill_with<F>(this: &mut [MaybeUninit<T>], mut f: F) -> &mut [T]
1083+
#[deprecated(
1084+
note = "replaced by inherent write_with method; will eventually be removed",
1085+
since = "1.83.0"
1086+
)]
1087+
pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], f: F) -> &'a mut [T]
11271088
where
11281089
F: FnMut() -> T,
11291090
{
1130-
let mut guard = Guard { slice: this, initialized: 0 };
1131-
1132-
for element in guard.slice.iter_mut() {
1133-
element.write(f());
1134-
guard.initialized += 1;
1135-
}
1136-
1137-
super::forget(guard);
1138-
1139-
// SAFETY: Valid elements have just been written into `this` so it is initialized
1140-
unsafe { this.assume_init_mut() }
1091+
this.write_with(f)
11411092
}
11421093

1143-
/// Fills a slice with elements yielded by an iterator until either all elements have been
1144-
/// initialized or the iterator is empty.
1145-
///
1146-
/// Returns two slices. The first slice contains the initialized portion of the original slice.
1147-
/// The second slice is the still-uninitialized remainder of the original slice.
1148-
///
1149-
/// # Panics
1150-
///
1151-
/// This function panics if the iterator's `next` function panics.
1152-
///
1153-
/// If such a panic occurs, any elements previously initialized during this operation will be
1154-
/// dropped.
1155-
///
1156-
/// # Examples
1157-
///
1158-
/// Completely filling the slice:
1159-
///
1160-
/// ```
1161-
/// #![feature(maybe_uninit_fill)]
1162-
/// use std::mem::MaybeUninit;
1163-
///
1164-
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1165-
///
1166-
/// let iter = [1, 2, 3].into_iter().cycle();
1167-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1168-
///
1169-
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1170-
/// assert_eq!(remainder.len(), 0);
1171-
/// ```
1172-
///
1173-
/// Partially filling the slice:
1174-
///
1175-
/// ```
1176-
/// #![feature(maybe_uninit_fill)]
1177-
/// use std::mem::MaybeUninit;
1178-
///
1179-
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1180-
/// let iter = [1, 2];
1181-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1182-
///
1183-
/// assert_eq!(initialized, &mut [1, 2]);
1184-
/// assert_eq!(remainder.len(), 3);
1185-
/// ```
1186-
///
1187-
/// Checking an iterator after filling a slice:
1188-
///
1189-
/// ```
1190-
/// #![feature(maybe_uninit_fill)]
1191-
/// use std::mem::MaybeUninit;
1192-
///
1193-
/// let mut buf = [const { MaybeUninit::uninit() }; 3];
1194-
/// let mut iter = [1, 2, 3, 4, 5].into_iter();
1195-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref());
1196-
///
1197-
/// assert_eq!(initialized, &mut [1, 2, 3]);
1198-
/// assert_eq!(remainder.len(), 0);
1199-
/// assert_eq!(iter.as_slice(), &[4, 5]);
1200-
/// ```
1094+
/// Deprecated version of [`slice::write_iter`].
12011095
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1202-
pub fn fill_from<I>(this: &mut [MaybeUninit<T>], it: I) -> (&mut [T], &mut [MaybeUninit<T>])
1096+
#[deprecated(
1097+
note = "replaced by inherent write_iter method; will eventually be removed",
1098+
since = "1.83.0"
1099+
)]
1100+
pub fn fill_from<'a, I>(
1101+
this: &'a mut [MaybeUninit<T>],
1102+
it: I,
1103+
) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
12031104
where
12041105
I: IntoIterator<Item = T>,
12051106
{
1206-
let iter = it.into_iter();
1207-
let mut guard = Guard { slice: this, initialized: 0 };
1208-
1209-
for (element, val) in guard.slice.iter_mut().zip(iter) {
1210-
element.write(val);
1211-
guard.initialized += 1;
1212-
}
1213-
1214-
let initialized_len = guard.initialized;
1215-
super::forget(guard);
1216-
1217-
// SAFETY: guard.initialized <= this.len()
1218-
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
1219-
1220-
// SAFETY: Valid elements have just been written into `init`, so that portion
1221-
// of `this` is initialized.
1222-
(unsafe { initted.assume_init_mut() }, remainder)
1107+
this.write_iter(it)
12231108
}
12241109

12251110
/// Deprecated version of [`slice::as_bytes`].
@@ -1380,6 +1265,163 @@ impl<T> [MaybeUninit<T>] {
13801265
unsafe { self.assume_init_mut() }
13811266
}
13821267

1268+
/// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1269+
/// initialized contents of the slice.
1270+
/// Any previously initialized elements will not be dropped.
1271+
///
1272+
/// This is similar to [`slice::fill`].
1273+
///
1274+
/// # Panics
1275+
///
1276+
/// This function will panic if any call to `Clone` panics.
1277+
///
1278+
/// If such a panic occurs, any elements previously initialized during this operation will be
1279+
/// dropped.
1280+
///
1281+
/// # Examples
1282+
///
1283+
/// ```
1284+
/// #![feature(maybe_uninit_fill)]
1285+
/// use std::mem::MaybeUninit;
1286+
///
1287+
/// let mut buf = [const { MaybeUninit::uninit() }; 10];
1288+
/// let initialized = buf.write_filled(1);
1289+
/// assert_eq!(initialized, &mut [1; 10]);
1290+
/// ```
1291+
#[doc(alias = "memset")]
1292+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1293+
pub fn write_filled(&mut self, value: T) -> &mut [T]
1294+
where
1295+
T: Clone,
1296+
{
1297+
SpecFill::spec_fill(self, value);
1298+
// SAFETY: Valid elements have just been filled into `self` so it is initialized
1299+
unsafe { self.assume_init_mut() }
1300+
}
1301+
1302+
/// Fills a slice with elements returned by calling a closure for each index.
1303+
///
1304+
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1305+
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
1306+
/// pass [`|_| Default::default()`][Default::default] as the argument.
1307+
///
1308+
/// # Panics
1309+
///
1310+
/// This function will panic if any call to the provided closure panics.
1311+
///
1312+
/// If such a panic occurs, any elements previously initialized during this operation will be
1313+
/// dropped.
1314+
///
1315+
/// # Examples
1316+
///
1317+
/// ```
1318+
/// #![feature(maybe_uninit_fill)]
1319+
/// use std::mem::MaybeUninit;
1320+
///
1321+
/// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 5];
1322+
/// let initialized = buf.write_with(|idx| idx + 1);
1323+
/// assert_eq!(initialized, &mut [1, 2, 3, 4, 5]);
1324+
/// ```
1325+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1326+
pub fn write_with<F>(&mut self, mut f: F) -> &mut [T]
1327+
where
1328+
F: FnMut(usize) -> T,
1329+
{
1330+
let mut guard = Guard { slice: self, initialized: 0 };
1331+
1332+
for (idx, element) in guard.slice.iter_mut().enumerate() {
1333+
element.write(f(idx));
1334+
guard.initialized += 1;
1335+
}
1336+
1337+
super::forget(guard);
1338+
1339+
// SAFETY: Valid elements have just been written into `this` so it is initialized
1340+
unsafe { self.assume_init_mut() }
1341+
}
1342+
1343+
/// Fills a slice with elements yielded by an iterator until either all elements have been
1344+
/// initialized or the iterator is empty.
1345+
///
1346+
/// Returns two slices. The first slice contains the initialized portion of the original slice.
1347+
/// The second slice is the still-uninitialized remainder of the original slice.
1348+
///
1349+
/// # Panics
1350+
///
1351+
/// This function panics if the iterator's `next` function panics.
1352+
///
1353+
/// If such a panic occurs, any elements previously initialized during this operation will be
1354+
/// dropped.
1355+
///
1356+
/// # Examples
1357+
///
1358+
/// Completely filling the slice:
1359+
///
1360+
/// ```
1361+
/// #![feature(maybe_uninit_fill)]
1362+
/// use std::mem::MaybeUninit;
1363+
///
1364+
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1365+
///
1366+
/// let iter = [1, 2, 3].into_iter().cycle();
1367+
/// let (initialized, remainder) = buf.write_iter(iter);
1368+
///
1369+
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1370+
/// assert_eq!(remainder.len(), 0);
1371+
/// ```
1372+
///
1373+
/// Partially filling the slice:
1374+
///
1375+
/// ```
1376+
/// #![feature(maybe_uninit_fill)]
1377+
/// use std::mem::MaybeUninit;
1378+
///
1379+
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1380+
/// let iter = [1, 2];
1381+
/// let (initialized, remainder) = buf.write_iter(iter);
1382+
///
1383+
/// assert_eq!(initialized, &mut [1, 2]);
1384+
/// assert_eq!(remainder.len(), 3);
1385+
/// ```
1386+
///
1387+
/// Checking an iterator after filling a slice:
1388+
///
1389+
/// ```
1390+
/// #![feature(maybe_uninit_fill)]
1391+
/// use std::mem::MaybeUninit;
1392+
///
1393+
/// let mut buf = [const { MaybeUninit::uninit() }; 3];
1394+
/// let mut iter = [1, 2, 3, 4, 5].into_iter();
1395+
/// let (initialized, remainder) = buf.write_iter(iter.by_ref());
1396+
///
1397+
/// assert_eq!(initialized, &mut [1, 2, 3]);
1398+
/// assert_eq!(remainder.len(), 0);
1399+
/// assert_eq!(iter.as_slice(), &[4, 5]);
1400+
/// ```
1401+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1402+
pub fn write_iter<I>(&mut self, it: I) -> (&mut [T], &mut [MaybeUninit<T>])
1403+
where
1404+
I: IntoIterator<Item = T>,
1405+
{
1406+
let iter = it.into_iter();
1407+
let mut guard = Guard { slice: self, initialized: 0 };
1408+
1409+
for (element, val) in guard.slice.iter_mut().zip(iter) {
1410+
element.write(val);
1411+
guard.initialized += 1;
1412+
}
1413+
1414+
let initialized_len = guard.initialized;
1415+
super::forget(guard);
1416+
1417+
// SAFETY: guard.initialized <= self.len()
1418+
let (initted, remainder) = unsafe { self.split_at_mut_unchecked(initialized_len) };
1419+
1420+
// SAFETY: Valid elements have just been written into `init`, so that portion
1421+
// of `this` is initialized.
1422+
(unsafe { initted.assume_init_mut() }, remainder)
1423+
}
1424+
13831425
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
13841426
///
13851427
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.