diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1984cfeefc14b..05a0993c2ee49 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2630,6 +2630,14 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("length", "size")] pub fn len(&self) -> usize { + if !T::IS_ZST { + // SAFETY: The maximum capacity of `Vec` is `isize::MAX` bytes, so if `T` non-ZST, + // `Vec` can have at most `isize::MAX as usize / mem::size_of::()` elements. + unsafe { + core::hint::assert_unchecked(self.len <= isize::MAX as usize / mem::size_of::()); + } + } + self.len } diff --git a/tests/codegen/vec-in-place.rs b/tests/codegen/vec-in-place.rs index c6b77363a4e50..df0a218f73bb5 100644 --- a/tests/codegen/vec-in-place.rs +++ b/tests/codegen/vec-in-place.rs @@ -37,7 +37,6 @@ pub struct Baz { #[no_mangle] pub fn vec_iterator_cast_primitive(vec: Vec) -> Vec { // CHECK-NOT: loop - // CHECK-NOT: call vec.into_iter().map(|e| e as u8).collect() } @@ -45,15 +44,30 @@ pub fn vec_iterator_cast_primitive(vec: Vec) -> Vec { #[no_mangle] pub fn vec_iterator_cast_wrapper(vec: Vec) -> Vec> { // CHECK-NOT: loop - // CHECK-NOT: call vec.into_iter().map(|e| Wrapper(e)).collect() } +// CHECK-LABEL: @vec_iterator_cast_signed +#[no_mangle] +pub fn vec_iterator_cast_signed(vec: Vec) -> Vec { + // CHECK-NOT: and i{{[0-9]+}} %{{.*}}, {{[0-9]+}} + vec.into_iter().map(|e| u32::from_ne_bytes(e.to_ne_bytes())).collect() +} + +// CHECK-LABEL: @vec_iterator_cast_signed_nested +#[no_mangle] +pub fn vec_iterator_cast_signed_nested(vec: Vec>) -> Vec> { + // CHECK-NOT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} + // CHECK-NOT: %{{.*}} = udiv + vec.into_iter() + .map(|e| e.into_iter().map(|e| u32::from_ne_bytes(e.to_ne_bytes())).collect()) + .collect() +} + // CHECK-LABEL: @vec_iterator_cast_unwrap #[no_mangle] pub fn vec_iterator_cast_unwrap(vec: Vec>) -> Vec { // CHECK-NOT: loop - // CHECK-NOT: call vec.into_iter().map(|e| e.0).collect() } @@ -61,7 +75,6 @@ pub fn vec_iterator_cast_unwrap(vec: Vec>) -> Vec { #[no_mangle] pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec { // CHECK-NOT: loop - // CHECK-NOT: call vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect() } @@ -69,7 +82,6 @@ pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec { #[no_mangle] pub fn vec_iterator_cast_deaggregate_tra(vec: Vec) -> Vec<[u64; 4]> { // CHECK-NOT: loop - // CHECK-NOT: call // Safety: For the purpose of this test we assume that Bar layout matches [u64; 4]. // This currently is not guaranteed for repr(Rust) types, but it happens to work here and @@ -82,7 +94,6 @@ pub fn vec_iterator_cast_deaggregate_tra(vec: Vec) -> Vec<[u64; 4]> { #[no_mangle] pub fn vec_iterator_cast_deaggregate_fold(vec: Vec) -> Vec<[u64; 4]> { // CHECK-NOT: loop - // CHECK-NOT: call // Safety: For the purpose of this test we assume that Bar layout matches [u64; 4]. // This currently is not guaranteed for repr(Rust) types, but it happens to work here and @@ -95,7 +106,6 @@ pub fn vec_iterator_cast_deaggregate_fold(vec: Vec) -> Vec<[u64; 4]> { #[no_mangle] pub fn vec_iterator_cast_unwrap_drop(vec: Vec>) -> Vec { // CHECK-NOT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} - // CHECK-NOT: call // CHECK-NOT: %{{.*}} = mul // CHECK-NOT: %{{.*}} = udiv @@ -106,7 +116,6 @@ pub fn vec_iterator_cast_unwrap_drop(vec: Vec>) -> Vec { #[no_mangle] pub fn vec_iterator_cast_wrap_drop(vec: Vec) -> Vec> { // CHECK-NOT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} - // CHECK-NOT: call // CHECK-NOT: %{{.*}} = mul // CHECK-NOT: %{{.*}} = udiv diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs index 4d76c24a9d9f4..90713345110a1 100644 --- a/tests/codegen/vec_pop_push_noop.rs +++ b/tests/codegen/vec_pop_push_noop.rs @@ -9,7 +9,6 @@ pub fn noop(v: &mut Vec) { // CHECK-NOT: call // CHECK: tail call void @llvm.assume // CHECK-NOT: grow_one - // CHECK-NOT: call // CHECK: ret if let Some(x) = v.pop() { v.push(x)