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 6a34d58

Browse files
committedJan 27, 2025
Add inherent versions of MaybeUninit::fill methods for slices
1 parent ebcf860 commit 6a34d58

File tree

2 files changed

+205
-163
lines changed

2 files changed

+205
-163
lines changed
 

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

+181-139
Original file line numberDiff line numberDiff line change
@@ -1104,161 +1104,46 @@ impl<T> MaybeUninit<T> {
11041104
this.write_clone_of_slice(src)
11051105
}
11061106

1107-
/// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1108-
/// initialized contents of the slice.
1109-
/// Any previously initialized elements will not be dropped.
1110-
///
1111-
/// This is similar to [`slice::fill`].
1112-
///
1113-
/// # Panics
1114-
///
1115-
/// This function will panic if any call to `Clone` panics.
1116-
///
1117-
/// If such a panic occurs, any elements previously initialized during this operation will be
1118-
/// dropped.
1119-
///
1120-
/// # Examples
1121-
///
1122-
/// ```
1123-
/// #![feature(maybe_uninit_fill)]
1124-
/// use std::mem::MaybeUninit;
1125-
///
1126-
/// let mut buf = [const { MaybeUninit::uninit() }; 10];
1127-
/// let initialized = MaybeUninit::fill(&mut buf, 1);
1128-
/// assert_eq!(initialized, &mut [1; 10]);
1129-
/// ```
1130-
#[doc(alias = "memset")]
1107+
/// Deprecated version of [`slice::write_filled`].
11311108
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1132-
pub fn fill(this: &mut [MaybeUninit<T>], value: T) -> &mut [T]
1109+
#[deprecated(
1110+
note = "replaced by inherent write_filled method; will eventually be removed",
1111+
since = "1.83.0"
1112+
)]
1113+
pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
11331114
where
11341115
T: Clone,
11351116
{
1136-
SpecFill::spec_fill(this, value);
1137-
// SAFETY: Valid elements have just been filled into `this` so it is initialized
1138-
unsafe { this.assume_init_mut() }
1117+
this.write_filled(value)
11391118
}
11401119

1141-
/// Fills a slice with elements returned by calling a closure repeatedly.
1142-
///
1143-
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1144-
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
1145-
/// pass [`Default::default`] as the argument.
1146-
///
1147-
/// # Panics
1148-
///
1149-
/// This function will panic if any call to the provided closure panics.
1150-
///
1151-
/// If such a panic occurs, any elements previously initialized during this operation will be
1152-
/// dropped.
1153-
///
1154-
/// # Examples
1155-
///
1156-
/// ```
1157-
/// #![feature(maybe_uninit_fill)]
1158-
/// use std::mem::MaybeUninit;
1159-
///
1160-
/// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10];
1161-
/// let initialized = MaybeUninit::fill_with(&mut buf, Default::default);
1162-
/// assert_eq!(initialized, &mut [0; 10]);
1163-
/// ```
1120+
/// Deprecated version of [`slice::write_with`].
11641121
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1165-
pub fn fill_with<F>(this: &mut [MaybeUninit<T>], mut f: F) -> &mut [T]
1122+
#[deprecated(
1123+
note = "replaced by inherent write_with method; will eventually be removed",
1124+
since = "1.83.0"
1125+
)]
1126+
pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], f: F) -> &'a mut [T]
11661127
where
11671128
F: FnMut() -> T,
11681129
{
1169-
let mut guard = Guard { slice: this, initialized: 0 };
1170-
1171-
for element in guard.slice.iter_mut() {
1172-
element.write(f());
1173-
guard.initialized += 1;
1174-
}
1175-
1176-
super::forget(guard);
1177-
1178-
// SAFETY: Valid elements have just been written into `this` so it is initialized
1179-
unsafe { this.assume_init_mut() }
1130+
this.write_with(f)
11801131
}
11811132

1182-
/// Fills a slice with elements yielded by an iterator until either all elements have been
1183-
/// initialized or the iterator is empty.
1184-
///
1185-
/// Returns two slices. The first slice contains the initialized portion of the original slice.
1186-
/// The second slice is the still-uninitialized remainder of the original slice.
1187-
///
1188-
/// # Panics
1189-
///
1190-
/// This function panics if the iterator's `next` function panics.
1191-
///
1192-
/// If such a panic occurs, any elements previously initialized during this operation will be
1193-
/// dropped.
1194-
///
1195-
/// # Examples
1196-
///
1197-
/// Completely filling the slice:
1198-
///
1199-
/// ```
1200-
/// #![feature(maybe_uninit_fill)]
1201-
/// use std::mem::MaybeUninit;
1202-
///
1203-
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1204-
///
1205-
/// let iter = [1, 2, 3].into_iter().cycle();
1206-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1207-
///
1208-
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1209-
/// assert_eq!(remainder.len(), 0);
1210-
/// ```
1211-
///
1212-
/// Partially filling the slice:
1213-
///
1214-
/// ```
1215-
/// #![feature(maybe_uninit_fill)]
1216-
/// use std::mem::MaybeUninit;
1217-
///
1218-
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1219-
/// let iter = [1, 2];
1220-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1221-
///
1222-
/// assert_eq!(initialized, &mut [1, 2]);
1223-
/// assert_eq!(remainder.len(), 3);
1224-
/// ```
1225-
///
1226-
/// Checking an iterator after filling a slice:
1227-
///
1228-
/// ```
1229-
/// #![feature(maybe_uninit_fill)]
1230-
/// use std::mem::MaybeUninit;
1231-
///
1232-
/// let mut buf = [const { MaybeUninit::uninit() }; 3];
1233-
/// let mut iter = [1, 2, 3, 4, 5].into_iter();
1234-
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref());
1235-
///
1236-
/// assert_eq!(initialized, &mut [1, 2, 3]);
1237-
/// assert_eq!(remainder.len(), 0);
1238-
/// assert_eq!(iter.as_slice(), &[4, 5]);
1239-
/// ```
1133+
/// Deprecated version of [`slice::write_iter`].
12401134
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1241-
pub fn fill_from<I>(this: &mut [MaybeUninit<T>], it: I) -> (&mut [T], &mut [MaybeUninit<T>])
1135+
#[deprecated(
1136+
note = "replaced by inherent write_iter method; will eventually be removed",
1137+
since = "1.83.0"
1138+
)]
1139+
pub fn fill_from<'a, I>(
1140+
this: &'a mut [MaybeUninit<T>],
1141+
it: I,
1142+
) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
12421143
where
12431144
I: IntoIterator<Item = T>,
12441145
{
1245-
let iter = it.into_iter();
1246-
let mut guard = Guard { slice: this, initialized: 0 };
1247-
1248-
for (element, val) in guard.slice.iter_mut().zip(iter) {
1249-
element.write(val);
1250-
guard.initialized += 1;
1251-
}
1252-
1253-
let initialized_len = guard.initialized;
1254-
super::forget(guard);
1255-
1256-
// SAFETY: guard.initialized <= this.len()
1257-
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
1258-
1259-
// SAFETY: Valid elements have just been written into `init`, so that portion
1260-
// of `this` is initialized.
1261-
(unsafe { initted.assume_init_mut() }, remainder)
1146+
this.write_iter(it)
12621147
}
12631148

12641149
/// Deprecated version of [`slice::as_bytes`].
@@ -1420,6 +1305,163 @@ impl<T> [MaybeUninit<T>] {
14201305
unsafe { self.assume_init_mut() }
14211306
}
14221307

1308+
/// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1309+
/// initialized contents of the slice.
1310+
/// Any previously initialized elements will not be dropped.
1311+
///
1312+
/// This is similar to [`slice::fill`].
1313+
///
1314+
/// # Panics
1315+
///
1316+
/// This function will panic if any call to `Clone` panics.
1317+
///
1318+
/// If such a panic occurs, any elements previously initialized during this operation will be
1319+
/// dropped.
1320+
///
1321+
/// # Examples
1322+
///
1323+
/// ```
1324+
/// #![feature(maybe_uninit_fill)]
1325+
/// use std::mem::MaybeUninit;
1326+
///
1327+
/// let mut buf = [const { MaybeUninit::uninit() }; 10];
1328+
/// let initialized = buf.write_filled(1);
1329+
/// assert_eq!(initialized, &mut [1; 10]);
1330+
/// ```
1331+
#[doc(alias = "memset")]
1332+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1333+
pub fn write_filled(&mut self, value: T) -> &mut [T]
1334+
where
1335+
T: Clone,
1336+
{
1337+
SpecFill::spec_fill(self, value);
1338+
// SAFETY: Valid elements have just been filled into `self` so it is initialized
1339+
unsafe { self.assume_init_mut() }
1340+
}
1341+
1342+
/// Fills a slice with elements returned by calling a closure repeatedly.
1343+
///
1344+
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1345+
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
1346+
/// pass [`Default::default`] as the argument.
1347+
///
1348+
/// # Panics
1349+
///
1350+
/// This function will panic if any call to the provided closure panics.
1351+
///
1352+
/// If such a panic occurs, any elements previously initialized during this operation will be
1353+
/// dropped.
1354+
///
1355+
/// # Examples
1356+
///
1357+
/// ```
1358+
/// #![feature(maybe_uninit_fill)]
1359+
/// use std::mem::MaybeUninit;
1360+
///
1361+
/// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10];
1362+
/// let initialized = buf.write_with(Default::default);
1363+
/// assert_eq!(initialized, &mut [0; 10]);
1364+
/// ```
1365+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1366+
pub fn write_with<F>(&mut self, mut f: F) -> &mut [T]
1367+
where
1368+
F: FnMut() -> T,
1369+
{
1370+
let mut guard = Guard { slice: self, initialized: 0 };
1371+
1372+
for element in guard.slice.iter_mut() {
1373+
element.write(f());
1374+
guard.initialized += 1;
1375+
}
1376+
1377+
super::forget(guard);
1378+
1379+
// SAFETY: Valid elements have just been written into `this` so it is initialized
1380+
unsafe { self.assume_init_mut() }
1381+
}
1382+
1383+
/// Fills a slice with elements yielded by an iterator until either all elements have been
1384+
/// initialized or the iterator is empty.
1385+
///
1386+
/// Returns two slices. The first slice contains the initialized portion of the original slice.
1387+
/// The second slice is the still-uninitialized remainder of the original slice.
1388+
///
1389+
/// # Panics
1390+
///
1391+
/// This function panics if the iterator's `next` function panics.
1392+
///
1393+
/// If such a panic occurs, any elements previously initialized during this operation will be
1394+
/// dropped.
1395+
///
1396+
/// # Examples
1397+
///
1398+
/// Completely filling the slice:
1399+
///
1400+
/// ```
1401+
/// #![feature(maybe_uninit_fill)]
1402+
/// use std::mem::MaybeUninit;
1403+
///
1404+
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1405+
///
1406+
/// let iter = [1, 2, 3].into_iter().cycle();
1407+
/// let (initialized, remainder) = buf.write_iter(iter);
1408+
///
1409+
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1410+
/// assert_eq!(remainder.len(), 0);
1411+
/// ```
1412+
///
1413+
/// Partially filling the slice:
1414+
///
1415+
/// ```
1416+
/// #![feature(maybe_uninit_fill)]
1417+
/// use std::mem::MaybeUninit;
1418+
///
1419+
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
1420+
/// let iter = [1, 2];
1421+
/// let (initialized, remainder) = buf.write_iter(iter);
1422+
///
1423+
/// assert_eq!(initialized, &mut [1, 2]);
1424+
/// assert_eq!(remainder.len(), 3);
1425+
/// ```
1426+
///
1427+
/// Checking an iterator after filling a slice:
1428+
///
1429+
/// ```
1430+
/// #![feature(maybe_uninit_fill)]
1431+
/// use std::mem::MaybeUninit;
1432+
///
1433+
/// let mut buf = [const { MaybeUninit::uninit() }; 3];
1434+
/// let mut iter = [1, 2, 3, 4, 5].into_iter();
1435+
/// let (initialized, remainder) = buf.write_iter(iter.by_ref());
1436+
///
1437+
/// assert_eq!(initialized, &mut [1, 2, 3]);
1438+
/// assert_eq!(remainder.len(), 0);
1439+
/// assert_eq!(iter.as_slice(), &[4, 5]);
1440+
/// ```
1441+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1442+
pub fn write_iter<I>(&mut self, it: I) -> (&mut [T], &mut [MaybeUninit<T>])
1443+
where
1444+
I: IntoIterator<Item = T>,
1445+
{
1446+
let iter = it.into_iter();
1447+
let mut guard = Guard { slice: self, initialized: 0 };
1448+
1449+
for (element, val) in guard.slice.iter_mut().zip(iter) {
1450+
element.write(val);
1451+
guard.initialized += 1;
1452+
}
1453+
1454+
let initialized_len = guard.initialized;
1455+
super::forget(guard);
1456+
1457+
// SAFETY: guard.initialized <= self.len()
1458+
let (initted, remainder) = unsafe { self.split_at_mut_unchecked(initialized_len) };
1459+
1460+
// SAFETY: Valid elements have just been written into `init`, so that portion
1461+
// of `this` is initialized.
1462+
(unsafe { initted.assume_init_mut() }, remainder)
1463+
}
1464+
14231465
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
14241466
///
14251467
/// 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.