Skip to content

Commit 86d342f

Browse files
EFanZhgitbot
authored and
gitbot
committed
Asserts the maximum value that can be returned from Vec::len
1 parent 8648405 commit 86d342f

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

alloc/src/vec/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
#[cfg(not(no_global_oom_handling))]
5757
use core::cmp;
5858
use core::cmp::Ordering;
59-
use core::fmt;
6059
use core::hash::{Hash, Hasher};
6160
#[cfg(not(no_global_oom_handling))]
6261
use core::iter;
@@ -65,6 +64,7 @@ use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
6564
use core::ops::{self, Index, IndexMut, Range, RangeBounds};
6665
use core::ptr::{self, NonNull};
6766
use core::slice::{self, SliceIndex};
67+
use core::{fmt, intrinsics};
6868

6969
#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
7070
pub use self::extract_if::ExtractIf;
@@ -2675,7 +2675,14 @@ impl<T, A: Allocator> Vec<T, A> {
26752675
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
26762676
#[rustc_confusables("length", "size")]
26772677
pub const fn len(&self) -> usize {
2678-
self.len
2678+
let len = self.len;
2679+
2680+
// SAFETY: The maximum capacity of `Vec<T>` is `isize::MAX` bytes, so the maximum value can
2681+
// be returned is `usize::checked_div(mem::size_of::<T>()).unwrap_or(usize::MAX)`, which
2682+
// matches the definition of `T::MAX_SLICE_LEN`.
2683+
unsafe { intrinsics::assume(len <= T::MAX_SLICE_LEN) };
2684+
2685+
len
26792686
}
26802687

26812688
/// Returns `true` if the vector contains no elements.

core/src/mem/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,17 @@ pub trait SizedTypeProperties: Sized {
12411241
#[doc(hidden)]
12421242
#[unstable(feature = "sized_type_properties", issue = "none")]
12431243
const LAYOUT: Layout = Layout::new::<Self>();
1244+
1245+
/// The largest safe length for a `[Self]`.
1246+
///
1247+
/// Anything larger than this would make `size_of_val` overflow `isize::MAX`,
1248+
/// which is never allowed for a single object.
1249+
#[doc(hidden)]
1250+
#[unstable(feature = "sized_type_properties", issue = "none")]
1251+
const MAX_SLICE_LEN: usize = match size_of::<Self>() {
1252+
0 => usize::MAX,
1253+
n => (isize::MAX as usize) / n,
1254+
};
12441255
}
12451256
#[doc(hidden)]
12461257
#[unstable(feature = "sized_type_properties", issue = "none")]

0 commit comments

Comments
 (0)