From 2ff14448863ac1a1dd9533461708e29aae170c2d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:06:31 +0200 Subject: Adding debian version 1.65.0+dfsg1-2. Signed-off-by: Daniel Baumann --- library/core/tests/alloc.rs | 44 ++++++ library/core/tests/any.rs | 2 +- library/core/tests/atomic.rs | 2 +- library/core/tests/const_ptr.rs | 6 +- library/core/tests/iter/adapters/array_chunks.rs | 179 +++++++++++++++++++++++ library/core/tests/iter/adapters/by_ref_sized.rs | 20 +++ library/core/tests/iter/adapters/flatten.rs | 42 ++++++ library/core/tests/iter/adapters/mod.rs | 24 +++ library/core/tests/iter/adapters/skip.rs | 31 ++++ library/core/tests/lib.rs | 6 +- library/core/tests/num/int_log.rs | 156 ++++++++++---------- library/core/tests/num/int_macros.rs | 26 ++++ library/core/tests/num/uint_macros.rs | 22 +++ library/core/tests/ptr.rs | 2 +- library/core/tests/result.rs | 9 -- library/core/tests/slice.rs | 3 +- library/core/tests/str_lossy.rs | 138 ++++++++--------- 17 files changed, 548 insertions(+), 164 deletions(-) create mode 100644 library/core/tests/iter/adapters/array_chunks.rs create mode 100644 library/core/tests/iter/adapters/by_ref_sized.rs (limited to 'library/core/tests') diff --git a/library/core/tests/alloc.rs b/library/core/tests/alloc.rs index 8a5a06b34..3ceaeadce 100644 --- a/library/core/tests/alloc.rs +++ b/library/core/tests/alloc.rs @@ -1,4 +1,5 @@ use core::alloc::Layout; +use core::mem::size_of; use core::ptr::{self, NonNull}; #[test] @@ -12,6 +13,49 @@ fn const_unchecked_layout() { assert_eq!(Some(DANGLING), NonNull::new(ptr::invalid_mut(ALIGN))); } +#[test] +fn layout_round_up_to_align_edge_cases() { + const MAX_SIZE: usize = isize::MAX as usize; + + for shift in 0..usize::BITS { + let align = 1_usize << shift; + let edge = (MAX_SIZE + 1) - align; + let low = edge.saturating_sub(10); + let high = edge.saturating_add(10); + assert!(Layout::from_size_align(low, align).is_ok()); + assert!(Layout::from_size_align(high, align).is_err()); + for size in low..=high { + assert_eq!( + Layout::from_size_align(size, align).is_ok(), + size.next_multiple_of(align) <= MAX_SIZE, + ); + } + } +} + +#[test] +fn layout_array_edge_cases() { + for_type::(); + for_type::<[i32; 0b10101]>(); + for_type::<[u8; 0b1010101]>(); + + // Make sure ZSTs don't lead to divide-by-zero + assert_eq!(Layout::array::<()>(usize::MAX).unwrap(), Layout::from_size_align(0, 1).unwrap()); + + fn for_type() { + const MAX_SIZE: usize = isize::MAX as usize; + + let edge = (MAX_SIZE + 1) / size_of::(); + let low = edge.saturating_sub(10); + let high = edge.saturating_add(10); + assert!(Layout::array::(low).is_ok()); + assert!(Layout::array::(high).is_err()); + for n in low..=high { + assert_eq!(Layout::array::(n).is_ok(), n * size_of::() <= MAX_SIZE); + } + } +} + #[test] fn layout_debug_shows_log2_of_alignment() { // `Debug` is not stable, but here's what it does right now diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs index 8ed0c8880..9538b8139 100644 --- a/library/core/tests/any.rs +++ b/library/core/tests/any.rs @@ -142,7 +142,7 @@ impl Provider for SomeConcreteType { demand .provide_ref::(&self.some_string) .provide_ref::(&self.some_string) - .provide_value::(|| "bye".to_owned()); + .provide_value_with::(|| "bye".to_owned()); } } diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 13b12db20..94b031060 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -155,7 +155,7 @@ fn ptr_add_data() { assert_eq!(atom.fetch_ptr_sub(1, SeqCst), n.wrapping_add(1)); assert_eq!(atom.load(SeqCst), n); - let bytes_from_n = |b| n.cast::().wrapping_add(b).cast::(); + let bytes_from_n = |b| n.wrapping_byte_add(b); assert_eq!(atom.fetch_byte_add(1, SeqCst), n); assert_eq!(atom.load(SeqCst), bytes_from_n(1)); diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs index 152fed803..d874f0831 100644 --- a/library/core/tests/const_ptr.rs +++ b/library/core/tests/const_ptr.rs @@ -3,7 +3,7 @@ const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x const fn unaligned_ptr() -> *const u16 { // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16 - unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 } + unsafe { DATA.as_ptr().byte_add(1) } } #[test] @@ -67,7 +67,7 @@ fn write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45])); } two_aligned @@ -91,7 +91,7 @@ fn mut_ptr_write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45])); } two_aligned diff --git a/library/core/tests/iter/adapters/array_chunks.rs b/library/core/tests/iter/adapters/array_chunks.rs new file mode 100644 index 000000000..4e9d89e1e --- /dev/null +++ b/library/core/tests/iter/adapters/array_chunks.rs @@ -0,0 +1,179 @@ +use core::cell::Cell; +use core::iter::{self, Iterator}; + +use super::*; + +#[test] +fn test_iterator_array_chunks_infer() { + let xs = [1, 1, 2, -2, 6, 0, 3, 1]; + for [a, b, c] in xs.iter().copied().array_chunks() { + assert_eq!(a + b + c, 4); + } +} + +#[test] +fn test_iterator_array_chunks_clone_and_drop() { + let count = Cell::new(0); + let mut it = (0..5).map(|_| CountDrop::new(&count)).array_chunks::<3>(); + assert_eq!(it.by_ref().count(), 1); + assert_eq!(count.get(), 3); + let mut it2 = it.clone(); + assert_eq!(count.get(), 3); + assert_eq!(it.into_remainder().unwrap().len(), 2); + assert_eq!(count.get(), 5); + assert!(it2.next().is_none()); + assert_eq!(it2.into_remainder().unwrap().len(), 2); + assert_eq!(count.get(), 7); +} + +#[test] +fn test_iterator_array_chunks_remainder() { + let mut it = (0..11).array_chunks::<4>(); + assert_eq!(it.next(), Some([0, 1, 2, 3])); + assert_eq!(it.next(), Some([4, 5, 6, 7])); + assert_eq!(it.next(), None); + assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]); +} + +#[test] +fn test_iterator_array_chunks_size_hint() { + let it = (0..6).array_chunks::<1>(); + assert_eq!(it.size_hint(), (6, Some(6))); + + let it = (0..6).array_chunks::<3>(); + assert_eq!(it.size_hint(), (2, Some(2))); + + let it = (0..6).array_chunks::<5>(); + assert_eq!(it.size_hint(), (1, Some(1))); + + let it = (0..6).array_chunks::<7>(); + assert_eq!(it.size_hint(), (0, Some(0))); + + let it = (1..).array_chunks::<2>(); + assert_eq!(it.size_hint(), (usize::MAX / 2, None)); + + let it = (1..).filter(|x| x % 2 != 0).array_chunks::<2>(); + assert_eq!(it.size_hint(), (0, None)); +} + +#[test] +fn test_iterator_array_chunks_count() { + let it = (0..6).array_chunks::<1>(); + assert_eq!(it.count(), 6); + + let it = (0..6).array_chunks::<3>(); + assert_eq!(it.count(), 2); + + let it = (0..6).array_chunks::<5>(); + assert_eq!(it.count(), 1); + + let it = (0..6).array_chunks::<7>(); + assert_eq!(it.count(), 0); + + let it = (0..6).filter(|x| x % 2 == 0).array_chunks::<2>(); + assert_eq!(it.count(), 1); + + let it = iter::empty::().array_chunks::<2>(); + assert_eq!(it.count(), 0); + + let it = [(); usize::MAX].iter().array_chunks::<2>(); + assert_eq!(it.count(), usize::MAX / 2); +} + +#[test] +fn test_iterator_array_chunks_next_and_next_back() { + let mut it = (0..11).array_chunks::<3>(); + assert_eq!(it.next(), Some([0, 1, 2])); + assert_eq!(it.next_back(), Some([6, 7, 8])); + assert_eq!(it.next(), Some([3, 4, 5])); + assert_eq!(it.next_back(), None); + assert_eq!(it.next(), None); + assert_eq!(it.next_back(), None); + assert_eq!(it.next(), None); + assert_eq!(it.into_remainder().unwrap().as_slice(), &[9, 10]); +} + +#[test] +fn test_iterator_array_chunks_rev_remainder() { + let mut it = (0..11).array_chunks::<4>(); + { + let mut it = it.by_ref().rev(); + assert_eq!(it.next(), Some([4, 5, 6, 7])); + assert_eq!(it.next(), Some([0, 1, 2, 3])); + assert_eq!(it.next(), None); + assert_eq!(it.next(), None); + } + assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]); +} + +#[test] +fn test_iterator_array_chunks_try_fold() { + let count = Cell::new(0); + let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>(); + let result: Result<_, ()> = it.by_ref().try_fold(0, |acc, _item| Ok(acc + 1)); + assert_eq!(result, Ok(3)); + assert_eq!(count.get(), 9); + drop(it); + assert_eq!(count.get(), 10); + + let count = Cell::new(0); + let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>(); + let result = it.by_ref().try_fold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) }); + assert_eq!(result, Err(2)); + assert_eq!(count.get(), 9); + drop(it); + assert_eq!(count.get(), 9); +} + +#[test] +fn test_iterator_array_chunks_fold() { + let result = (1..11).array_chunks::<3>().fold(0, |acc, [a, b, c]| { + assert_eq!(acc + 1, a); + assert_eq!(acc + 2, b); + assert_eq!(acc + 3, c); + acc + 3 + }); + assert_eq!(result, 9); + + let count = Cell::new(0); + let result = + (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1); + assert_eq!(result, 3); + assert_eq!(count.get(), 10); +} + +#[test] +fn test_iterator_array_chunks_try_rfold() { + let count = Cell::new(0); + let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>(); + let result: Result<_, ()> = it.try_rfold(0, |acc, _item| Ok(acc + 1)); + assert_eq!(result, Ok(3)); + assert_eq!(count.get(), 9); + drop(it); + assert_eq!(count.get(), 10); + + let count = Cell::new(0); + let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>(); + let result = it.try_rfold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) }); + assert_eq!(result, Err(2)); + assert_eq!(count.get(), 9); + drop(it); + assert_eq!(count.get(), 10); +} + +#[test] +fn test_iterator_array_chunks_rfold() { + let result = (1..11).array_chunks::<3>().rfold(0, |acc, [a, b, c]| { + assert_eq!(10 - (acc + 1), c); + assert_eq!(10 - (acc + 2), b); + assert_eq!(10 - (acc + 3), a); + acc + 3 + }); + assert_eq!(result, 9); + + let count = Cell::new(0); + let result = + (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().rfold(0, |acc, _item| acc + 1); + assert_eq!(result, 3); + assert_eq!(count.get(), 10); +} diff --git a/library/core/tests/iter/adapters/by_ref_sized.rs b/library/core/tests/iter/adapters/by_ref_sized.rs new file mode 100644 index 000000000..a9c066f0e --- /dev/null +++ b/library/core/tests/iter/adapters/by_ref_sized.rs @@ -0,0 +1,20 @@ +use core::iter::*; + +#[test] +fn test_iterator_by_ref_sized() { + let a = ['a', 'b', 'c', 'd']; + + let mut s = String::from("Z"); + let mut it = a.iter().copied(); + ByRefSized(&mut it).take(2).for_each(|x| s.push(x)); + assert_eq!(s, "Zab"); + ByRefSized(&mut it).fold((), |(), x| s.push(x)); + assert_eq!(s, "Zabcd"); + + let mut s = String::from("Z"); + let mut it = a.iter().copied(); + ByRefSized(&mut it).rev().take(2).for_each(|x| s.push(x)); + assert_eq!(s, "Zdc"); + ByRefSized(&mut it).rfold((), |(), x| s.push(x)); + assert_eq!(s, "Zdcba"); +} diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs index f8ab8c9d4..690fd0c21 100644 --- a/library/core/tests/iter/adapters/flatten.rs +++ b/library/core/tests/iter/adapters/flatten.rs @@ -168,3 +168,45 @@ fn test_trusted_len_flatten() { assert_trusted_len(&iter); assert_eq!(iter.size_hint(), (20, Some(20))); } + +#[test] +fn test_flatten_count() { + let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); + + assert_eq!(it.clone().count(), 40); + it.advance_by(5).unwrap(); + assert_eq!(it.clone().count(), 35); + it.advance_back_by(5).unwrap(); + assert_eq!(it.clone().count(), 30); + it.advance_by(10).unwrap(); + assert_eq!(it.clone().count(), 20); + it.advance_back_by(8).unwrap(); + assert_eq!(it.clone().count(), 12); + it.advance_by(4).unwrap(); + assert_eq!(it.clone().count(), 8); + it.advance_back_by(5).unwrap(); + assert_eq!(it.clone().count(), 3); + it.advance_by(3).unwrap(); + assert_eq!(it.clone().count(), 0); +} + +#[test] +fn test_flatten_last() { + let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); + + assert_eq!(it.clone().last(), Some(39)); + it.advance_by(5).unwrap(); // 5..40 + assert_eq!(it.clone().last(), Some(39)); + it.advance_back_by(5).unwrap(); // 5..35 + assert_eq!(it.clone().last(), Some(34)); + it.advance_by(10).unwrap(); // 15..35 + assert_eq!(it.clone().last(), Some(34)); + it.advance_back_by(8).unwrap(); // 15..27 + assert_eq!(it.clone().last(), Some(26)); + it.advance_by(4).unwrap(); // 19..27 + assert_eq!(it.clone().last(), Some(26)); + it.advance_back_by(5).unwrap(); // 19..22 + assert_eq!(it.clone().last(), Some(21)); + it.advance_by(3).unwrap(); // 22..22 + assert_eq!(it.clone().last(), None); +} diff --git a/library/core/tests/iter/adapters/mod.rs b/library/core/tests/iter/adapters/mod.rs index 567d9fe49..ffd5f3857 100644 --- a/library/core/tests/iter/adapters/mod.rs +++ b/library/core/tests/iter/adapters/mod.rs @@ -1,3 +1,5 @@ +mod array_chunks; +mod by_ref_sized; mod chain; mod cloned; mod copied; @@ -183,3 +185,25 @@ impl Clone for CountClone { ret } } + +#[derive(Debug, Clone)] +struct CountDrop<'a> { + dropped: bool, + count: &'a Cell, +} + +impl<'a> CountDrop<'a> { + pub fn new(count: &'a Cell) -> Self { + Self { dropped: false, count } + } +} + +impl Drop for CountDrop<'_> { + fn drop(&mut self) { + if self.dropped { + panic!("double drop"); + } + self.dropped = true; + self.count.set(self.count.get() + 1); + } +} diff --git a/library/core/tests/iter/adapters/skip.rs b/library/core/tests/iter/adapters/skip.rs index 65f235e86..754641834 100644 --- a/library/core/tests/iter/adapters/skip.rs +++ b/library/core/tests/iter/adapters/skip.rs @@ -201,3 +201,34 @@ fn test_skip_non_fused() { // advance it further. `Unfuse` tests that this doesn't happen by panicking in that scenario. let _ = non_fused.skip(20).next(); } + +#[test] +fn test_skip_non_fused_nth_overflow() { + let non_fused = Unfuse::new(0..10); + + // Ensures that calling skip and `nth` where the sum would overflow does not fail for non-fused + // iterators. + let _ = non_fused.skip(20).nth(usize::MAX); +} + +#[test] +fn test_skip_overflow_wrapping() { + // Test to ensure even on overflowing on `skip+nth` the correct amount of elements are yielded. + struct WrappingIterator(usize); + + impl Iterator for WrappingIterator { + type Item = usize; + + fn next(&mut self) -> core::option::Option { + ::nth(self, 0) + } + + fn nth(&mut self, nth: usize) -> core::option::Option { + self.0 = self.0.wrapping_add(nth.wrapping_add(1)); + Some(self.0) + } + } + + let wrap = WrappingIterator(0); + assert_eq!(wrap.skip(20).nth(usize::MAX), Some(20)); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index db94368f6..4a0e162bc 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -3,6 +3,7 @@ #![feature(array_methods)] #![feature(array_windows)] #![feature(bench_black_box)] +#![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(const_assume)] #![feature(const_black_box)] @@ -14,6 +15,7 @@ #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] #![feature(const_num_from_num)] +#![feature(const_pointer_byte_offsets)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_read)] #![feature(const_ptr_write)] @@ -61,6 +63,7 @@ #![feature(slice_partition_dedup)] #![feature(int_log)] #![feature(iter_advance_by)] +#![feature(iter_array_chunks)] #![feature(iter_collect_into)] #![feature(iter_partition_in_place)] #![feature(iter_intersperse)] @@ -73,7 +76,7 @@ #![feature(const_pin)] #![feature(never_type)] #![feature(unwrap_infallible)] -#![feature(result_into_ok_or_err)] +#![feature(pointer_byte_offsets)] #![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(once_cell)] @@ -96,6 +99,7 @@ #![feature(waker_getters)] #![feature(slice_flatten)] #![feature(provide_any)] +#![feature(utf8_chunks)] #![deny(unsafe_op_in_unsafe_fn)] extern crate test; diff --git a/library/core/tests/num/int_log.rs b/library/core/tests/num/int_log.rs index dc3092e14..be203fb5c 100644 --- a/library/core/tests/num/int_log.rs +++ b/library/core/tests/num/int_log.rs @@ -1,166 +1,166 @@ -//! This tests the `Integer::{log,log2,log10}` methods. These tests are in a +//! This tests the `Integer::{ilog,log2,log10}` methods. These tests are in a //! separate file because there's both a large number of them, and not all tests -//! can be run on Android. This is because in Android `log2` uses an imprecise +//! can be run on Android. This is because in Android `ilog2` uses an imprecise //! approximation:https://github.com/rust-lang/rust/blob/4825e12fc9c79954aa0fe18f5521efa6c19c7539/src/libstd/sys/unix/android.rs#L27-L53 #[test] -fn checked_log() { - assert_eq!(999u32.checked_log(10), Some(2)); - assert_eq!(1000u32.checked_log(10), Some(3)); - assert_eq!(555u32.checked_log(13), Some(2)); - assert_eq!(63u32.checked_log(4), Some(2)); - assert_eq!(64u32.checked_log(4), Some(3)); - assert_eq!(10460353203u64.checked_log(3), Some(21)); - assert_eq!(10460353202u64.checked_log(3), Some(20)); - assert_eq!(147808829414345923316083210206383297601u128.checked_log(3), Some(80)); - assert_eq!(147808829414345923316083210206383297600u128.checked_log(3), Some(79)); - assert_eq!(22528399544939174411840147874772641u128.checked_log(19683), Some(8)); - assert_eq!(22528399544939174411840147874772631i128.checked_log(19683), Some(7)); - - assert_eq!(0u8.checked_log(4), None); - assert_eq!(0u16.checked_log(4), None); - assert_eq!(0i8.checked_log(4), None); - assert_eq!(0i16.checked_log(4), None); +fn checked_ilog() { + assert_eq!(999u32.checked_ilog(10), Some(2)); + assert_eq!(1000u32.checked_ilog(10), Some(3)); + assert_eq!(555u32.checked_ilog(13), Some(2)); + assert_eq!(63u32.checked_ilog(4), Some(2)); + assert_eq!(64u32.checked_ilog(4), Some(3)); + assert_eq!(10460353203u64.checked_ilog(3), Some(21)); + assert_eq!(10460353202u64.checked_ilog(3), Some(20)); + assert_eq!(147808829414345923316083210206383297601u128.checked_ilog(3), Some(80)); + assert_eq!(147808829414345923316083210206383297600u128.checked_ilog(3), Some(79)); + assert_eq!(22528399544939174411840147874772641u128.checked_ilog(19683), Some(8)); + assert_eq!(22528399544939174411840147874772631i128.checked_ilog(19683), Some(7)); + + assert_eq!(0u8.checked_ilog(4), None); + assert_eq!(0u16.checked_ilog(4), None); + assert_eq!(0i8.checked_ilog(4), None); + assert_eq!(0i16.checked_ilog(4), None); #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_log(4), None); + assert_eq!(i.checked_ilog(4), None); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as u32)); + assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32)); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as u32)); + assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32)); } } #[test] -fn checked_log2() { - assert_eq!(5u32.checked_log2(), Some(2)); - assert_eq!(0u64.checked_log2(), None); - assert_eq!(128i32.checked_log2(), Some(7)); - assert_eq!((-55i16).checked_log2(), None); +fn checked_ilog2() { + assert_eq!(5u32.checked_ilog2(), Some(2)); + assert_eq!(0u64.checked_ilog2(), None); + assert_eq!(128i32.checked_ilog2(), Some(7)); + assert_eq!((-55i16).checked_ilog2(), None); - assert_eq!(0u8.checked_log2(), None); - assert_eq!(0u16.checked_log2(), None); - assert_eq!(0i8.checked_log2(), None); - assert_eq!(0i16.checked_log2(), None); + assert_eq!(0u8.checked_ilog2(), None); + assert_eq!(0u16.checked_ilog2(), None); + assert_eq!(0i8.checked_ilog2(), None); + assert_eq!(0i16.checked_ilog2(), None); for i in 1..=u8::MAX { - assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - // Guard against Android's imprecise f32::log2 implementation. + // Guard against Android's imprecise f32::ilog2 implementation. if i != 8192 && i != 32768 { - assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); } } for i in i8::MIN..=0 { - assert_eq!(i.checked_log2(), None); + assert_eq!(i.checked_ilog2(), None); } for i in 1..=i8::MAX { - assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); } #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_log2(), None); + assert_eq!(i.checked_ilog2(), None); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - // Guard against Android's imprecise f32::log2 implementation. + // Guard against Android's imprecise f32::ilog2 implementation. if i != 8192 { - assert_eq!(i.checked_log2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); } } } -// Validate cases that fail on Android's imprecise float log2 implementation. +// Validate cases that fail on Android's imprecise float ilog2 implementation. #[test] #[cfg(not(target_os = "android"))] -fn checked_log2_not_android() { - assert_eq!(8192u16.checked_log2(), Some((8192f32).log2() as u32)); - assert_eq!(32768u16.checked_log2(), Some((32768f32).log2() as u32)); - assert_eq!(8192i16.checked_log2(), Some((8192f32).log2() as u32)); +fn checked_ilog2_not_android() { + assert_eq!(8192u16.checked_ilog2(), Some((8192f32).log2() as u32)); + assert_eq!(32768u16.checked_ilog2(), Some((32768f32).log2() as u32)); + assert_eq!(8192i16.checked_ilog2(), Some((8192f32).log2() as u32)); } #[test] -fn checked_log10() { - assert_eq!(0u8.checked_log10(), None); - assert_eq!(0u16.checked_log10(), None); - assert_eq!(0i8.checked_log10(), None); - assert_eq!(0i16.checked_log10(), None); +fn checked_ilog10() { + assert_eq!(0u8.checked_ilog10(), None); + assert_eq!(0u16.checked_ilog10(), None); + assert_eq!(0i8.checked_ilog10(), None); + assert_eq!(0i16.checked_ilog10(), None); #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_log10(), None); + assert_eq!(i.checked_ilog10(), None); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); } #[cfg(not(miri))] // Miri is too slow for i in 1..=100_000u32 { - assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); } } -macro_rules! log10_loop { - ($T:ty, $log10_max:expr) => { - assert_eq!(<$T>::MAX.log10(), $log10_max); - for i in 0..=$log10_max { +macro_rules! ilog10_loop { + ($T:ty, $ilog10_max:expr) => { + assert_eq!(<$T>::MAX.ilog10(), $ilog10_max); + for i in 0..=$ilog10_max { let p = (10 as $T).pow(i as u32); if p >= 10 { - assert_eq!((p - 9).log10(), i - 1); - assert_eq!((p - 1).log10(), i - 1); + assert_eq!((p - 9).ilog10(), i - 1); + assert_eq!((p - 1).ilog10(), i - 1); } - assert_eq!(p.log10(), i); - assert_eq!((p + 1).log10(), i); + assert_eq!(p.ilog10(), i); + assert_eq!((p + 1).ilog10(), i); if p >= 10 { - assert_eq!((p + 9).log10(), i); + assert_eq!((p + 9).ilog10(), i); } - // also check `x.log(10)` + // also check `x.ilog(10)` if p >= 10 { - assert_eq!((p - 9).log(10), i - 1); - assert_eq!((p - 1).log(10), i - 1); + assert_eq!((p - 9).ilog(10), i - 1); + assert_eq!((p - 1).ilog(10), i - 1); } - assert_eq!(p.log(10), i); - assert_eq!((p + 1).log(10), i); + assert_eq!(p.ilog(10), i); + assert_eq!((p + 1).ilog(10), i); if p >= 10 { - assert_eq!((p + 9).log(10), i); + assert_eq!((p + 9).ilog(10), i); } } }; } #[test] -fn log10_u8() { - log10_loop! { u8, 2 } +fn ilog10_u8() { + ilog10_loop! { u8, 2 } } #[test] -fn log10_u16() { - log10_loop! { u16, 4 } +fn ilog10_u16() { + ilog10_loop! { u16, 4 } } #[test] -fn log10_u32() { - log10_loop! { u32, 9 } +fn ilog10_u32() { + ilog10_loop! { u32, 9 } } #[test] -fn log10_u64() { - log10_loop! { u64, 19 } +fn ilog10_u64() { + ilog10_loop! { u64, 19 } } #[test] -fn log10_u128() { - log10_loop! { u128, 38 } +fn ilog10_u128() { + ilog10_loop! { u128, 38 } } diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 8b84a78e6..18c55e43a 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -338,6 +338,32 @@ macro_rules! int_module { assert_eq!(MIN.checked_next_multiple_of(-3), None); assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN)); } + + #[test] + fn test_carrying_add() { + assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true)); + assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true)); + assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true)); + assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false)); + assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow + assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true)); + assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow + assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true)); + assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false)); + } + + #[test] + fn test_borrowing_sub() { + assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); + assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false)); + assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow + assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true)); + assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow + assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true)); + assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false)); + } } }; } diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 93ae620c2..15ae9f232 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -230,6 +230,28 @@ macro_rules! uint_module { assert_eq!((1 as $T).checked_next_multiple_of(0), None); assert_eq!(MAX.checked_next_multiple_of(2), None); } + + #[test] + fn test_carrying_add() { + assert_eq!($T::MAX.carrying_add(1, false), (0, true)); + assert_eq!($T::MAX.carrying_add(0, true), (0, true)); + assert_eq!($T::MAX.carrying_add(1, true), (1, true)); + + assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false)); + assert_eq!($T::MIN.carrying_add(0, true), (1, false)); + assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true)); + } + + #[test] + fn test_borrowing_sub() { + assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); + + assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false)); + assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false)); + assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true)); + } } }; } diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 12861794c..97a369810 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -650,7 +650,7 @@ fn thin_box() { .unwrap_or_else(|| handle_alloc_error(layout)) .cast::>(); ptr.as_ptr().write(meta); - ptr.cast::().as_ptr().add(offset).cast::().write(value); + ptr.as_ptr().byte_add(offset).cast::().write(value); Self { ptr, phantom: PhantomData } } } diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs index 103e8cc3a..50926da3c 100644 --- a/library/core/tests/result.rs +++ b/library/core/tests/result.rs @@ -95,15 +95,6 @@ fn test_unwrap_or() { assert_eq!(ok_err.unwrap_or(50), 50); } -#[test] -fn test_ok_or_err() { - let ok: Result = Ok(100); - let err: Result = Err(200); - - assert_eq!(ok.into_ok_or_err(), 100); - assert_eq!(err.into_ok_or_err(), 200); -} - #[test] fn test_unwrap_or_else() { fn handler(msg: &'static str) -> isize { diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 0656109e9..b8f6fe696 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1197,7 +1197,6 @@ fn chunks_mut_are_send_and_sync() { use std::slice::{ChunksExactMut, ChunksMut, RChunksExactMut, RChunksMut}; use std::sync::MutexGuard; - #[allow(unused)] fn assert_send_and_sync() where ChunksMut<'static, Cell>: Send, @@ -1210,6 +1209,8 @@ fn chunks_mut_are_send_and_sync() { RChunksExactMut<'static, MutexGuard<'static, u32>>: Sync, { } + + assert_send_and_sync(); } #[test] diff --git a/library/core/tests/str_lossy.rs b/library/core/tests/str_lossy.rs index d4b47a470..9d3f0b65f 100644 --- a/library/core/tests/str_lossy.rs +++ b/library/core/tests/str_lossy.rs @@ -1,85 +1,85 @@ -use core::str::lossy::*; +use core::str::Utf8Chunks; #[test] fn chunks() { - let mut iter = Utf8Lossy::from_bytes(b"hello").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); + macro_rules! assert_chunks { + ( $string:expr, $(($valid:expr, $invalid:expr)),* $(,)? ) => {{ + let mut iter = Utf8Chunks::new($string); + $( + let chunk = iter.next().expect("missing chunk"); + assert_eq!($valid, chunk.valid()); + assert_eq!($invalid, chunk.invalid()); + )* + assert_eq!(None, iter.next()); + }}; + } - let mut iter = Utf8Lossy::from_bytes("ศไทย中华Việt Nam".as_bytes()).chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "ศไทย中华Việt Nam", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"Hello\xC2 There\xFF Goodbye").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC2" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xFF" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC0" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xE6\x83" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"\xF5foo\xF5\x80bar").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF5" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF5" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"\xF1foo\xF1\x80bar\xF1\x80\x80baz").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF1" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF1\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF1\x80\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"\xF4foo\xF4\x80bar\xF4\xBFbaz").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF4" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF4\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF4" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); - - let mut iter = Utf8Lossy::from_bytes(b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF0" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "foo\u{10000}bar", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); + assert_chunks!(b"hello", ("hello", b"")); + assert_chunks!("ศไทย中华Việt Nam".as_bytes(), ("ศไทย中华Việt Nam", b"")); + assert_chunks!( + b"Hello\xC2 There\xFF Goodbye", + ("Hello", b"\xC2"), + (" There", b"\xFF"), + (" Goodbye", b""), + ); + assert_chunks!( + b"Hello\xC0\x80 There\xE6\x83 Goodbye", + ("Hello", b"\xC0"), + ("", b"\x80"), + (" There", b"\xE6\x83"), + (" Goodbye", b""), + ); + assert_chunks!( + b"\xF5foo\xF5\x80bar", + ("", b"\xF5"), + ("foo", b"\xF5"), + ("", b"\x80"), + ("bar", b""), + ); + assert_chunks!( + b"\xF1foo\xF1\x80bar\xF1\x80\x80baz", + ("", b"\xF1"), + ("foo", b"\xF1\x80"), + ("bar", b"\xF1\x80\x80"), + ("baz", b""), + ); + assert_chunks!( + b"\xF4foo\xF4\x80bar\xF4\xBFbaz", + ("", b"\xF4"), + ("foo", b"\xF4\x80"), + ("bar", b"\xF4"), + ("", b"\xBF"), + ("baz", b""), + ); + assert_chunks!( + b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar", + ("", b"\xF0"), + ("", b"\x80"), + ("", b"\x80"), + ("", b"\x80"), + ("foo\u{10000}bar", b""), + ); // surrogates - let mut iter = Utf8Lossy::from_bytes(b"\xED\xA0\x80foo\xED\xBF\xBFbar").chunks(); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xED" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xA0" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xED" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next()); - assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next()); - assert_eq!(None, iter.next()); -} - -#[test] -fn display() { - assert_eq!( - "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", - &Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string() + assert_chunks!( + b"\xED\xA0\x80foo\xED\xBF\xBFbar", + ("", b"\xED"), + ("", b"\xA0"), + ("", b"\x80"), + ("foo", b"\xED"), + ("", b"\xBF"), + ("", b"\xBF"), + ("bar", b""), ); } #[test] fn debug() { assert_eq!( - "\"Hello\\xc0\\x80 There\\xe6\\x83 Goodbye\\u{10d4ea}\"", + "\"Hello\\xC0\\x80 There\\xE6\\x83 Goodbye\\u{10d4ea}\"", &format!( "{:?}", - Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa") - ) + Utf8Chunks::new(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa").debug(), + ), ); } -- cgit v1.2.3