Auto merge of #67184 - tmandry:rollup-mzqxtck, r=tmandry

Rollup of 11 pull requests

Successful merges:

 - #66892 (Format libcore with rustfmt (including tests and benches))
 - #67106 (resolve: Resolve visibilities on fields with non-builtin attributes)
 - #67113 (Print the visibility in `print_variant`.)
 - #67115 (Simplify `check_decl_no_pat`.)
 - #67119 (libstd miri tests: avoid warnings)
 - #67125 (Added ExactSizeIterator bound to return types)
 - #67138 (Simplify `Layout::extend_packed`)
 - #67145 (fix miri step debug printing)
 - #67149 (Do not ICE #67123)
 - #67155 (Move `Layout`s instead of binding by reference)
 - #67169 (inline some common methods on OsStr)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-12-10 02:41:00 +00:00
commit 975e83a32a
77 changed files with 1540 additions and 1274 deletions

View file

@ -22,7 +22,7 @@ fn allocate_zeroed() {
}
#[bench]
#[cfg(not(miri))] // Miri does not support benchmarks
#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn alloc_owned_small(b: &mut Bencher) {
b.iter(|| {
let _: Box<_> = box 10;

View file

@ -182,7 +182,7 @@ fn test_insert_prev() {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg(not(miri))] // Miri does not support threads
#[cfg_attr(miri, ignore)] // Miri does not support threads
fn test_send() {
let n = list_from(&[1, 2, 3]);
thread::spawn(move || {

View file

@ -3,7 +3,7 @@ use super::*;
use ::test;
#[bench]
#[cfg(not(miri))] // Miri does not support benchmarks
#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_push_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@ -16,7 +16,7 @@ fn bench_push_back_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg(not(miri))] // Miri does not support benchmarks
#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_push_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@ -29,7 +29,7 @@ fn bench_push_front_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg(not(miri))] // Miri does not support benchmarks
#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_pop_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
@ -43,7 +43,7 @@ fn bench_pop_back_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg(not(miri))] // Miri does not support benchmarks
#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_pop_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);

View file

@ -29,7 +29,7 @@ impl Drop for Canary {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg(not(miri))] // Miri does not support threads
#[cfg_attr(miri, ignore)] // Miri does not support threads
fn manually_share_arc() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = Arc::new(v);
@ -334,7 +334,7 @@ fn test_ptr_eq() {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg(not(miri))] // Miri does not support threads
#[cfg_attr(miri, ignore)] // Miri does not support threads
fn test_weak_count_locked() {
let mut a = Arc::new(atomic::AtomicBool::new(false));
let a2 = a.clone();

View file

@ -388,7 +388,7 @@ fn test_reverse() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_sort() {
let mut rng = thread_rng();
@ -1610,7 +1610,7 @@ fn panic_safe() {
let moduli = &[5, 20, 50];
#[cfg(miri)]
let lens = (1..13);
let lens = 1..13;
#[cfg(miri)]
let moduli = &[10];

View file

@ -166,7 +166,7 @@ fn test_join_for_different_lengths_with_long_separator() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_unsafe_slice() {
assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)});
assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)});
@ -483,8 +483,8 @@ mod slice_index {
}
#[test]
#[cfg(not(target_os = "emscripten"))] // hits an OOM
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(target_os = "emscripten", ignore)] // hits an OOM
#[cfg_attr(miri, ignore)] // Miri is too slow
fn simple_big() {
fn a_million_letter_x() -> String {
let mut i = 0;
@ -1069,7 +1069,7 @@ fn test_rev_iterator() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_chars_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
@ -1081,7 +1081,7 @@ fn test_chars_decoding() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_chars_rev_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
@ -1380,7 +1380,6 @@ fn test_bool_from_str() {
assert_eq!("not even a boolean".parse::<bool>().ok(), None);
}
#[cfg(not(miri))] // Miri is too slow
fn check_contains_all_substrings(s: &str) {
assert!(s.contains(""));
for i in 0..s.len() {
@ -1391,7 +1390,7 @@ fn check_contains_all_substrings(s: &str) {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn strslice_issue_16589() {
assert!("bananas".contains("nana"));
@ -1408,7 +1407,7 @@ fn strslice_issue_16878() {
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_strslice_contains() {
let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
check_contains_all_substrings(x);

View file

@ -523,7 +523,7 @@ fn test_reserve_exact() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
@ -601,7 +601,7 @@ fn test_try_reserve() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.

View file

@ -1080,7 +1080,7 @@ fn test_reserve_exact() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
@ -1183,7 +1183,7 @@ fn test_try_reserve() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.

View file

@ -1100,7 +1100,7 @@ fn test_reserve_exact_2() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
@ -1214,7 +1214,7 @@ fn test_try_reserve() {
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
// See that test for comments.

View file

@ -310,8 +310,7 @@ impl Layout {
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
let new_size = self.size().checked_add(next.size())
.ok_or(LayoutErr { private: () })?;
let layout = Layout::from_size_align(new_size, self.align())?;
Ok(layout)
Layout::from_size_align(new_size, self.align())
}
/// Creates a layout describing the record for a `[T; n]`.
@ -1143,9 +1142,9 @@ pub unsafe trait Alloc {
where Self: Sized
{
match Layout::array::<T>(n) {
Ok(ref layout) if layout.size() > 0 => {
Ok(layout) if layout.size() > 0 => {
unsafe {
self.alloc(layout.clone()).map(|p| p.cast())
self.alloc(layout).map(|p| p.cast())
}
}
_ => Err(AllocErr),
@ -1193,9 +1192,9 @@ pub unsafe trait Alloc {
where Self: Sized
{
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new)) {
(Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
(Ok(k_old), Ok(k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
debug_assert!(k_old.align() == k_new.align());
self.realloc(ptr.cast(), k_old.clone(), k_new.size()).map(NonNull::cast)
self.realloc(ptr.cast(), k_old, k_new.size()).map(NonNull::cast)
}
_ => {
Err(AllocErr)
@ -1227,8 +1226,8 @@ pub unsafe trait Alloc {
where Self: Sized
{
match Layout::array::<T>(n) {
Ok(ref k) if k.size() > 0 => {
Ok(self.dealloc(ptr.cast(), k.clone()))
Ok(k) if k.size() > 0 => {
Ok(self.dealloc(ptr.cast(), k))
}
_ => {
Err(AllocErr)

View file

@ -1,5 +1,5 @@
use core::any::*;
use test::{Bencher, black_box};
use test::{black_box, Bencher};
#[bench]
fn bench_downcast_ref(b: &mut Bencher) {

View file

@ -22,17 +22,9 @@
//
// Therefore:
fn branchless_to_ascii_upper_case(byte: u8) -> u8 {
byte &
!(
(
byte.wrapping_add(0x1f) &
!byte.wrapping_add(0x05) &
0x80
) >> 2
)
byte & !((byte.wrapping_add(0x1f) & !byte.wrapping_add(0x05) & 0x80) >> 2)
}
macro_rules! benches {
($( fn $name: ident($arg: ident: &mut [u8]) $body: block )+ @iter $( $is_: ident, )+) => {
benches! {@
@ -254,12 +246,15 @@ benches! {
}
macro_rules! repeat {
($s: expr) => { concat!($s, $s, $s, $s, $s, $s, $s, $s, $s, $s) }
($s: expr) => {
concat!($s, $s, $s, $s, $s, $s, $s, $s, $s, $s)
};
}
const SHORT: &'static str = "Alice's";
const MEDIUM: &'static str = "Alice's Adventures in Wonderland";
const LONG: &'static str = repeat!(r#"
const LONG: &'static str = repeat!(
r#"
La Guida di Bragia, a Ballad Opera for the Marionette Theatre (around 1850)
Alice's Adventures in Wonderland (1865)
Phantasmagoria and Other Poems (1869)
@ -275,8 +270,10 @@ const LONG: &'static str = repeat!(r#"
What the Tortoise Said to Achilles (1895)
Three Sunsets and Other Poems (1898)
The Manlet (1903)[106]
"#);
"#
);
#[rustfmt::skip]
const ASCII_UPPERCASE_MAP: [u8; 256] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@ -330,6 +327,7 @@ enum AsciiCharacterClass {
}
use self::AsciiCharacterClass::*;
#[rustfmt::skip]
static ASCII_CHARACTER_CLASS: [AsciiCharacterClass; 256] = [
// _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f
C, C, C, C, C, C, C, C, C, Cw,Cw,C, Cw,Cw,C, C, // 0_

View file

@ -25,8 +25,13 @@ fn bench_to_digit_radix_36(b: &mut Bencher) {
#[bench]
fn bench_to_digit_radix_var(b: &mut Bencher) {
b.iter(|| CHARS.iter().cycle()
.zip(RADIX.iter().cycle())
.take(10_000)
.map(|(c, radix)| c.to_digit(*radix)).min())
b.iter(|| {
CHARS
.iter()
.cycle()
.zip(RADIX.iter().cycle())
.take(10_000)
.map(|(c, radix)| c.to_digit(*radix))
.min()
})
}

View file

@ -1,5 +1,5 @@
use std::io::{self, Write as IoWrite};
use std::fmt::{self, Write as FmtWrite};
use std::io::{self, Write as IoWrite};
use test::Bencher;
#[bench]

View file

@ -1,7 +1,7 @@
#![allow(deprecated)]
use core::hash::*;
use test::{Bencher, black_box};
use test::{black_box, Bencher};
fn hash_bytes<H: Hasher>(mut s: H, x: &[u8]) -> u64 {
Hasher::write(&mut s, x);
@ -44,11 +44,11 @@ fn bench_str_over_8_bytes(b: &mut Bencher) {
#[bench]
fn bench_long_str(b: &mut Bencher) {
let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
officia deserunt mollit anim id est laborum.";
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
officia deserunt mollit anim id est laborum.";
b.iter(|| {
assert_eq!(hash(&s), 17717065544121360093);
})
@ -58,9 +58,7 @@ officia deserunt mollit anim id est laborum.";
fn bench_u32(b: &mut Bencher) {
let u = 162629500u32;
let u = black_box(u);
b.iter(|| {
hash(&u)
});
b.iter(|| hash(&u));
b.bytes = 8;
}
@ -70,9 +68,7 @@ fn bench_u32_keyed(b: &mut Bencher) {
let u = black_box(u);
let k1 = black_box(0x1);
let k2 = black_box(0x2);
b.iter(|| {
hash_with(SipHasher::new_with_keys(k1, k2), &u)
});
b.iter(|| hash_with(SipHasher::new_with_keys(k1, k2), &u));
b.bytes = 8;
}
@ -80,62 +76,48 @@ fn bench_u32_keyed(b: &mut Bencher) {
fn bench_u64(b: &mut Bencher) {
let u = 16262950014981195938u64;
let u = black_box(u);
b.iter(|| {
hash(&u)
});
b.iter(|| hash(&u));
b.bytes = 8;
}
#[bench]
fn bench_bytes_4(b: &mut Bencher) {
let data = black_box([b' '; 4]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 4;
}
#[bench]
fn bench_bytes_7(b: &mut Bencher) {
let data = black_box([b' '; 7]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 7;
}
#[bench]
fn bench_bytes_8(b: &mut Bencher) {
let data = black_box([b' '; 8]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 8;
}
#[bench]
fn bench_bytes_a_16(b: &mut Bencher) {
let data = black_box([b' '; 16]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 16;
}
#[bench]
fn bench_bytes_b_32(b: &mut Bencher) {
let data = black_box([b' '; 32]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 32;
}
#[bench]
fn bench_bytes_c_128(b: &mut Bencher) {
let data = black_box([b' '; 128]);
b.iter(|| {
hash_bytes(SipHasher::default(), &data)
});
b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 128;
}

View file

@ -1,5 +1,5 @@
use core::iter::*;
use test::{Bencher, black_box};
use test::{black_box, Bencher};
#[bench]
fn bench_rposition(b: &mut Bencher) {
@ -14,7 +14,11 @@ fn bench_skip_while(b: &mut Bencher) {
b.iter(|| {
let it = 0..100;
let mut sum = 0;
it.skip_while(|&x| { sum += x; sum < 4000 }).all(|_| true);
it.skip_while(|&x| {
sum += x;
sum < 4000
})
.all(|_| true);
});
}
@ -29,7 +33,9 @@ fn bench_multiple_take(b: &mut Bencher) {
});
}
fn scatter(x: i32) -> i32 { (x * 31) % 127 }
fn scatter(x: i32) -> i32 {
(x * 31) % 127
}
#[bench]
fn bench_max_by_key(b: &mut Bencher) {
@ -76,23 +82,21 @@ pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
fn bench_zip_copy(b: &mut Bencher) {
let source = vec![0u8; 16 * 1024];
let mut dst = black_box(vec![0u8; 16 * 1024]);
b.iter(|| {
copy_zip(&source, &mut dst)
})
b.iter(|| copy_zip(&source, &mut dst))
}
#[bench]
fn bench_zip_add(b: &mut Bencher) {
let source = vec![1.; 16 * 1024];
let mut dst = vec![0.; 16 * 1024];
b.iter(|| {
add_zip(&source, &mut dst)
});
b.iter(|| add_zip(&source, &mut dst));
}
/// `Iterator::for_each` implemented as a plain loop.
fn for_each_loop<I, F>(iter: I, mut f: F) where
I: Iterator, F: FnMut(I::Item)
fn for_each_loop<I, F>(iter: I, mut f: F)
where
I: Iterator,
F: FnMut(I::Item),
{
for item in iter {
f(item);
@ -101,8 +105,10 @@ fn for_each_loop<I, F>(iter: I, mut f: F) where
/// `Iterator::for_each` implemented with `fold` for internal iteration.
/// (except when `by_ref()` effectively disables that optimization.)
fn for_each_fold<I, F>(iter: I, mut f: F) where
I: Iterator, F: FnMut(I::Item)
fn for_each_fold<I, F>(iter: I, mut f: F)
where
I: Iterator,
F: FnMut(I::Item),
{
iter.fold((), move |(), item| f(item));
}
@ -137,25 +143,20 @@ fn bench_for_each_chain_ref_fold(b: &mut Bencher) {
});
}
/// Helper to benchmark `sum` for iterators taken by value which
/// can optimize `fold`, and by reference which cannot.
macro_rules! bench_sums {
($bench_sum:ident, $bench_ref_sum:ident, $iter:expr) => {
#[bench]
fn $bench_sum(b: &mut Bencher) {
b.iter(|| -> i64 {
$iter.map(black_box).sum()
});
b.iter(|| -> i64 { $iter.map(black_box).sum() });
}
#[bench]
fn $bench_ref_sum(b: &mut Bencher) {
b.iter(|| -> i64 {
$iter.map(black_box).by_ref().sum()
});
b.iter(|| -> i64 { $iter.map(black_box).by_ref().sum() });
}
}
};
}
bench_sums! {
@ -286,7 +287,10 @@ fn bench_zip_then_skip(b: &mut Bencher) {
let t: Vec<_> = (0..100_000).collect();
b.iter(|| {
let s = v.iter().zip(t.iter()).skip(10000)
let s = v
.iter()
.zip(t.iter())
.skip(10000)
.take_while(|t| *t.0 < 10100)
.map(|(a, b)| *a + *b)
.sum::<u64>();
@ -299,7 +303,10 @@ fn bench_skip_then_zip(b: &mut Bencher) {
let t: Vec<_> = (0..100_000).collect();
b.iter(|| {
let s = v.iter().skip(10000).zip(t.iter().skip(10000))
let s = v
.iter()
.skip(10000)
.zip(t.iter().skip(10000))
.take_while(|t| *t.0 < 10100)
.map(|(a, b)| *a + *b)
.sum::<u64>();
@ -309,23 +316,17 @@ fn bench_skip_then_zip(b: &mut Bencher) {
#[bench]
fn bench_filter_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count()
})
b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())
}
#[bench]
fn bench_filter_ref_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
})
b.iter(|| (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count())
}
#[bench]
fn bench_filter_chain_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count()
})
b.iter(|| (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count())
}
#[bench]

View file

@ -6,9 +6,9 @@ extern crate test;
mod any;
mod ascii;
mod char;
mod fmt;
mod hash;
mod iter;
mod num;
mod ops;
mod slice;
mod fmt;

View file

@ -3,17 +3,17 @@ mod strategy {
mod grisu;
}
use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
use std::f64;
use std::io::Write;
use std::vec::Vec;
use test::Bencher;
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
use core::num::flt2dec::MAX_SIG_DIGITS;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}

View file

@ -1,6 +1,6 @@
use std::{i16, f64};
use super::super::*;
use core::num::flt2dec::strategy::dragon::*;
use std::{f64, i16};
use test::Bencher;
#[bench]

View file

@ -1,12 +1,12 @@
use std::{i16, f64};
use super::super::*;
use core::num::flt2dec::strategy::grisu::*;
use std::{f64, i16};
use test::Bencher;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}

View file

@ -1,8 +1,8 @@
mod flt2dec;
mod dec2flt;
mod flt2dec;
use test::Bencher;
use std::str::FromStr;
use test::Bencher;
const ASCII_NUMBERS: [&str; 19] = [
"0",
@ -27,7 +27,7 @@ const ASCII_NUMBERS: [&str; 19] = [
];
macro_rules! from_str_bench {
($mac:ident, $t:ty) => (
($mac:ident, $t:ty) => {
#[bench]
fn $mac(b: &mut Bencher) {
b.iter(|| {
@ -39,11 +39,11 @@ macro_rules! from_str_bench {
.max()
})
}
)
};
}
macro_rules! from_str_radix_bench {
($mac:ident, $t:ty, $radix:expr) => (
($mac:ident, $t:ty, $radix:expr) => {
#[bench]
fn $mac(b: &mut Bencher) {
b.iter(|| {
@ -55,7 +55,7 @@ macro_rules! from_str_radix_bench {
.max()
})
}
)
};
}
from_str_bench!(bench_u8_from_str, u8);

View file

@ -4,17 +4,16 @@ use test::Bencher;
// Overhead of dtors
struct HasDtor {
_x: isize
_x: isize,
}
impl Drop for HasDtor {
fn drop(&mut self) {
}
fn drop(&mut self) {}
}
#[bench]
fn alloc_obj_with_dtor(b: &mut Bencher) {
b.iter(|| {
HasDtor { _x : 10 };
HasDtor { _x: 10 };
})
}

View file

@ -8,11 +8,12 @@ enum Cache {
}
fn binary_search<F>(b: &mut Bencher, cache: Cache, mapper: F)
where F: Fn(usize) -> usize
where
F: Fn(usize) -> usize,
{
let size = match cache {
Cache::L1 => 1000, // 8kb
Cache::L2 => 10_000, // 80kb
Cache::L1 => 1000, // 8kb
Cache::L2 => 10_000, // 80kb
Cache::L3 => 1_000_000, // 8Mb
};
let v = (0..size).map(&mapper).collect::<Vec<_>>();

View file

@ -15,11 +15,7 @@ impl bool {
#[unstable(feature = "bool_to_option", issue = "64260")]
#[inline]
pub fn then_some<T>(self, t: T) -> Option<T> {
if self {
Some(t)
} else {
None
}
if self { Some(t) } else { None }
}
/// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise.
@ -35,10 +31,6 @@ impl bool {
#[unstable(feature = "bool_to_option", issue = "64260")]
#[inline]
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
if self {
Some(f())
} else {
None
}
if self { Some(f()) } else { None }
}
}

View file

@ -146,7 +146,6 @@ impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.2
// https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
// Note: integers can only be represented with full precision in a float if
// they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
// Lossy float conversions are not implemented at this time.

View file

@ -64,31 +64,27 @@ pub unsafe fn unreachable_unchecked() -> ! {
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {
#[cfg(
all(
any(target_arch = "x86", target_arch = "x86_64"),
target_feature = "sse2"
)
)] {
#[cfg(target_arch = "x86")] {
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
{
#[cfg(target_arch = "x86")]
{
unsafe { crate::arch::x86::_mm_pause() };
}
#[cfg(target_arch = "x86_64")] {
#[cfg(target_arch = "x86_64")]
{
unsafe { crate::arch::x86_64::_mm_pause() };
}
}
#[cfg(
any(
target_arch = "aarch64",
all(target_arch = "arm", target_feature = "v6")
)
)] {
#[cfg(target_arch = "aarch64")] {
#[cfg(any(target_arch = "aarch64", all(target_arch = "arm", target_feature = "v6")))]
{
#[cfg(target_arch = "aarch64")]
{
unsafe { crate::arch::aarch64::__yield() };
}
#[cfg(target_arch = "arm")] {
#[cfg(target_arch = "arm")]
{
unsafe { crate::arch::arm::__yield() };
}
}

View file

@ -91,9 +91,9 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
message="a value of type `{Self}` cannot be built from an iterator \
over elements of type `{A}`",
label="value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`",
message = "a value of type `{Self}` cannot be built from an iterator \
over elements of type `{A}`",
label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
)]
pub trait FromIterator<A>: Sized {
/// Creates a value from an iterator.
@ -116,7 +116,7 @@ pub trait FromIterator<A>: Sized {
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> Self;
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
/// Conversion into an `Iterator`.
@ -214,7 +214,7 @@ pub trait IntoIterator {
/// Which kind of iterator are we turning this into?
#[stable(feature = "rust1", since = "1.0.0")]
type IntoIter: Iterator<Item=Self::Item>;
type IntoIter: Iterator<Item = Self::Item>;
/// Creates an iterator from a value.
///
@ -340,7 +340,7 @@ pub trait Extend<A> {
/// assert_eq!("abcdef", &message);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T);
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);
}
#[stable(feature = "extend_for_unit", since = "1.28.0")]

View file

@ -439,7 +439,10 @@ impl f64 {
#[cfg(not(bootstrap))]
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
#[inline]
pub unsafe fn approx_unchecked_to<Int>(self) -> Int where Self: FloatToInt<Int> {
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
where
Self: FloatToInt<Int>,
{
FloatToInt::<Int>::approx_unchecked(self)
}

View file

@ -5,20 +5,28 @@
/// extracting those success or failure values from an existing instance and
/// creating a new instance from a success or failure value.
#[unstable(feature = "try_trait", issue = "42327")]
#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(all(
any(from_method="from_error", from_method="from_ok"),
from_desugaring="QuestionMark"),
message="the `?` operator can only be used in {ItemContext} \
that returns `Result` or `Option` \
(or another type that implements `{Try}`)",
label="cannot use the `?` operator in {ItemContext} that returns `{Self}`",
enclosing_scope="this function should return `Result` or `Option` to accept `?`"),
on(all(from_method="into_result", from_desugaring="QuestionMark"),
message="the `?` operator can only be applied to values \
that implement `{Try}`",
label="the `?` operator cannot be applied to type `{Self}`")
))]
#[cfg_attr(
not(bootstrap),
rustc_on_unimplemented(
on(
all(
any(from_method = "from_error", from_method = "from_ok"),
from_desugaring = "QuestionMark"
),
message = "the `?` operator can only be used in {ItemContext} \
that returns `Result` or `Option` \
(or another type that implements `{Try}`)",
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
),
on(
all(from_method = "into_result", from_desugaring = "QuestionMark"),
message = "the `?` operator can only be applied to values \
that implement `{Try}`",
label = "the `?` operator cannot be applied to type `{Self}`"
)
)
)]
#[doc(alias = "?")]
pub trait Try {
/// The type of this value when viewed as successful.

View file

@ -22,10 +22,12 @@
// ignore-tidy-undocumented-unsafe
#![allow(dead_code, missing_docs)]
#![unstable(feature = "core_panic",
reason = "internal details of the implementation of the `panic!` \
and related macros",
issue = "0")]
#![unstable(
feature = "core_panic",
reason = "internal details of the implementation of the `panic!` \
and related macros",
issue = "0"
)]
use crate::fmt;
use crate::panic::{Location, PanicInfo};
@ -33,7 +35,7 @@ use crate::panic::{Location, PanicInfo};
#[cold]
// never inline unless panic_immediate_abort to avoid code
// bloat at the call sites as much as possible
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
pub fn panic(expr: &str, location: &Location<'_>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
@ -50,7 +52,7 @@ pub fn panic(expr: &str, location: &Location<'_>) -> ! {
}
#[cold]
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
if cfg!(feature = "panic_immediate_abort") {
@ -59,13 +61,13 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
panic_fmt(
format_args!("index out of bounds: the len is {} but the index is {}", len, index),
location
location,
)
}
#[cold]
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
#[cfg_attr( feature="panic_immediate_abort" ,inline)]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[cfg_attr(feature = "panic_immediate_abort", inline)]
pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
unsafe { super::intrinsics::abort() }

View file

@ -65,15 +65,16 @@
//! [`write_volatile`]: ./fn.write_volatile.html
//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
// ignore-tidy-filelength
// ignore-tidy-undocumented-unsafe
#![stable(feature = "rust1", since = "1.0.0")]
use crate::intrinsics;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::fmt;
use crate::hash;
use crate::intrinsics;
use crate::mem::{self, MaybeUninit};
use crate::cmp::Ordering::{self, Less, Equal, Greater};
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::intrinsics::copy_nonoverlapping;
@ -197,7 +198,9 @@ unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
pub const fn null<T>() -> *const T { 0 as *const T }
pub const fn null<T>() -> *const T {
0 as *const T
}
/// Creates a null mutable raw pointer.
///
@ -212,7 +215,9 @@ pub const fn null<T>() -> *const T { 0 as *const T }
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
pub const fn null_mut<T>() -> *mut T {
0 as *mut T
}
#[repr(C)]
pub(crate) union Repr<T> {
@ -704,9 +709,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn read_unaligned<T>(src: *const T) -> T {
let mut tmp = MaybeUninit::<T>::uninit();
copy_nonoverlapping(src as *const u8,
tmp.as_mut_ptr() as *mut u8,
mem::size_of::<T>());
copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
tmp.assume_init()
}
@ -889,9 +892,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
copy_nonoverlapping(&src as *const T as *const u8,
dst as *mut u8,
mem::size_of::<T>());
copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
mem::forget(src);
}
@ -1122,11 +1123,7 @@ impl<T: ?Sized> *const T {
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&*self)
}
if self.is_null() { None } else { Some(&*self) }
}
/// Calculates the offset from a pointer.
@ -1182,7 +1179,10 @@ impl<T: ?Sized> *const T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
pub unsafe fn offset(self, count: isize) -> *const T
where
T: Sized,
{
intrinsics::offset(self, count)
}
@ -1237,10 +1237,11 @@ impl<T: ?Sized> *const T {
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized {
unsafe {
intrinsics::arith_offset(self, count)
}
pub fn wrapping_offset(self, count: isize) -> *const T
where
T: Sized,
{
unsafe { intrinsics::arith_offset(self, count) }
}
/// Calculates the distance between two pointers. The returned value is in
@ -1308,7 +1309,10 @@ impl<T: ?Sized> *const T {
#[unstable(feature = "ptr_offset_from", issue = "41079")]
#[rustc_const_unstable(feature = "const_ptr_offset_from")]
#[inline]
pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
pub const unsafe fn offset_from(self, origin: *const T) -> isize
where
T: Sized,
{
let pointee_size = mem::size_of::<T>();
let ok = 0 < pointee_size && pointee_size <= isize::max_value() as usize;
// assert that the pointee size is valid in a const eval compatible way
@ -1353,7 +1357,10 @@ impl<T: ?Sized> *const T {
/// ```
#[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
#[inline]
pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
pub fn wrapping_offset_from(self, origin: *const T) -> isize
where
T: Sized,
{
let pointee_size = mem::size_of::<T>();
assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
@ -1415,7 +1422,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.offset(count as isize)
}
@ -1475,7 +1483,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.offset((count as isize).wrapping_neg())
}
@ -1529,7 +1538,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.wrapping_offset(count as isize)
}
@ -1583,7 +1593,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.wrapping_offset((count as isize).wrapping_neg())
}
@ -1597,7 +1608,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
where T: Sized,
where
T: Sized,
{
read(self)
}
@ -1615,7 +1627,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
where T: Sized,
where
T: Sized,
{
read_volatile(self)
}
@ -1631,7 +1644,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
where T: Sized,
where
T: Sized,
{
read_unaligned(self)
}
@ -1647,7 +1661,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
where T: Sized,
where
T: Sized,
{
copy(self, dest, count)
}
@ -1663,7 +1678,8 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
where T: Sized,
where
T: Sized,
{
copy_nonoverlapping(self, dest, count)
}
@ -1708,17 +1724,17 @@ impl<T: ?Sized> *const T {
/// # } }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
pub fn align_offset(self, align: usize) -> usize where T: Sized {
pub fn align_offset(self, align: usize) -> usize
where
T: Sized,
{
if !align.is_power_of_two() {
panic!("align_offset: align is not a power-of-two");
}
unsafe {
align_offset(self, align)
}
unsafe { align_offset(self, align) }
}
}
#[lang = "mut_ptr"]
impl<T: ?Sized> *mut T {
/// Returns `true` if the pointer is null.
@ -1805,11 +1821,7 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&*self)
}
if self.is_null() { None } else { Some(&*self) }
}
/// Calculates the offset from a pointer.
@ -1865,7 +1877,10 @@ impl<T: ?Sized> *mut T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
pub unsafe fn offset(self, count: isize) -> *mut T
where
T: Sized,
{
intrinsics::offset(self, count) as *mut T
}
@ -1919,10 +1934,11 @@ impl<T: ?Sized> *mut T {
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
pub fn wrapping_offset(self, count: isize) -> *mut T where T: Sized {
unsafe {
intrinsics::arith_offset(self, count) as *mut T
}
pub fn wrapping_offset(self, count: isize) -> *mut T
where
T: Sized,
{
unsafe { intrinsics::arith_offset(self, count) as *mut T }
}
/// Returns `None` if the pointer is null, or else returns a mutable
@ -1967,11 +1983,7 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
if self.is_null() {
None
} else {
Some(&mut *self)
}
if self.is_null() { None } else { Some(&mut *self) }
}
/// Calculates the distance between two pointers. The returned value is in
@ -2039,7 +2051,10 @@ impl<T: ?Sized> *mut T {
#[unstable(feature = "ptr_offset_from", issue = "41079")]
#[rustc_const_unstable(feature = "const_ptr_offset_from")]
#[inline]
pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
pub const unsafe fn offset_from(self, origin: *const T) -> isize
where
T: Sized,
{
(self as *const T).offset_from(origin)
}
@ -2079,7 +2094,10 @@ impl<T: ?Sized> *mut T {
/// ```
#[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
#[inline]
pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
pub fn wrapping_offset_from(self, origin: *const T) -> isize
where
T: Sized,
{
(self as *const T).wrapping_offset_from(origin)
}
@ -2137,7 +2155,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.offset(count as isize)
}
@ -2197,7 +2216,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.offset((count as isize).wrapping_neg())
}
@ -2251,7 +2271,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.wrapping_offset(count as isize)
}
@ -2305,7 +2326,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
where T: Sized,
where
T: Sized,
{
self.wrapping_offset((count as isize).wrapping_neg())
}
@ -2319,7 +2341,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
where T: Sized,
where
T: Sized,
{
read(self)
}
@ -2337,7 +2360,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
where T: Sized,
where
T: Sized,
{
read_volatile(self)
}
@ -2353,7 +2377,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
where T: Sized,
where
T: Sized,
{
read_unaligned(self)
}
@ -2369,7 +2394,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
where T: Sized,
where
T: Sized,
{
copy(self, dest, count)
}
@ -2385,7 +2411,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
where T: Sized,
where
T: Sized,
{
copy_nonoverlapping(self, dest, count)
}
@ -2401,7 +2428,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from(self, src: *const T, count: usize)
where T: Sized,
where
T: Sized,
{
copy(src, self, count)
}
@ -2417,7 +2445,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize)
where T: Sized,
where
T: Sized,
{
copy_nonoverlapping(src, self, count)
}
@ -2442,7 +2471,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write(self, val: T)
where T: Sized,
where
T: Sized,
{
write(self, val)
}
@ -2456,7 +2486,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_bytes(self, val: u8, count: usize)
where T: Sized,
where
T: Sized,
{
write_bytes(self, val, count)
}
@ -2474,7 +2505,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_volatile(self, val: T)
where T: Sized,
where
T: Sized,
{
write_volatile(self, val)
}
@ -2490,7 +2522,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_unaligned(self, val: T)
where T: Sized,
where
T: Sized,
{
write_unaligned(self, val)
}
@ -2504,7 +2537,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn replace(self, src: T) -> T
where T: Sized,
where
T: Sized,
{
replace(self, src)
}
@ -2519,7 +2553,8 @@ impl<T: ?Sized> *mut T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn swap(self, with: *mut T)
where T: Sized,
where
T: Sized,
{
swap(self, with)
}
@ -2564,13 +2599,14 @@ impl<T: ?Sized> *mut T {
/// # } }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
pub fn align_offset(self, align: usize) -> usize where T: Sized {
pub fn align_offset(self, align: usize) -> usize
where
T: Sized,
{
if !align.is_power_of_two() {
panic!("align_offset: align is not a power-of-two");
}
unsafe {
align_offset(self, align)
}
unsafe { align_offset(self, align) }
}
}
@ -2588,7 +2624,7 @@ impl<T: ?Sized> *mut T {
/// than trying to adapt this to accommodate that change.
///
/// Any questions go to @nagisa.
#[lang="align_offset"]
#[lang = "align_offset"]
pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
/// Calculate multiplicative modular inverse of `x` modulo `m`.
///
@ -2628,9 +2664,8 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
// uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
// usize::max_value()` instead, because we take the result `mod n` at the end
// anyway.
inverse = inverse.wrapping_mul(
2usize.wrapping_sub(x.wrapping_mul(inverse))
) & (going_mod - 1);
inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse)))
& (going_mod - 1);
if going_mod > m {
return inverse & (m - 1);
}
@ -2689,13 +2724,13 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
usize::max_value()
}
// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *const T {
#[inline]
fn eq(&self, other: &*const T) -> bool { *self == *other }
fn eq(&self, other: &*const T) -> bool {
*self == *other
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -2704,7 +2739,9 @@ impl<T: ?Sized> Eq for *const T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool { *self == *other }
fn eq(&self, other: &*mut T) -> bool {
*self == *other
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -2890,7 +2927,7 @@ macro_rules! fnptr_impls_args {
};
}
fnptr_impls_args! { }
fnptr_impls_args! {}
fnptr_impls_args! { A }
fnptr_impls_args! { A, B }
fnptr_impls_args! { A, B, C }
@ -2927,16 +2964,24 @@ impl<T: ?Sized> PartialOrd for *const T {
}
#[inline]
fn lt(&self, other: &*const T) -> bool { *self < *other }
fn lt(&self, other: &*const T) -> bool {
*self < *other
}
#[inline]
fn le(&self, other: &*const T) -> bool { *self <= *other }
fn le(&self, other: &*const T) -> bool {
*self <= *other
}
#[inline]
fn gt(&self, other: &*const T) -> bool { *self > *other }
fn gt(&self, other: &*const T) -> bool {
*self > *other
}
#[inline]
fn ge(&self, other: &*const T) -> bool { *self >= *other }
fn ge(&self, other: &*const T) -> bool {
*self >= *other
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -2961,14 +3006,22 @@ impl<T: ?Sized> PartialOrd for *mut T {
}
#[inline]
fn lt(&self, other: &*mut T) -> bool { *self < *other }
fn lt(&self, other: &*mut T) -> bool {
*self < *other
}
#[inline]
fn le(&self, other: &*mut T) -> bool { *self <= *other }
fn le(&self, other: &*mut T) -> bool {
*self <= *other
}
#[inline]
fn gt(&self, other: &*mut T) -> bool { *self > *other }
fn gt(&self, other: &*mut T) -> bool {
*self > *other
}
#[inline]
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
fn ge(&self, other: &*mut T) -> bool {
*self >= *other
}
}

View file

@ -24,11 +24,8 @@ fn any_referenced() {
#[test]
fn any_owning() {
let (a, b, c) = (
box 5_usize as Box<dyn Any>,
box TEST as Box<dyn Any>,
box Test as Box<dyn Any>,
);
let (a, b, c) =
(box 5_usize as Box<dyn Any>, box TEST as Box<dyn Any>, box Test as Box<dyn Any>);
assert!(a.is::<usize>());
assert!(!b.is::<usize>());
@ -49,12 +46,12 @@ fn any_downcast_ref() {
match a.downcast_ref::<usize>() {
Some(&5) => {}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match a.downcast_ref::<Test>() {
None => {}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
}
@ -72,7 +69,7 @@ fn any_downcast_mut() {
assert_eq!(*x, 5);
*x = 612;
}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<usize>() {
@ -80,27 +77,27 @@ fn any_downcast_mut() {
assert_eq!(*x, 7);
*x = 413;
}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match a_r.downcast_mut::<Test>() {
None => (),
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<Test>() {
None => (),
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match a_r.downcast_mut::<usize>() {
Some(&mut 612) => {}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<usize>() {
Some(&mut 413) => {}
x => panic!("Unexpected value {:?}", x)
x => panic!("Unexpected value {:?}", x),
}
}

View file

@ -41,7 +41,6 @@ fn array_try_from() {
}
}
#[test]
fn iterator_collect() {
let arr = [0, 1, 2, 5, 9];
@ -150,10 +149,7 @@ fn iterator_flat_map() {
#[test]
fn iterator_debug() {
let arr = [0, 1, 2, 5, 9];
assert_eq!(
format!("{:?}", IntoIter::new(arr)),
"IntoIter([0, 1, 2, 5, 9])",
);
assert_eq!(format!("{:?}", IntoIter::new(arr)), "IntoIter([0, 1, 2, 5, 9])",);
}
#[test]
@ -168,7 +164,7 @@ fn iterator_drops() {
struct Foo<'a>(&'a Cell<usize>);
impl Drop for Foo<'_> {
fn drop(&mut self) {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}

View file

@ -22,10 +22,12 @@ fn test_to_ascii_uppercase() {
assert_eq!("hıß".to_ascii_uppercase(), "Hıß");
for i in 0..501 {
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
(from_u32(upper).unwrap()).to_string());
let upper =
if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } else { i };
assert_eq!(
(from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
(from_u32(upper).unwrap()).to_string()
);
}
}
@ -36,23 +38,23 @@ fn test_to_ascii_lowercase() {
assert_eq!("ß".to_ascii_lowercase(), "ß");
for i in 0..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
(from_u32(lower).unwrap()).to_string());
let lower =
if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
assert_eq!(
(from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
(from_u32(lower).unwrap()).to_string()
);
}
}
#[test]
fn test_make_ascii_lower_case() {
macro_rules! test {
($from: expr, $to: expr) => {
{
let mut x = $from;
x.make_ascii_lowercase();
assert_eq!(x, $to);
}
}
($from: expr, $to: expr) => {{
let mut x = $from;
x.make_ascii_lowercase();
assert_eq!(x, $to);
}};
}
test!(b'A', b'a');
test!(b'a', b'a');
@ -65,17 +67,14 @@ fn test_make_ascii_lower_case() {
test!("ß".to_string(), "ß");
}
#[test]
fn test_make_ascii_upper_case() {
macro_rules! test {
($from: expr, $to: expr) => {
{
let mut x = $from;
x.make_ascii_uppercase();
assert_eq!(x, $to);
}
}
($from: expr, $to: expr) => {{
let mut x = $from;
x.make_ascii_uppercase();
assert_eq!(x, $to);
}};
}
test!(b'a', b'A');
test!(b'A', b'A');
@ -88,7 +87,7 @@ fn test_make_ascii_upper_case() {
test!("hıß".to_string(), "Hıß");
let mut x = "Hello".to_string();
x[..3].make_ascii_uppercase(); // Test IndexMut on String.
x[..3].make_ascii_uppercase(); // Test IndexMut on String.
assert_eq!(x, "HELlo")
}
@ -103,10 +102,13 @@ fn test_eq_ignore_ascii_case() {
assert!(!"ß".eq_ignore_ascii_case("s"));
for i in 0..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
&from_u32(lower).unwrap().to_string()));
let lower =
if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
assert!(
(from_u32(i).unwrap())
.to_string()
.eq_ignore_ascii_case(&from_u32(lower).unwrap().to_string())
);
}
}
@ -158,12 +160,14 @@ macro_rules! assert_none {
#[test]
fn test_is_ascii_alphabetic() {
assert_all!(is_ascii_alphabetic,
assert_all!(
is_ascii_alphabetic,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
);
assert_none!(is_ascii_alphabetic,
assert_none!(
is_ascii_alphabetic,
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
" \t\n\x0c\r",
@ -177,11 +181,9 @@ fn test_is_ascii_alphabetic() {
#[test]
fn test_is_ascii_uppercase() {
assert_all!(is_ascii_uppercase,
"",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
);
assert_none!(is_ascii_uppercase,
assert_all!(is_ascii_uppercase, "", "ABCDEFGHIJKLMNOQPRSTUVWXYZ",);
assert_none!(
is_ascii_uppercase,
"abcdefghijklmnopqrstuvwxyz",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@ -196,10 +198,9 @@ fn test_is_ascii_uppercase() {
#[test]
fn test_is_ascii_lowercase() {
assert_all!(is_ascii_lowercase,
"abcdefghijklmnopqrstuvwxyz",
);
assert_none!(is_ascii_lowercase,
assert_all!(is_ascii_lowercase, "abcdefghijklmnopqrstuvwxyz",);
assert_none!(
is_ascii_lowercase,
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@ -214,13 +215,15 @@ fn test_is_ascii_lowercase() {
#[test]
fn test_is_ascii_alphanumeric() {
assert_all!(is_ascii_alphanumeric,
assert_all!(
is_ascii_alphanumeric,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
);
assert_none!(is_ascii_alphanumeric,
assert_none!(
is_ascii_alphanumeric,
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
" \t\n\x0c\r",
"\x00\x01\x02\x03\x04\x05\x06\x07",
@ -233,11 +236,9 @@ fn test_is_ascii_alphanumeric() {
#[test]
fn test_is_ascii_digit() {
assert_all!(is_ascii_digit,
"",
"0123456789",
);
assert_none!(is_ascii_digit,
assert_all!(is_ascii_digit, "", "0123456789",);
assert_none!(
is_ascii_digit,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@ -252,12 +253,9 @@ fn test_is_ascii_digit() {
#[test]
fn test_is_ascii_hexdigit() {
assert_all!(is_ascii_hexdigit,
"",
"0123456789",
"abcdefABCDEF",
);
assert_none!(is_ascii_hexdigit,
assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",);
assert_none!(
is_ascii_hexdigit,
"ghijklmnopqrstuvwxyz",
"GHIJKLMNOQPRSTUVWXYZ",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@ -272,11 +270,9 @@ fn test_is_ascii_hexdigit() {
#[test]
fn test_is_ascii_punctuation() {
assert_all!(is_ascii_punctuation,
"",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
);
assert_none!(is_ascii_punctuation,
assert_all!(is_ascii_punctuation, "", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",);
assert_none!(
is_ascii_punctuation,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
@ -291,14 +287,16 @@ fn test_is_ascii_punctuation() {
#[test]
fn test_is_ascii_graphic() {
assert_all!(is_ascii_graphic,
assert_all!(
is_ascii_graphic,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
);
assert_none!(is_ascii_graphic,
assert_none!(
is_ascii_graphic,
" \t\n\x0c\r",
"\x00\x01\x02\x03\x04\x05\x06\x07",
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@ -310,11 +308,9 @@ fn test_is_ascii_graphic() {
#[test]
fn test_is_ascii_whitespace() {
assert_all!(is_ascii_whitespace,
"",
" \t\n\x0c\r",
);
assert_none!(is_ascii_whitespace,
assert_all!(is_ascii_whitespace, "", " \t\n\x0c\r",);
assert_none!(
is_ascii_whitespace,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
@ -329,7 +325,8 @@ fn test_is_ascii_whitespace() {
#[test]
fn test_is_ascii_control() {
assert_all!(is_ascii_control,
assert_all!(
is_ascii_control,
"",
"\x00\x01\x02\x03\x04\x05\x06\x07",
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@ -337,7 +334,8 @@ fn test_is_ascii_control() {
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x7f",
);
assert_none!(is_ascii_control,
assert_none!(
is_ascii_control,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",

View file

@ -1,5 +1,5 @@
use core::sync::atomic::*;
use core::sync::atomic::Ordering::SeqCst;
use core::sync::atomic::*;
#[test]
fn bool_() {
@ -15,7 +15,7 @@ fn bool_() {
fn bool_and() {
let a = AtomicBool::new(true);
assert_eq!(a.fetch_and(false, SeqCst), true);
assert_eq!(a.load(SeqCst),false);
assert_eq!(a.load(SeqCst), false);
}
#[test]
@ -89,7 +89,7 @@ fn int_xor() {
static S_FALSE: AtomicBool = AtomicBool::new(false);
static S_TRUE: AtomicBool = AtomicBool::new(true);
static S_INT: AtomicIsize = AtomicIsize::new(0);
static S_INT: AtomicIsize = AtomicIsize::new(0);
static S_UINT: AtomicUsize = AtomicUsize::new(0);
#[test]

View file

@ -236,7 +236,7 @@ fn ref_mut_map_accessor() {
}
let x = X(RefCell::new((7, 'z')));
{
let mut d: RefMut<'_ ,u32> = x.accessor();
let mut d: RefMut<'_, u32> = x.accessor();
assert_eq!(*d, 7);
*d += 1;
}
@ -250,7 +250,9 @@ fn as_ptr() {
assert_eq!(1, unsafe { *c1.as_ptr() });
let c2: Cell<usize> = Cell::new(0);
unsafe { *c2.as_ptr() = 1; }
unsafe {
*c2.as_ptr() = 1;
}
assert_eq!(1, c2.get());
let r1: RefCell<usize> = RefCell::new(0);
@ -258,7 +260,9 @@ fn as_ptr() {
assert_eq!(1, unsafe { *r1.as_ptr() });
let r2: RefCell<usize> = RefCell::new(0);
unsafe { *r2.as_ptr() = 1; }
unsafe {
*r2.as_ptr() = 1;
}
assert_eq!(1, *r2.borrow());
}

View file

@ -1,6 +1,6 @@
use std::{char,str};
use std::convert::TryFrom;
use std::str::FromStr;
use std::{char, str};
#[test]
fn test_convert() {
@ -143,13 +143,13 @@ fn test_is_control() {
#[test]
fn test_is_numeric() {
assert!('2'.is_numeric());
assert!('7'.is_numeric());
assert!('¾'.is_numeric());
assert!(!'c'.is_numeric());
assert!(!'i'.is_numeric());
assert!(!'z'.is_numeric());
assert!(!'Q'.is_numeric());
assert!('2'.is_numeric());
assert!('7'.is_numeric());
assert!('¾'.is_numeric());
assert!(!'c'.is_numeric());
assert!(!'i'.is_numeric());
assert!(!'z'.is_numeric());
assert!(!'Q'.is_numeric());
}
#[test]
@ -176,9 +176,9 @@ fn test_escape_debug() {
assert_eq!(string('\u{ff}'), "\u{ff}");
assert_eq!(string('\u{11b}'), "\u{11b}");
assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
assert_eq!(string('\u{301}'), "\\u{301}"); // combining character
assert_eq!(string('\u{200b}'),"\\u{200b}"); // zero width space
assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
assert_eq!(string('\u{301}'), "\\u{301}"); // combining character
assert_eq!(string('\u{200b}'), "\\u{200b}"); // zero width space
assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
}
@ -272,8 +272,8 @@ fn test_len_utf16() {
fn test_decode_utf16() {
fn check(s: &[u16], expected: &[Result<char, u16>]) {
let v = char::decode_utf16(s.iter().cloned())
.map(|r| r.map_err(|e| e.unpaired_surrogate()))
.collect::<Vec<_>>();
.map(|r| r.map_err(|e| e.unpaired_surrogate()))
.collect::<Vec<_>>();
assert_eq!(v, expected);
}
check(&[0xD800, 0x41, 0x42], &[Err(0xD800), Ok('A'), Ok('B')]);

View file

@ -1,7 +1,7 @@
mod sip;
use std::hash::{Hash, Hasher};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::rc::Rc;
struct MyHasher {
@ -20,10 +20,11 @@ impl Hasher for MyHasher {
self.hash += *byte as u64;
}
}
fn finish(&self) -> u64 { self.hash }
fn finish(&self) -> u64 {
self.hash
}
}
#[test]
fn test_writer_hasher() {
fn hash<T: Hash>(t: &T) -> u64 {
@ -52,17 +53,17 @@ fn test_writer_hasher() {
assert_eq!(hash(&'a'), 97);
let s: &str = "a";
assert_eq!(hash(& s), 97 + 0xFF);
assert_eq!(hash(&s), 97 + 0xFF);
let s: Box<str> = String::from("a").into_boxed_str();
assert_eq!(hash(& s), 97 + 0xFF);
assert_eq!(hash(&s), 97 + 0xFF);
let s: Rc<&str> = Rc::new("a");
assert_eq!(hash(&s), 97 + 0xFF);
let cs: &[u8] = &[1, 2, 3];
assert_eq!(hash(& cs), 9);
assert_eq!(hash(&cs), 9);
let cs: Box<[u8]> = Box::new([1, 2, 3]);
assert_eq!(hash(& cs), 9);
assert_eq!(hash(&cs), 9);
let cs: Rc<[u8]> = Rc::new([1, 2, 3]);
assert_eq!(hash(& cs), 9);
assert_eq!(hash(&cs), 9);
let ptr = 5_usize as *const i32;
assert_eq!(hash(&ptr), 5);
@ -70,24 +71,36 @@ fn test_writer_hasher() {
let ptr = 5_usize as *mut i32;
assert_eq!(hash(&ptr), 5);
if cfg!(miri) { // Miri cannot hash pointers
return;
}
let cs: &mut [u8] = &mut [1, 2, 3];
let ptr = cs.as_ptr();
let slice_ptr = cs as *const [u8];
#[cfg(not(miri))] // Miri cannot hash pointers
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
let slice_ptr = cs as *mut [u8];
#[cfg(not(miri))] // Miri cannot hash pointers
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
}
struct Custom { hash: u64 }
struct CustomHasher { output: u64 }
struct Custom {
hash: u64,
}
struct CustomHasher {
output: u64,
}
impl Hasher for CustomHasher {
fn finish(&self) -> u64 { self.output }
fn write(&mut self, _: &[u8]) { panic!() }
fn write_u64(&mut self, data: u64) { self.output = data; }
fn finish(&self) -> u64 {
self.output
}
fn write(&mut self, _: &[u8]) {
panic!()
}
fn write_u64(&mut self, data: u64) {
self.output = data;
}
}
impl Default for CustomHasher {

View file

@ -2,7 +2,7 @@
use core::hash::{Hash, Hasher};
use core::hash::{SipHasher, SipHasher13};
use core::{slice, mem};
use core::{mem, slice};
// Hash just the bytes of the slice, without length prefix
struct Bytes<'a>(&'a [u8]);
@ -16,25 +16,25 @@ impl<'a> Hash for Bytes<'a> {
}
macro_rules! u8to64_le {
($buf:expr, $i:expr) =>
($buf[0+$i] as u64 |
($buf[1+$i] as u64) << 8 |
($buf[2+$i] as u64) << 16 |
($buf[3+$i] as u64) << 24 |
($buf[4+$i] as u64) << 32 |
($buf[5+$i] as u64) << 40 |
($buf[6+$i] as u64) << 48 |
($buf[7+$i] as u64) << 56);
($buf:expr, $i:expr, $len:expr) =>
({
($buf:expr, $i:expr) => {
$buf[0 + $i] as u64
| ($buf[1 + $i] as u64) << 8
| ($buf[2 + $i] as u64) << 16
| ($buf[3 + $i] as u64) << 24
| ($buf[4 + $i] as u64) << 32
| ($buf[5 + $i] as u64) << 40
| ($buf[6 + $i] as u64) << 48
| ($buf[7 + $i] as u64) << 56
};
($buf:expr, $i:expr, $len:expr) => {{
let mut t = 0;
let mut out = 0;
while t < $len {
out |= ($buf[t+$i] as u64) << t*8;
out |= ($buf[t + $i] as u64) << t * 8;
t += 1;
}
out
});
}};
}
fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
@ -49,71 +49,71 @@ fn hash<T: Hash>(x: &T) -> u64 {
#[test]
#[allow(unused_must_use)]
fn test_siphash_1_3() {
let vecs : [[u8; 8]; 64] = [
[ 0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab ],
[ 0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9 ],
[ 0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82 ],
[ 0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b ],
[ 0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf ],
[ 0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde ],
[ 0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5 ],
[ 0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3 ],
[ 0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36 ],
[ 0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25 ],
[ 0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79 ],
[ 0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70 ],
[ 0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78 ],
[ 0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30 ],
[ 0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60 ],
[ 0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3 ],
[ 0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc ],
[ 0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c ],
[ 0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f ],
[ 0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2 ],
[ 0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0 ],
[ 0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9 ],
[ 0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f ],
[ 0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52 ],
[ 0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4 ],
[ 0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45 ],
[ 0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a ],
[ 0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9 ],
[ 0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb ],
[ 0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88 ],
[ 0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54 ],
[ 0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23 ],
[ 0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81 ],
[ 0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d ],
[ 0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75 ],
[ 0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce ],
[ 0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c ],
[ 0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6 ],
[ 0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3 ],
[ 0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62 ],
[ 0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1 ],
[ 0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66 ],
[ 0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65 ],
[ 0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24 ],
[ 0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2 ],
[ 0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2 ],
[ 0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1 ],
[ 0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49 ],
[ 0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f ],
[ 0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6 ],
[ 0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e ],
[ 0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c ],
[ 0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4 ],
[ 0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36 ],
[ 0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31 ],
[ 0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2 ],
[ 0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4 ],
[ 0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23 ],
[ 0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f ],
[ 0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8 ],
[ 0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6 ],
[ 0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae ],
[ 0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3 ],
[ 0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d ]
let vecs: [[u8; 8]; 64] = [
[0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab],
[0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9],
[0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82],
[0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b],
[0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf],
[0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde],
[0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5],
[0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3],
[0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36],
[0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25],
[0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79],
[0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70],
[0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78],
[0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30],
[0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60],
[0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3],
[0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc],
[0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c],
[0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f],
[0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2],
[0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0],
[0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9],
[0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f],
[0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52],
[0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4],
[0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45],
[0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a],
[0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9],
[0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb],
[0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88],
[0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54],
[0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23],
[0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81],
[0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d],
[0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75],
[0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce],
[0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c],
[0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6],
[0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3],
[0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62],
[0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1],
[0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66],
[0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65],
[0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24],
[0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2],
[0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2],
[0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1],
[0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49],
[0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f],
[0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6],
[0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e],
[0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c],
[0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4],
[0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36],
[0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31],
[0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2],
[0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4],
[0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23],
[0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f],
[0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8],
[0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6],
[0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae],
[0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3],
[0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d],
];
let k0 = 0x_07_06_05_04_03_02_01_00;
@ -143,71 +143,71 @@ fn test_siphash_1_3() {
#[test]
#[allow(unused_must_use)]
fn test_siphash_2_4() {
let vecs : [[u8; 8]; 64] = [
[ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
[ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
[ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
[ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
[ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
[ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
[ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
[ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
[ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
[ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
[ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
[ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
[ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
[ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
[ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
[ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
[ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
[ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
[ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
[ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
[ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
[ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
[ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
[ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
[ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
[ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
[ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
[ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
[ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
[ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
[ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
[ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
[ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
[ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
[ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
[ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
[ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
[ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
[ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
[ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
[ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
[ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
[ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
[ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
[ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
[ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
[ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
[ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
[ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
[ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
[ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
[ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
[ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
[ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
[ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
[ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
[ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
[ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
[ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
[ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
[ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
[ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
[ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
[ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
let vecs: [[u8; 8]; 64] = [
[0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72],
[0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74],
[0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d],
[0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85],
[0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf],
[0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18],
[0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb],
[0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab],
[0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93],
[0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e],
[0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a],
[0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4],
[0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75],
[0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14],
[0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7],
[0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1],
[0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f],
[0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69],
[0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b],
[0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb],
[0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe],
[0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0],
[0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93],
[0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8],
[0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8],
[0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc],
[0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17],
[0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f],
[0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde],
[0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6],
[0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad],
[0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32],
[0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71],
[0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7],
[0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12],
[0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15],
[0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31],
[0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02],
[0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca],
[0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a],
[0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e],
[0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad],
[0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18],
[0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4],
[0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9],
[0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9],
[0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb],
[0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0],
[0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6],
[0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7],
[0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee],
[0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1],
[0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a],
[0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81],
[0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f],
[0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24],
[0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7],
[0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea],
[0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60],
[0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66],
[0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c],
[0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f],
[0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5],
[0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95],
];
let k0 = 0x_07_06_05_04_03_02_01_00;
@ -320,8 +320,7 @@ fn test_write_short_works() {
h1.write_u8(0x01u8);
let mut h2 = SipHasher::new();
h2.write(unsafe {
slice::from_raw_parts(&test_usize as *const _ as *const u8,
mem::size_of::<usize>())
slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::<usize>())
});
h2.write(b"bytes");
h2.write(b"string");

View file

@ -2,7 +2,8 @@ use core::any::TypeId;
#[test]
fn test_typeid_sized_types() {
struct X; struct Y(u32);
struct X;
struct Y(u32);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
@ -12,7 +13,8 @@ fn test_typeid_sized_types() {
#[test]
fn test_typeid_unsized_types() {
trait Z {}
struct X(str); struct Y(dyn Z + 'static);
struct X(str);
struct Y(dyn Z + 'static);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());

View file

@ -13,7 +13,7 @@ fn smoke() {
drop(x);
// also test unsizing
let x : Box<ManuallyDrop<[TypeWithDrop]>> =
let x: Box<ManuallyDrop<[TypeWithDrop]>> =
Box::new(ManuallyDrop::new([TypeWithDrop, TypeWithDrop]));
drop(x);
}

View file

@ -96,7 +96,9 @@ fn test_transmute_copy() {
#[test]
fn test_transmute() {
trait Foo { fn dummy(&self) { } }
trait Foo {
fn dummy(&self) {}
}
impl Foo for isize {}
let a = box 100isize as Box<dyn Foo>;
@ -116,13 +118,13 @@ fn test_transmute() {
fn test_discriminant_send_sync() {
enum Regular {
A,
B(i32)
B(i32),
}
enum NotSendSync {
A(*const i32)
A(*const i32),
}
fn is_send_sync<T: Send + Sync>() { }
fn is_send_sync<T: Send + Sync>() {}
is_send_sync::<Discriminant<Regular>>();
is_send_sync::<Discriminant<NotSendSync>>();

View file

@ -4,9 +4,7 @@ use std::mem::size_of;
#[test]
fn test_create_nonzero_instance() {
let _a = unsafe {
NonZeroU32::new_unchecked(21)
};
let _a = unsafe { NonZeroU32::new_unchecked(21) };
}
#[test]
@ -17,17 +15,15 @@ fn test_size_nonzero_in_option() {
#[test]
fn test_match_on_nonzero_option() {
let a = Some(unsafe {
NonZeroU32::new_unchecked(42)
});
let a = Some(unsafe { NonZeroU32::new_unchecked(42) });
match a {
Some(val) => assert_eq!(val.get(), 42),
None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
}
match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
Some(val) => assert_eq!(val.get(), 43),
None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
}
}
@ -45,7 +41,7 @@ fn test_match_option_vec() {
let a = Some(vec![1, 2, 3, 4]);
match a {
Some(v) => assert_eq!(v, [1, 2, 3, 4]),
None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])"),
}
}
@ -56,7 +52,7 @@ fn test_match_option_rc() {
let five = Rc::new(5);
match Some(five) {
Some(r) => assert_eq!(*r, 5),
None => panic!("unexpected None while matching on Some(Rc::new(5))")
None => panic!("unexpected None while matching on Some(Rc::new(5))"),
}
}
@ -67,7 +63,7 @@ fn test_match_option_arc() {
let five = Arc::new(5);
match Some(five) {
Some(a) => assert_eq!(*a, 5),
None => panic!("unexpected None while matching on Some(Arc::new(5))")
None => panic!("unexpected None while matching on Some(Arc::new(5))"),
}
}
@ -85,7 +81,7 @@ fn test_match_option_string() {
let five = "Five".to_string();
match Some(five) {
Some(s) => assert_eq!(s, "Five"),
None => panic!("unexpected None while matching on Some(String { ... })")
None => panic!("unexpected None while matching on Some(String { ... })"),
}
}
@ -100,7 +96,9 @@ mod atom {
}
macro_rules! atom {
("foo") => { atom::FOO_ATOM }
("foo") => {
atom::FOO_ATOM
};
}
#[test]
@ -108,7 +106,7 @@ fn test_match_nonzero_const_pattern() {
match atom!("foo") {
// Using as a pattern is supported by the compiler:
atom!("foo") => {}
_ => panic!("Expected the const item as a pattern to match.")
_ => panic!("Expected the const item as a pattern to match."),
}
}
@ -129,10 +127,7 @@ fn test_from_signed_nonzero() {
#[test]
fn test_from_str() {
assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
assert_eq!(
"0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
Some(IntErrorKind::Zero)
);
assert_eq!("0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()), Some(IntErrorKind::Zero));
assert_eq!(
"-1".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
Some(IntErrorKind::InvalidDigit)

View file

@ -70,7 +70,7 @@ fn test_sub_underflow_2() {
fn test_mul_small() {
assert_eq!(*Big::from_small(7).mul_small(5), Big::from_small(35));
assert_eq!(*Big::from_small(0xff).mul_small(0xff), Big::from_u64(0xfe01));
assert_eq!(*Big::from_u64(0xffffff/13).mul_small(13), Big::from_u64(0xffffff));
assert_eq!(*Big::from_u64(0xffffff / 13).mul_small(13), Big::from_u64(0xffffff));
}
#[test]
@ -134,7 +134,7 @@ fn test_mul_digits() {
assert_eq!(*Big::from_u64(0x123).mul_digits(&[0x56, 0x4]), Big::from_u64(0x4edc2));
assert_eq!(*Big::from_u64(0x12345).mul_digits(&[0x67]), Big::from_u64(0x7530c3));
assert_eq!(*Big::from_small(0x12).mul_digits(&[0x67, 0x45, 0x3]), Big::from_u64(0x3ae13e));
assert_eq!(*Big::from_u64(0xffffff/13).mul_digits(&[13]), Big::from_u64(0xffffff));
assert_eq!(*Big::from_u64(0xffffff / 13).mul_digits(&[13]), Big::from_u64(0xffffff));
assert_eq!(*Big::from_small(13).mul_digits(&[0x3b, 0xb1, 0x13]), Big::from_u64(0xffffff));
}
@ -156,10 +156,14 @@ fn test_div_rem_small() {
assert_eq!(as_val(Big::from_small(0xff).div_rem_small(15)), (Big::from_small(17), 0));
assert_eq!(as_val(Big::from_small(0xff).div_rem_small(16)), (Big::from_small(15), 15));
assert_eq!(as_val(Big::from_small(3).div_rem_small(40)), (Big::from_small(0), 3));
assert_eq!(as_val(Big::from_u64(0xffffff).div_rem_small(123)),
(Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8));
assert_eq!(as_val(Big::from_u64(0x10000).div_rem_small(123)),
(Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8));
assert_eq!(
as_val(Big::from_u64(0xffffff).div_rem_small(123)),
(Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8)
);
assert_eq!(
as_val(Big::from_u64(0x10000).div_rem_small(123)),
(Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8)
);
}
#[test]

View file

@ -1,6 +1,6 @@
#![allow(overflowing_literals)]
use std::{i64, f32, f64};
use std::{f32, f64, i64};
mod parse;
mod rawfp;
@ -9,7 +9,7 @@ mod rawfp;
// to be correct) and see if those strings are parsed back to the value of the literal.
// Requires a *polymorphic literal*, i.e., one that can serve as f64 as well as f32.
macro_rules! test_literal {
($x: expr) => ({
($x: expr) => {{
let x32: f32 = $x;
let x64: f64 = $x;
let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
@ -20,7 +20,7 @@ macro_rules! test_literal {
assert_eq!(neg_input.parse(), Ok(-x64));
assert_eq!(neg_input.parse(), Ok(-x32));
}
})
}};
}
#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
@ -31,7 +31,11 @@ fn ordinary() {
test_literal!(0.1);
test_literal!(12345.);
test_literal!(0.9999999);
#[cfg(not(miri))] // Miri is too slow
if cfg!(miri) { // Miri is too slow
return;
}
test_literal!(2.2250738585072014e-308);
}
@ -53,7 +57,7 @@ fn large() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn subnormals() {
test_literal!(5e-324);
test_literal!(91e-324);
@ -65,7 +69,7 @@ fn subnormals() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn infinity() {
test_literal!(1e400);
test_literal!(1e309);
@ -77,9 +81,12 @@ fn infinity() {
fn zero() {
test_literal!(0.0);
test_literal!(1e-325);
#[cfg(not(miri))] // Miri is too slow
if cfg!(miri) { // Miri is too slow
return;
}
test_literal!(1e-326);
#[cfg(not(miri))] // Miri is too slow
test_literal!(1e-500);
}

View file

@ -1,5 +1,5 @@
use core::num::dec2flt::parse::{Decimal, parse_decimal};
use core::num::dec2flt::parse::ParseResult::{Valid, Invalid};
use core::num::dec2flt::parse::ParseResult::{Invalid, Valid};
use core::num::dec2flt::parse::{parse_decimal, Decimal};
#[test]
fn missing_pieces() {

View file

@ -1,8 +1,8 @@
use core::num::dec2flt::rawfp::RawFloat;
use core::num::dec2flt::rawfp::{fp_to_float, next_float, prev_float, round_normal};
use core::num::diy_float::Fp;
use std::f32;
use std::f64;
use core::num::diy_float::Fp;
use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
use core::num::dec2flt::rawfp::RawFloat;
fn integer_decode(f: f64) -> (u64, i16, i8) {
RawFloat::integer_decode(f)
@ -53,16 +53,23 @@ fn integers_to_f64() {
assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
}
const SOME_FLOATS: [f64; 9] =
[0.1f64, 33.568, 42.1e-5, 777.0e9, 1.1111, 0.347997,
9843579834.35892, 12456.0e-150, 54389573.0e-150];
const SOME_FLOATS: [f64; 9] = [
0.1f64,
33.568,
42.1e-5,
777.0e9,
1.1111,
0.347997,
9843579834.35892,
12456.0e-150,
54389573.0e-150,
];
#[test]
fn human_f64_roundtrip() {
for &x in &SOME_FLOATS {
let (f, e, _) = integer_decode(x);
let fp = Fp { f: f, e: e};
let fp = Fp { f: f, e: e };
assert_eq!(fp_to_float::<f64>(fp), x);
}
}

View file

@ -3,14 +3,24 @@ use core::num::flt2dec::estimator::*;
#[test]
fn test_estimate_scaling_factor() {
macro_rules! assert_almost_eq {
($actual:expr, $expected:expr) => ({
($actual:expr, $expected:expr) => {{
let actual = $actual;
let expected = $expected;
println!("{} - {} = {} - {} = {}", stringify!($expected), stringify!($actual),
expected, actual, expected - actual);
assert!(expected == actual || expected == actual + 1,
"expected {}, actual {}", expected, actual);
})
println!(
"{} - {} = {} - {} = {}",
stringify!($expected),
stringify!($actual),
expected,
actual,
expected - actual
);
assert!(
expected == actual || expected == actual + 1,
"expected {}, actual {}",
expected,
actual
);
}};
}
assert_almost_eq!(estimate_scaling_factor(1, 0), 0);

View file

@ -256,7 +256,6 @@ pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
check_shortest!(f(minf32) => b"1", -44);
}
#[cfg(not(miri))] // Miri is too slow
pub fn f32_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf32 = ldexp_f32(1.0, -149);
@ -362,7 +361,6 @@ pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
check_shortest!(f(minf64) => b"5", -323);
}
#[cfg(not(miri))] // Miri is too slow
pub fn f64_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf64 = ldexp_f64(1.0, -1074);

View file

@ -3,27 +3,28 @@
use std::i16;
use std::str;
use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::strategy::grisu::format_exact_opt;
use core::num::flt2dec::strategy::grisu::format_shortest_opt;
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
use rand::SeedableRng;
use rand::rngs::StdRng;
use rand::distributions::{Distribution, Uniform};
use rand::rngs::StdRng;
use rand::SeedableRng;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}
fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
V: FnMut(usize) -> Decoded {
where
F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
V: FnMut(usize) -> Decoded,
{
assert!(k <= 1024);
let mut npassed = 0; // f(x) = Some(g(x))
@ -31,8 +32,14 @@ fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V
for i in 0..n {
if (i & 0xfffff) == 0 {
println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
i, n, nignored, npassed, i - nignored - npassed);
println!(
"in progress, {:x}/{:x} (ignored={} passed={} failed={})",
i,
n,
nignored,
npassed,
i - nignored - npassed
);
}
let decoded = v(i);
@ -43,27 +50,47 @@ fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V
if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
npassed += 1;
} else {
println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
str::from_utf8(&buf2[..len2]).unwrap(), e2);
println!(
"equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
i,
n,
decoded,
str::from_utf8(&buf1[..len1]).unwrap(),
e1,
str::from_utf8(&buf2[..len2]).unwrap(),
e2
);
}
} else {
nignored += 1;
}
}
println!("{}({}): done, ignored={} passed={} failed={}",
func, k, nignored, npassed, n - nignored - npassed);
assert!(nignored + npassed == n,
"{}({}): {} out of {} values returns an incorrect value!",
func, k, n - nignored - npassed, n);
println!(
"{}({}): done, ignored={} passed={} failed={}",
func,
k,
nignored,
npassed,
n - nignored - npassed
);
assert!(
nignored + npassed == n,
"{}({}): {} out of {} values returns an incorrect value!",
func,
k,
n - nignored - npassed,
n
);
(npassed, nignored)
}
pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
where
F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
{
if cfg!(target_os = "emscripten") {
return // using rng pulls in i128 support, which doesn't work
return; // using rng pulls in i128 support, which doesn't work
}
let mut rng = StdRng::from_entropy();
let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
@ -74,10 +101,12 @@ pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
}
pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
where
F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
{
if cfg!(target_os = "emscripten") {
return // using rng pulls in i128 support, which doesn't work
return; // using rng pulls in i128 support, which doesn't work
}
let mut rng = StdRng::from_entropy();
let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
@ -88,8 +117,10 @@ pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
}
pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
where
F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
{
// we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
// so why not simply testing all of them?
//
@ -97,12 +128,11 @@ pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
// but with `-C opt-level=3 -C lto` this only takes about an hour or so.
// iterate from 0x0000_0001 to 0x7f7f_ffff, i.e., all finite ranges
let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
k, 0x7f7f_ffff, f, g, |i: usize| {
let x = f32::from_bits(i as u32 + 1);
decode_finite(x)
});
let (npassed, nignored) =
iterate("f32_exhaustive_equivalence_test", k, 0x7f7f_ffff, f, g, |i: usize| {
let x = f32::from_bits(i as u32 + 1);
decode_finite(x)
});
assert_eq!((npassed, nignored), (2121451881, 17643158));
}
@ -118,7 +148,8 @@ fn shortest_random_equivalence_test() {
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
}
#[test] #[ignore] // it is too expensive
#[test]
#[ignore] // it is too expensive
fn shortest_f32_exhaustive_equivalence_test() {
// it is hard to directly test the optimality of the output, but we can at least test if
// two different algorithms agree to each other.
@ -131,13 +162,13 @@ fn shortest_f32_exhaustive_equivalence_test() {
f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}
#[test] #[ignore] // it is too expensive
#[test]
#[ignore] // it is too expensive
fn shortest_f64_hard_random_equivalence_test() {
// this again probably has to use appropriate rustc flags.
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
f64_random_equivalence_test(format_shortest_opt, fallback,
MAX_SIG_DIGITS, 100_000_000);
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 100_000_000);
}
#[test]
@ -149,8 +180,12 @@ fn exact_f32_random_equivalence_test() {
const N: usize = 3;
for k in 1..21 {
f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN), k, N);
f32_random_equivalence_test(
|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN),
k,
N,
);
}
}
@ -163,7 +198,11 @@ fn exact_f64_random_equivalence_test() {
const N: usize = 3;
for k in 1..21 {
f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN), k, N);
f64_random_equivalence_test(
|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN),
k,
N,
);
}
}

View file

@ -22,7 +22,7 @@ fn shortest_sanity_test() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn exact_sanity_test() {
// This test ends up running what I can only assume is some corner-ish case
// of the `exp2` library function, defined in whatever C runtime we're

View file

@ -6,12 +6,18 @@ fn test_cached_power() {
assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E);
assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E);
for e in -1137..961 { // full range for f64
for e in -1137..961 {
// full range for f64
let low = ALPHA - e - 64;
let high = GAMMA - e - 64;
let (_k, cached) = cached_power(low, high);
assert!(low <= cached.e && cached.e <= high,
"cached_power({}, {}) = {:?} is incorrect", low, high, cached);
assert!(
low <= cached.e && cached.e <= high,
"cached_power({}, {}) = {:?} is incorrect",
low,
high,
cached
);
}
}
@ -26,7 +32,6 @@ fn test_max_pow10_no_more_than() {
}
}
#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
#[test]
fn shortest_sanity_test() {
@ -36,7 +41,7 @@ fn shortest_sanity_test() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn exact_sanity_test() {
// See comments in dragon.rs's exact_sanity_test for why this test is
// ignored on MSVC

View file

@ -1,240 +1,241 @@
macro_rules! int_module { ($T:ident, $T_i:ident) => (
#[cfg(test)]
mod tests {
use core::$T_i::*;
use core::isize;
use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
use core::mem;
macro_rules! int_module {
($T:ident, $T_i:ident) => {
#[cfg(test)]
mod tests {
use core::isize;
use core::mem;
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use core::$T_i::*;
use crate::num;
use crate::num;
#[test]
fn test_overflows() {
assert!(MAX > 0);
assert!(MIN <= 0);
assert_eq!(MIN + MAX + 1, 0);
}
#[test]
fn test_overflows() {
assert!(MAX > 0);
assert!(MIN <= 0);
assert_eq!(MIN + MAX + 1, 0);
}
#[test]
fn test_num() {
num::test_num(10 as $T, 2 as $T);
}
#[test]
fn test_num() {
num::test_num(10 as $T, 2 as $T);
}
#[test]
fn test_rem_euclid() {
assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
}
#[test]
fn test_rem_euclid() {
assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
}
#[test]
pub fn test_abs() {
assert_eq!((1 as $T).abs(), 1 as $T);
assert_eq!((0 as $T).abs(), 0 as $T);
assert_eq!((-1 as $T).abs(), 1 as $T);
}
#[test]
pub fn test_abs() {
assert_eq!((1 as $T).abs(), 1 as $T);
assert_eq!((0 as $T).abs(), 0 as $T);
assert_eq!((-1 as $T).abs(), 1 as $T);
}
#[test]
fn test_signum() {
assert_eq!((1 as $T).signum(), 1 as $T);
assert_eq!((0 as $T).signum(), 0 as $T);
assert_eq!((-0 as $T).signum(), 0 as $T);
assert_eq!((-1 as $T).signum(), -1 as $T);
}
#[test]
fn test_signum() {
assert_eq!((1 as $T).signum(), 1 as $T);
assert_eq!((0 as $T).signum(), 0 as $T);
assert_eq!((-0 as $T).signum(), 0 as $T);
assert_eq!((-1 as $T).signum(), -1 as $T);
}
#[test]
fn test_is_positive() {
assert!((1 as $T).is_positive());
assert!(!(0 as $T).is_positive());
assert!(!(-0 as $T).is_positive());
assert!(!(-1 as $T).is_positive());
}
#[test]
fn test_is_positive() {
assert!((1 as $T).is_positive());
assert!(!(0 as $T).is_positive());
assert!(!(-0 as $T).is_positive());
assert!(!(-1 as $T).is_positive());
}
#[test]
fn test_is_negative() {
assert!(!(1 as $T).is_negative());
assert!(!(0 as $T).is_negative());
assert!(!(-0 as $T).is_negative());
assert!((-1 as $T).is_negative());
}
#[test]
fn test_is_negative() {
assert!(!(1 as $T).is_negative());
assert!(!(0 as $T).is_negative());
assert!(!(-0 as $T).is_negative());
assert!((-1 as $T).is_negative());
}
#[test]
fn test_bitwise_operators() {
assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
}
#[test]
fn test_bitwise_operators() {
assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
}
const A: $T = 0b0101100;
const B: $T = 0b0100001;
const C: $T = 0b1111001;
const A: $T = 0b0101100;
const B: $T = 0b0100001;
const C: $T = 0b1111001;
const _0: $T = 0;
const _1: $T = !0;
const _0: $T = 0;
const _1: $T = !0;
#[test]
fn test_count_ones() {
assert_eq!(A.count_ones(), 3);
assert_eq!(B.count_ones(), 2);
assert_eq!(C.count_ones(), 5);
}
#[test]
fn test_count_ones() {
assert_eq!(A.count_ones(), 3);
assert_eq!(B.count_ones(), 2);
assert_eq!(C.count_ones(), 5);
}
#[test]
fn test_count_zeros() {
let bits = mem::size_of::<$T>() * 8;
assert_eq!(A.count_zeros(), bits as u32 - 3);
assert_eq!(B.count_zeros(), bits as u32 - 2);
assert_eq!(C.count_zeros(), bits as u32 - 5);
}
#[test]
fn test_count_zeros() {
let bits = mem::size_of::<$T>() * 8;
assert_eq!(A.count_zeros(), bits as u32 - 3);
assert_eq!(B.count_zeros(), bits as u32 - 2);
assert_eq!(C.count_zeros(), bits as u32 - 5);
}
#[test]
fn test_rotate() {
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
#[test]
fn test_rotate() {
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behaviour. See #10183.
assert_eq!(_0.rotate_left(124), _0);
assert_eq!(_1.rotate_left(124), _1);
assert_eq!(_0.rotate_right(124), _0);
assert_eq!(_1.rotate_right(124), _1);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behaviour. See #10183.
assert_eq!(_0.rotate_left(124), _0);
assert_eq!(_1.rotate_left(124), _1);
assert_eq!(_0.rotate_right(124), _0);
assert_eq!(_1.rotate_right(124), _1);
// Rotating by 0 should have no effect
assert_eq!(A.rotate_left(0), A);
assert_eq!(B.rotate_left(0), B);
assert_eq!(C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq!(A.rotate_left(64), A);
assert_eq!(B.rotate_left(64), B);
assert_eq!(C.rotate_left(64), C);
}
// Rotating by 0 should have no effect
assert_eq!(A.rotate_left(0), A);
assert_eq!(B.rotate_left(0), B);
assert_eq!(C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq!(A.rotate_left(64), A);
assert_eq!(B.rotate_left(64), B);
assert_eq!(C.rotate_left(64), C);
}
#[test]
fn test_swap_bytes() {
assert_eq!(A.swap_bytes().swap_bytes(), A);
assert_eq!(B.swap_bytes().swap_bytes(), B);
assert_eq!(C.swap_bytes().swap_bytes(), C);
#[test]
fn test_swap_bytes() {
assert_eq!(A.swap_bytes().swap_bytes(), A);
assert_eq!(B.swap_bytes().swap_bytes(), B);
assert_eq!(C.swap_bytes().swap_bytes(), C);
// Swapping these should make no difference
assert_eq!(_0.swap_bytes(), _0);
assert_eq!(_1.swap_bytes(), _1);
}
// Swapping these should make no difference
assert_eq!(_0.swap_bytes(), _0);
assert_eq!(_1.swap_bytes(), _1);
}
#[test]
fn test_le() {
assert_eq!($T::from_le(A.to_le()), A);
assert_eq!($T::from_le(B.to_le()), B);
assert_eq!($T::from_le(C.to_le()), C);
assert_eq!($T::from_le(_0), _0);
assert_eq!($T::from_le(_1), _1);
assert_eq!(_0.to_le(), _0);
assert_eq!(_1.to_le(), _1);
}
#[test]
fn test_le() {
assert_eq!($T::from_le(A.to_le()), A);
assert_eq!($T::from_le(B.to_le()), B);
assert_eq!($T::from_le(C.to_le()), C);
assert_eq!($T::from_le(_0), _0);
assert_eq!($T::from_le(_1), _1);
assert_eq!(_0.to_le(), _0);
assert_eq!(_1.to_le(), _1);
}
#[test]
fn test_be() {
assert_eq!($T::from_be(A.to_be()), A);
assert_eq!($T::from_be(B.to_be()), B);
assert_eq!($T::from_be(C.to_be()), C);
assert_eq!($T::from_be(_0), _0);
assert_eq!($T::from_be(_1), _1);
assert_eq!(_0.to_be(), _0);
assert_eq!(_1.to_be(), _1);
}
#[test]
fn test_be() {
assert_eq!($T::from_be(A.to_be()), A);
assert_eq!($T::from_be(B.to_be()), B);
assert_eq!($T::from_be(C.to_be()), C);
assert_eq!($T::from_be(_0), _0);
assert_eq!($T::from_be(_1), _1);
assert_eq!(_0.to_be(), _0);
assert_eq!(_1.to_be(), _1);
}
#[test]
fn test_signed_checked_div() {
assert_eq!((10 as $T).checked_div(2), Some(5));
assert_eq!((5 as $T).checked_div(0), None);
assert_eq!(isize::MIN.checked_div(-1), None);
}
#[test]
fn test_signed_checked_div() {
assert_eq!((10 as $T).checked_div(2), Some(5));
assert_eq!((5 as $T).checked_div(0), None);
assert_eq!(isize::MIN.checked_div(-1), None);
}
#[test]
fn test_saturating_abs() {
assert_eq!((0 as $T).saturating_abs(), 0);
assert_eq!((123 as $T).saturating_abs(), 123);
assert_eq!((-123 as $T).saturating_abs(), 123);
assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
assert_eq!(MAX.saturating_abs(), MAX);
assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
assert_eq!((MIN + 1).saturating_abs(), MAX);
assert_eq!(MIN.saturating_abs(), MAX);
}
#[test]
fn test_saturating_abs() {
assert_eq!((0 as $T).saturating_abs(), 0);
assert_eq!((123 as $T).saturating_abs(), 123);
assert_eq!((-123 as $T).saturating_abs(), 123);
assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
assert_eq!(MAX.saturating_abs(), MAX);
assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
assert_eq!((MIN + 1).saturating_abs(), MAX);
assert_eq!(MIN.saturating_abs(), MAX);
}
#[test]
fn test_saturating_neg() {
assert_eq!((0 as $T).saturating_neg(), 0);
assert_eq!((123 as $T).saturating_neg(), -123);
assert_eq!((-123 as $T).saturating_neg(), 123);
assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
assert_eq!(MAX.saturating_neg(), MIN + 1);
assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
assert_eq!((MIN + 1).saturating_neg(), MAX);
assert_eq!(MIN.saturating_neg(), MAX);
}
#[test]
fn test_saturating_neg() {
assert_eq!((0 as $T).saturating_neg(), 0);
assert_eq!((123 as $T).saturating_neg(), -123);
assert_eq!((-123 as $T).saturating_neg(), 123);
assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
assert_eq!(MAX.saturating_neg(), MIN + 1);
assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
assert_eq!((MIN + 1).saturating_neg(), MAX);
assert_eq!(MIN.saturating_neg(), MAX);
}
#[test]
fn test_from_str() {
fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
::std::str::FromStr::from_str(t).ok()
#[test]
fn test_from_str() {
fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
::std::str::FromStr::from_str(t).ok()
}
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
#[test]
fn test_from_str_radix() {
assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
}
#[test]
fn test_pow() {
let mut r = 2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(0), 1 as $T);
r = -2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(3), -8 as $T);
}
}
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
#[test]
fn test_from_str_radix() {
assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
}
#[test]
fn test_pow() {
let mut r = 2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(0), 1 as $T);
r = -2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(3), -8 as $T);
}
};
}
)}

View file

@ -1,160 +1,162 @@
macro_rules! uint_module { ($T:ident, $T_i:ident) => (
#[cfg(test)]
mod tests {
use core::$T_i::*;
use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
use std::str::FromStr;
use std::mem;
macro_rules! uint_module {
($T:ident, $T_i:ident) => {
#[cfg(test)]
mod tests {
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use core::$T_i::*;
use std::mem;
use std::str::FromStr;
use crate::num;
use crate::num;
#[test]
fn test_overflows() {
assert!(MAX > 0);
assert!(MIN <= 0);
assert!((MIN + MAX).wrapping_add(1) == 0);
}
#[test]
fn test_overflows() {
assert!(MAX > 0);
assert!(MIN <= 0);
assert!((MIN + MAX).wrapping_add(1) == 0);
}
#[test]
fn test_num() {
num::test_num(10 as $T, 2 as $T);
}
#[test]
fn test_num() {
num::test_num(10 as $T, 2 as $T);
}
#[test]
fn test_bitwise_operators() {
assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
assert!(0b1110 as $T == (0b0111 as $T).shl(1));
assert!(0b0111 as $T == (0b1110 as $T).shr(1));
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
}
#[test]
fn test_bitwise_operators() {
assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
assert!(0b1110 as $T == (0b0111 as $T).shl(1));
assert!(0b0111 as $T == (0b1110 as $T).shr(1));
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
}
const A: $T = 0b0101100;
const B: $T = 0b0100001;
const C: $T = 0b1111001;
const A: $T = 0b0101100;
const B: $T = 0b0100001;
const C: $T = 0b1111001;
const _0: $T = 0;
const _1: $T = !0;
const _0: $T = 0;
const _1: $T = !0;
#[test]
fn test_count_ones() {
assert!(A.count_ones() == 3);
assert!(B.count_ones() == 2);
assert!(C.count_ones() == 5);
}
#[test]
fn test_count_ones() {
assert!(A.count_ones() == 3);
assert!(B.count_ones() == 2);
assert!(C.count_ones() == 5);
}
#[test]
fn test_count_zeros() {
let bits = mem::size_of::<$T>() * 8;
assert!(A.count_zeros() == bits as u32 - 3);
assert!(B.count_zeros() == bits as u32 - 2);
assert!(C.count_zeros() == bits as u32 - 5);
}
#[test]
fn test_count_zeros() {
let bits = mem::size_of::<$T>() * 8;
assert!(A.count_zeros() == bits as u32 - 3);
assert!(B.count_zeros() == bits as u32 - 2);
assert!(C.count_zeros() == bits as u32 - 5);
}
#[test]
fn test_rotate() {
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
#[test]
fn test_rotate() {
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behaviour. See #10183.
assert_eq!(_0.rotate_left(124), _0);
assert_eq!(_1.rotate_left(124), _1);
assert_eq!(_0.rotate_right(124), _0);
assert_eq!(_1.rotate_right(124), _1);
// Rotating these should make no difference
//
// We test using 124 bits because to ensure that overlong bit shifts do
// not cause undefined behaviour. See #10183.
assert_eq!(_0.rotate_left(124), _0);
assert_eq!(_1.rotate_left(124), _1);
assert_eq!(_0.rotate_right(124), _0);
assert_eq!(_1.rotate_right(124), _1);
// Rotating by 0 should have no effect
assert_eq!(A.rotate_left(0), A);
assert_eq!(B.rotate_left(0), B);
assert_eq!(C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq!(A.rotate_left(64), A);
assert_eq!(B.rotate_left(64), B);
assert_eq!(C.rotate_left(64), C);
}
// Rotating by 0 should have no effect
assert_eq!(A.rotate_left(0), A);
assert_eq!(B.rotate_left(0), B);
assert_eq!(C.rotate_left(0), C);
// Rotating by a multiple of word size should also have no effect
assert_eq!(A.rotate_left(64), A);
assert_eq!(B.rotate_left(64), B);
assert_eq!(C.rotate_left(64), C);
}
#[test]
fn test_swap_bytes() {
assert_eq!(A.swap_bytes().swap_bytes(), A);
assert_eq!(B.swap_bytes().swap_bytes(), B);
assert_eq!(C.swap_bytes().swap_bytes(), C);
#[test]
fn test_swap_bytes() {
assert_eq!(A.swap_bytes().swap_bytes(), A);
assert_eq!(B.swap_bytes().swap_bytes(), B);
assert_eq!(C.swap_bytes().swap_bytes(), C);
// Swapping these should make no difference
assert_eq!(_0.swap_bytes(), _0);
assert_eq!(_1.swap_bytes(), _1);
}
// Swapping these should make no difference
assert_eq!(_0.swap_bytes(), _0);
assert_eq!(_1.swap_bytes(), _1);
}
#[test]
fn test_reverse_bits() {
assert_eq!(A.reverse_bits().reverse_bits(), A);
assert_eq!(B.reverse_bits().reverse_bits(), B);
assert_eq!(C.reverse_bits().reverse_bits(), C);
#[test]
fn test_reverse_bits() {
assert_eq!(A.reverse_bits().reverse_bits(), A);
assert_eq!(B.reverse_bits().reverse_bits(), B);
assert_eq!(C.reverse_bits().reverse_bits(), C);
// Swapping these should make no difference
assert_eq!(_0.reverse_bits(), _0);
assert_eq!(_1.reverse_bits(), _1);
}
// Swapping these should make no difference
assert_eq!(_0.reverse_bits(), _0);
assert_eq!(_1.reverse_bits(), _1);
}
#[test]
fn test_le() {
assert_eq!($T::from_le(A.to_le()), A);
assert_eq!($T::from_le(B.to_le()), B);
assert_eq!($T::from_le(C.to_le()), C);
assert_eq!($T::from_le(_0), _0);
assert_eq!($T::from_le(_1), _1);
assert_eq!(_0.to_le(), _0);
assert_eq!(_1.to_le(), _1);
}
#[test]
fn test_le() {
assert_eq!($T::from_le(A.to_le()), A);
assert_eq!($T::from_le(B.to_le()), B);
assert_eq!($T::from_le(C.to_le()), C);
assert_eq!($T::from_le(_0), _0);
assert_eq!($T::from_le(_1), _1);
assert_eq!(_0.to_le(), _0);
assert_eq!(_1.to_le(), _1);
}
#[test]
fn test_be() {
assert_eq!($T::from_be(A.to_be()), A);
assert_eq!($T::from_be(B.to_be()), B);
assert_eq!($T::from_be(C.to_be()), C);
assert_eq!($T::from_be(_0), _0);
assert_eq!($T::from_be(_1), _1);
assert_eq!(_0.to_be(), _0);
assert_eq!(_1.to_be(), _1);
}
#[test]
fn test_be() {
assert_eq!($T::from_be(A.to_be()), A);
assert_eq!($T::from_be(B.to_be()), B);
assert_eq!($T::from_be(C.to_be()), C);
assert_eq!($T::from_be(_0), _0);
assert_eq!($T::from_be(_1), _1);
assert_eq!(_0.to_be(), _0);
assert_eq!(_1.to_be(), _1);
}
#[test]
fn test_unsigned_checked_div() {
assert!((10 as $T).checked_div(2) == Some(5));
assert!((5 as $T).checked_div(0) == None);
}
#[test]
fn test_unsigned_checked_div() {
assert!((10 as $T).checked_div(2) == Some(5));
assert!((5 as $T).checked_div(0) == None);
}
fn from_str<T: FromStr>(t: &str) -> Option<T> {
FromStr::from_str(t).ok()
}
fn from_str<T: FromStr>(t: &str) -> Option<T> {
FromStr::from_str(t).ok()
}
#[test]
pub fn test_from_str() {
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
#[test]
pub fn test_from_str() {
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
#[test]
pub fn test_parse_bytes() {
assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
#[test]
pub fn test_parse_bytes() {
assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
}
assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
}
}
};
}
)}

View file

@ -1,4 +1,4 @@
use core::ops::{Bound, Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
// Test the Range structs without the syntactic sugar.
@ -59,28 +59,27 @@ fn test_range_inclusive() {
assert_eq!(r.next(), None);
}
#[test]
fn test_range_is_empty() {
use core::f32::*;
assert!(!(0.0 .. 10.0).is_empty());
assert!( (-0.0 .. 0.0).is_empty());
assert!( (10.0 .. 0.0).is_empty());
assert!(!(0.0..10.0).is_empty());
assert!((-0.0..0.0).is_empty());
assert!((10.0..0.0).is_empty());
assert!(!(NEG_INFINITY .. INFINITY).is_empty());
assert!( (EPSILON .. NAN).is_empty());
assert!( (NAN .. EPSILON).is_empty());
assert!( (NAN .. NAN).is_empty());
assert!(!(NEG_INFINITY..INFINITY).is_empty());
assert!((EPSILON..NAN).is_empty());
assert!((NAN..EPSILON).is_empty());
assert!((NAN..NAN).is_empty());
assert!(!(0.0 ..= 10.0).is_empty());
assert!(!(-0.0 ..= 0.0).is_empty());
assert!( (10.0 ..= 0.0).is_empty());
assert!(!(0.0..=10.0).is_empty());
assert!(!(-0.0..=0.0).is_empty());
assert!((10.0..=0.0).is_empty());
assert!(!(NEG_INFINITY ..= INFINITY).is_empty());
assert!( (EPSILON ..= NAN).is_empty());
assert!( (NAN ..= EPSILON).is_empty());
assert!( (NAN ..= NAN).is_empty());
assert!(!(NEG_INFINITY..=INFINITY).is_empty());
assert!((EPSILON..=NAN).is_empty());
assert!((NAN..=EPSILON).is_empty());
assert!((NAN..=NAN).is_empty());
}
#[test]

View file

@ -1,8 +1,8 @@
use core::option::*;
use core::mem;
use core::clone::Clone;
use core::array::FixedSizeArray;
use core::clone::Clone;
use core::mem;
use core::ops::DerefMut;
use core::option::*;
#[test]
fn test_get_ptr() {
@ -28,15 +28,15 @@ fn test_get_str() {
#[test]
fn test_get_resource() {
use std::rc::Rc;
use core::cell::RefCell;
use std::rc::Rc;
struct R {
i: Rc<RefCell<isize>>,
i: Rc<RefCell<isize>>,
}
impl Drop for R {
fn drop(&mut self) {
impl Drop for R {
fn drop(&mut self) {
let ii = &*self.i;
let i = *ii.borrow();
*ii.borrow_mut() = i + 1;
@ -44,9 +44,7 @@ fn test_get_resource() {
}
fn r(i: Rc<RefCell<isize>>) -> R {
R {
i,
}
R { i }
}
let i = Rc::new(RefCell::new(0));
@ -70,7 +68,8 @@ fn test_option_dance() {
assert!(y.is_none());
}
#[test] #[should_panic]
#[test]
#[should_panic]
fn test_option_too_much_dance() {
struct A;
let mut y = Some(A);
@ -210,7 +209,7 @@ fn test_mut_iter() {
fn test_ord() {
let small = Some(1.0f64);
let big = Some(5.0f64);
let nan = Some(0.0f64/0.0);
let nan = Some(0.0f64 / 0.0);
assert!(!(nan < big));
assert!(!(nan > big));
assert!(small < big);
@ -226,9 +225,7 @@ fn test_collect() {
let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
assert!(v == Some(vec![0, 1, 2]));
let v: Option<Vec<isize>> = (0..3).map(|x| {
if x > 1 { None } else { Some(x) }
}).collect();
let v: Option<Vec<isize>> = (0..3).map(|x| if x > 1 { None } else { Some(x) }).collect();
assert!(v == None);
// test that it does not take more elements than it needs

View file

@ -1,14 +1,14 @@
use core::ptr::*;
use core::cell::RefCell;
use core::ptr::*;
#[test]
fn test() {
unsafe {
struct Pair {
fst: isize,
snd: isize
snd: isize,
};
let mut p = Pair {fst: 10, snd: 20};
let mut p = Pair { fst: 10, snd: 20 };
let pptr: *mut Pair = &mut p;
let iptr: *mut isize = pptr as *mut isize;
assert_eq!(*iptr, 10);
@ -16,7 +16,7 @@ fn test() {
assert_eq!(*iptr, 30);
assert_eq!(p.fst, 30);
*pptr = Pair {fst: 50, snd: 60};
*pptr = Pair { fst: 50, snd: 60 };
assert_eq!(*iptr, 50);
assert_eq!(p.fst, 50);
assert_eq!(p.snd, 60);
@ -25,17 +25,11 @@ fn test() {
let mut v1 = vec![0u16, 0u16, 0u16];
copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
assert!((v1[0] == 0u16 &&
v1[1] == 32001u16 &&
v1[2] == 0u16));
assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
assert!((v1[0] == 32002u16 &&
v1[1] == 32001u16 &&
v1[2] == 0u16));
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
assert!((v1[0] == 32002u16 &&
v1[1] == 32001u16 &&
v1[2] == 32000u16));
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16));
}
}
@ -208,7 +202,7 @@ fn test_ptr_addition() {
#[test]
fn test_ptr_subtraction() {
unsafe {
let xs = vec![0,1,2,3,4,5,6,7,8,9];
let xs = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut idx = 9;
let ptr = xs.as_ptr();
@ -229,7 +223,7 @@ fn test_ptr_subtraction() {
m_ptr = m_ptr.offset(-1);
}
assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
assert_eq!(xs_mut, [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
}
}
@ -237,7 +231,9 @@ fn test_ptr_subtraction() {
fn test_set_memory() {
let mut xs = [0u8; 20];
let ptr = xs.as_mut_ptr();
unsafe { write_bytes(ptr, 5u8, xs.len()); }
unsafe {
write_bytes(ptr, 5u8, xs.len());
}
assert!(xs == [5u8; 20]);
}
@ -257,10 +253,10 @@ fn test_unsized_nonnull() {
#[no_mangle]
pub fn test_variadic_fnptr() {
use core::hash::{Hash, SipHasher};
extern {
extern "C" {
fn test_variadic_fnptr(_: u64, ...) -> f64;
}
let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
let p: unsafe extern "C" fn(u64, ...) -> f64 = test_variadic_fnptr;
let q = p.clone();
assert_eq!(p, q);
assert!(!(p < q));
@ -285,13 +281,15 @@ fn write_unaligned_drop() {
{
let c = Dropper(0);
let mut t = Dropper(1);
unsafe { write_unaligned(&mut t, c); }
unsafe {
write_unaligned(&mut t, c);
}
}
DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
}
#[test]
#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn align_offset_zst() {
// For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
// all, because no amount of elements will align the pointer.
@ -306,24 +304,29 @@ fn align_offset_zst() {
}
#[test]
#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn align_offset_stride1() {
// For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
// number of bytes.
let mut align = 1;
while align < 1024 {
for ptr in 1..2*align {
for ptr in 1..2 * align {
let expected = ptr % align;
let offset = if expected == 0 { 0 } else { align - expected };
assert_eq!((ptr as *const u8).align_offset(align), offset,
"ptr = {}, align = {}, size = 1", ptr, align);
assert_eq!(
(ptr as *const u8).align_offset(align),
offset,
"ptr = {}, align = {}, size = 1",
ptr,
align
);
}
align = (align + 1).next_power_of_two();
}
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn align_offset_weird_strides() {
#[repr(packed)]
struct A3(u16, u8);
@ -353,8 +356,14 @@ fn align_offset_weird_strides() {
}
let got = ptr.align_offset(align);
if got != expected {
eprintln!("aligning {:p} (with stride of {}) to {}, expected {}, got {}", ptr,
::std::mem::size_of::<T>(), align, expected, got);
eprintln!(
"aligning {:p} (with stride of {}) to {}, expected {}, got {}",
ptr,
::std::mem::size_of::<T>(),
align,
expected,
got
);
return true;
}
return false;
@ -365,7 +374,7 @@ fn align_offset_weird_strides() {
let mut align = 1;
let mut x = false;
while align < 1024 {
for ptr in 1usize..4*align {
for ptr in 1usize..4 * align {
unsafe {
x |= test_weird_stride::<A3>(ptr as *const A3, align);
x |= test_weird_stride::<A4>(ptr as *const A4, align);

View file

@ -1,4 +1,4 @@
use core::result::Result::{Ok, Err};
use core::result::Result::{Err, Ok};
#[test]
fn test_position() {
@ -50,8 +50,14 @@ fn test_binary_search() {
assert_eq!(b.binary_search(&0), Err(0));
assert_eq!(b.binary_search(&1), Ok(0));
assert_eq!(b.binary_search(&2), Err(1));
assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
assert!(match b.binary_search(&3) {
Ok(1..=3) => true,
_ => false,
});
assert!(match b.binary_search(&3) {
Ok(1..=3) => true,
_ => false,
});
assert_eq!(b.binary_search(&4), Err(4));
assert_eq!(b.binary_search(&5), Err(4));
assert_eq!(b.binary_search(&6), Err(4));
@ -187,7 +193,8 @@ fn test_chunks_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
let res = v1.chunks(2)
let res = v1
.chunks(2)
.zip(v2.chunks(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@ -339,7 +346,8 @@ fn test_chunks_exact_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
let res = v1.chunks_exact(2)
let res = v1
.chunks_exact(2)
.zip(v2.chunks_exact(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@ -482,7 +490,8 @@ fn test_rchunks_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
let res = v1.rchunks(2)
let res = v1
.rchunks(2)
.zip(v2.rchunks(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@ -619,7 +628,8 @@ fn test_rchunks_exact_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
let res = v1.rchunks_exact(2)
let res = v1
.rchunks_exact(2)
.zip(v2.rchunks_exact(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@ -756,7 +766,8 @@ fn test_windows_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
let res = v1.windows(2)
let res = v1
.windows(2)
.zip(v2.windows(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@ -769,11 +780,11 @@ fn test_windows_zip() {
fn test_iter_ref_consistency() {
use std::fmt::Debug;
fn test<T : Copy + Debug + PartialEq>(x : T) {
let v : &[T] = &[x, x, x];
let v_ptrs : [*const T; 3] = match v {
fn test<T: Copy + Debug + PartialEq>(x: T) {
let v: &[T] = &[x, x, x];
let v_ptrs: [*const T; 3] = match v {
[ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
_ => unreachable!()
_ => unreachable!(),
};
let len = v.len();
@ -817,19 +828,20 @@ fn test_iter_ref_consistency() {
assert_eq!(it.size_hint(), (remaining, Some(remaining)));
let prev = it.next_back().unwrap();
assert_eq!(prev as *const _, v_ptrs[remaining-1]);
assert_eq!(prev as *const _, v_ptrs[remaining - 1]);
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
}
}
fn test_mut<T : Copy + Debug + PartialEq>(x : T) {
let v : &mut [T] = &mut [x, x, x];
let v_ptrs : [*mut T; 3] = match v {
[ref v1, ref v2, ref v3] =>
[v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _],
_ => unreachable!()
fn test_mut<T: Copy + Debug + PartialEq>(x: T) {
let v: &mut [T] = &mut [x, x, x];
let v_ptrs: [*mut T; 3] = match v {
[ref v1, ref v2, ref v3] => {
[v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _]
}
_ => unreachable!(),
};
let len = v.len();
@ -873,7 +885,7 @@ fn test_iter_ref_consistency() {
assert_eq!(it.size_hint(), (remaining, Some(remaining)));
let prev = it.next_back().unwrap();
assert_eq!(prev as *mut _, v_ptrs[remaining-1]);
assert_eq!(prev as *mut _, v_ptrs[remaining - 1]);
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
@ -897,8 +909,7 @@ mod slice_index {
// This checks all six indexing methods, given an input range that
// should succeed. (it is NOT suitable for testing invalid inputs)
macro_rules! assert_range_eq {
($arr:expr, $range:expr, $expected:expr)
=> {
($arr:expr, $range:expr, $expected:expr) => {
let mut arr = $arr;
let mut expected = $expected;
{
@ -909,7 +920,8 @@ mod slice_index {
assert_eq!(s.get($range), Some(expected), "(in assertion for: get)");
unsafe {
assert_eq!(
s.get_unchecked($range), expected,
s.get_unchecked($range),
expected,
"(in assertion for: get_unchecked)",
);
}
@ -918,22 +930,21 @@ mod slice_index {
let s: &mut [_] = &mut arr;
let expected: &mut [_] = &mut expected;
assert_eq!(&mut s[$range], expected, "(in assertion for: index_mut)",);
assert_eq!(
&mut s[$range], expected,
"(in assertion for: index_mut)",
);
assert_eq!(
s.get_mut($range), Some(&mut expected[..]),
s.get_mut($range),
Some(&mut expected[..]),
"(in assertion for: get_mut)",
);
unsafe {
assert_eq!(
s.get_unchecked_mut($range), expected,
s.get_unchecked_mut($range),
expected,
"(in assertion for: get_unchecked_mut)",
);
}
}
}
};
}
// Make sure the macro can actually detect bugs,
@ -1126,8 +1137,8 @@ fn test_find_rfind() {
#[test]
fn test_iter_folds() {
let a = [1, 2, 3, 4, 5]; // len>4 so the unroll is used
assert_eq!(a.iter().fold(0, |acc, &x| 2*acc + x), 57);
assert_eq!(a.iter().rfold(0, |acc, &x| 2*acc + x), 129);
assert_eq!(a.iter().fold(0, |acc, &x| 2 * acc + x), 57);
assert_eq!(a.iter().rfold(0, |acc, &x| 2 * acc + x), 129);
let fold = |acc: i32, &x| acc.checked_mul(2)?.checked_add(x);
assert_eq!(a.iter().try_fold(0, &fold), Some(57));
assert_eq!(a.iter().try_rfold(0, &fold), Some(129));
@ -1172,7 +1183,7 @@ fn test_rotate_right() {
}
#[test]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn brute_force_rotate_test_0() {
// In case of edge cases involving multiple algorithms
let n = 300;
@ -1214,7 +1225,7 @@ fn brute_force_rotate_test_1() {
fn sort_unstable() {
use core::cmp::Ordering::{Equal, Greater, Less};
use core::slice::heapsort;
use rand::{SeedableRng, Rng, rngs::StdRng, seq::SliceRandom};
use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};
#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
@ -1291,12 +1302,12 @@ fn sort_unstable() {
#[test]
#[cfg(not(target_arch = "wasm32"))]
#[cfg(not(miri))] // Miri is too slow
#[cfg_attr(miri, ignore)] // Miri is too slow
fn partition_at_index() {
use core::cmp::Ordering::{Equal, Greater, Less};
use rand::rngs::StdRng;
use rand::seq::SliceRandom;
use rand::{SeedableRng, Rng};
use rand::{Rng, SeedableRng};
let mut rng = StdRng::from_entropy();
@ -1494,7 +1505,7 @@ pub mod memchr {
}
#[test]
#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn test_align_to_simple() {
let bytes = [1u8, 2, 3, 4, 5, 6, 7];
let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
@ -1504,9 +1515,15 @@ fn test_align_to_simple() {
let expect2 = [1 | 2 << 8, 3 | 4 << 8, 5 | 6 << 8];
let expect3 = [2 << 8 | 3, 4 << 8 | 5, 6 << 8 | 7];
let expect4 = [2 | 3 << 8, 4 | 5 << 8, 6 | 7 << 8];
assert!(aligned == expect1 || aligned == expect2 || aligned == expect3 || aligned == expect4,
"aligned={:?} expected={:?} || {:?} || {:?} || {:?}",
aligned, expect1, expect2, expect3, expect4);
assert!(
aligned == expect1 || aligned == expect2 || aligned == expect3 || aligned == expect4,
"aligned={:?} expected={:?} || {:?} || {:?} || {:?}",
aligned,
expect1,
expect2,
expect3,
expect4
);
}
#[test]
@ -1518,12 +1535,22 @@ fn test_align_to_zst() {
}
#[test]
#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn test_align_to_non_trivial() {
#[repr(align(8))] struct U64(u64, u64);
#[repr(align(8))] struct U64U64U32(u64, u64, u32);
let data = [U64(1, 2), U64(3, 4), U64(5, 6), U64(7, 8), U64(9, 10), U64(11, 12), U64(13, 14),
U64(15, 16)];
#[repr(align(8))]
struct U64(u64, u64);
#[repr(align(8))]
struct U64U64U32(u64, u64, u32);
let data = [
U64(1, 2),
U64(3, 4),
U64(5, 6),
U64(7, 8),
U64(9, 10),
U64(11, 12),
U64(13, 14),
U64(15, 16),
];
let (prefix, aligned, suffix) = unsafe { data.align_to::<U64U64U32>() };
assert_eq!(aligned.len(), 4);
assert_eq!(prefix.len() + suffix.len(), 2);
@ -1538,7 +1565,7 @@ fn test_align_to_empty_mid() {
let bytes = [1, 2, 3, 4, 5, 6, 7];
type Chunk = u32;
for offset in 0..4 {
let (_, mid, _) = unsafe { bytes[offset..offset+1].align_to::<Chunk>() };
let (_, mid, _) = unsafe { bytes[offset..offset + 1].align_to::<Chunk>() };
assert_eq!(mid.as_ptr() as usize % mem::align_of::<Chunk>(), 0);
}
}

View file

@ -3,65 +3,65 @@ use core::str::lossy::*;
#[test]
fn chunks() {
let mut iter = Utf8Lossy::from_bytes(b"hello").chunks();
assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"", }), iter.next());
assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"" }), iter.next());
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!(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!(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!(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!(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!(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!(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!(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());
// 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!(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());
}
@ -69,13 +69,17 @@ fn chunks() {
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());
&Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
);
}
#[test]
fn debug() {
assert_eq!(
"\"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")));
&format!(
"{:?}",
Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa")
)
);
}

View file

@ -3,10 +3,11 @@ use core::time::Duration;
#[test]
fn creation() {
assert_ne!(Duration::from_secs(1), Duration::from_secs(0));
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
Duration::from_secs(3));
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
Duration::new(4, 10 * 1_000_000));
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2), Duration::from_secs(3));
assert_eq!(
Duration::from_millis(10) + Duration::from_secs(4),
Duration::new(4, 10 * 1_000_000)
);
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
}
@ -68,29 +69,25 @@ fn nanos() {
#[test]
fn add() {
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
Duration::new(0, 1));
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
Duration::new(1, 1));
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1), Duration::new(0, 1));
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001), Duration::new(1, 1));
}
#[test]
fn checked_add() {
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
Some(Duration::new(0, 1)));
assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
Some(Duration::new(1, 1)));
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
assert_eq!(
Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
Some(Duration::new(1, 1))
);
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::core::u64::MAX, 0)), None);
}
#[test]
fn sub() {
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
Duration::new(0, 1));
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
Duration::new(0, 1));
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
Duration::new(0, 999_999_999));
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0), Duration::new(0, 1));
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000), Duration::new(0, 1));
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1), Duration::new(0, 999_999_999));
}
#[test]
@ -99,8 +96,7 @@ fn checked_sub() {
let one_nano = Duration::new(0, 1);
let one_sec = Duration::new(1, 0);
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
assert_eq!(one_sec.checked_sub(one_nano),
Some(Duration::new(0, 999_999_999)));
assert_eq!(one_sec.checked_sub(one_nano), Some(Duration::new(0, 999_999_999)));
assert_eq!(zero.checked_sub(one_nano), None);
assert_eq!(zero.checked_sub(one_sec), None);
}
@ -122,8 +118,7 @@ fn mul() {
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
assert_eq!(Duration::new(0, 500_000_001) * 4000,
Duration::new(2000, 4000));
assert_eq!(Duration::new(0, 500_000_001) * 4000, Duration::new(2000, 4000));
}
#[test]
@ -131,8 +126,7 @@ fn checked_mul() {
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
Some(Duration::new(2000, 4000)));
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000), Some(Duration::new(2000, 4000)));
assert_eq!(Duration::new(::core::u64::MAX - 1, 0).checked_mul(2), None);
}
@ -140,8 +134,7 @@ fn checked_mul() {
fn div() {
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
assert_eq!(Duration::new(99, 999_999_000) / 100,
Duration::new(0, 999_999_990));
assert_eq!(Duration::new(99, 999_999_000) / 100, Duration::new(0, 999_999_990));
}
#[test]
@ -162,7 +155,7 @@ fn correct_sum() {
Duration::new(5, 0),
];
let sum = durations.iter().sum::<Duration>();
assert_eq!(sum, Duration::new(1+2+5+4, 1_000_000_000 - 5));
assert_eq!(sum, Duration::new(1 + 2 + 5 + 4, 1_000_000_000 - 5));
}
#[test]
@ -286,9 +279,9 @@ fn debug_formatting_precision_two() {
#[test]
fn debug_formatting_precision_high() {
assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs");
assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs");
assert_eq!(format!("{:.9?}", Duration::new(1, 000_000_000)), "1.000000000s");
assert_eq!(format!("{:.9?}", Duration::new(1, 000_000_000)), "1.000000000s");
assert_eq!(format!("{:.10?}", Duration::new(4, 001_000_000)), "4.0010000000s");
assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s");
}

View file

@ -1,4 +1,4 @@
use std::cmp::Ordering::{Equal, Less, Greater};
use std::cmp::Ordering::{Equal, Greater, Less};
use std::f64::NAN;
#[test]

View file

@ -278,15 +278,15 @@ impl<'tcx> Body<'tcx> {
/// Returns an iterator over all function arguments.
#[inline]
pub fn args_iter(&self) -> impl Iterator<Item = Local> {
pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
(1..=arg_count).map(Local::new)
(1..arg_count + 1).map(Local::new)
}
/// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
/// locals that are neither arguments nor the return place).
#[inline]
pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> {
pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
let local_count = self.local_decls.len();
(arg_count + 1..local_count).map(Local::new)
@ -2380,11 +2380,15 @@ impl<'tcx> UserTypeProjections {
UserTypeProjections { contents: projs.collect() }
}
pub fn projections_and_spans(&self) -> impl Iterator<Item = &(UserTypeProjection, Span)> {
pub fn projections_and_spans(&self)
-> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator
{
self.contents.iter()
}
pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> {
pub fn projections(&self)
-> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator
{
self.contents.iter().map(|&(ref user_type, _span)| user_type)
}

View file

@ -240,7 +240,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id);
let param = generics.type_param(&param_ty, tcx);
if let Some(generics) = tcx.hir().get_generics(self.mir_def_id) {
if let Some(generics) =
tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) {
suggest_constraining_type_param(
generics,
&mut err,

View file

@ -304,7 +304,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if !self.stack.is_empty() {
// This should change *something*
debug_assert!(self.cur_frame() != old_stack || self.frame().block != old_bb);
info!("// {:?}", self.frame().block);
if let Some(block) = self.frame().block {
info!("// executing {:?}", block);
}
}
Ok(())
}

View file

@ -158,14 +158,14 @@ impl<'a> AstValidator<'a> {
err.emit();
}
fn check_decl_no_pat<F: FnMut(Span, bool)>(decl: &FnDecl, mut report_err: F) {
for arg in &decl.inputs {
match arg.pat.kind {
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, bool)) {
for Param { pat, .. } in &decl.inputs {
match pat.kind {
PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) |
PatKind::Wild => {}
PatKind::Ident(BindingMode::ByValue(Mutability::Mutable), _, None) =>
report_err(arg.pat.span, true),
_ => report_err(arg.pat.span, false),
report_err(pat.span, true),
_ => report_err(pat.span, false),
}
}
}

View file

@ -12,7 +12,7 @@ use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleIm
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
use crate::{ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas, ExternPreludeEntry};
use crate::Namespace::{self, TypeNS, ValueNS, MacroNS};
use crate::{ResolutionError, Determinacy, PathResult, CrateLint};
use crate::{ResolutionError, VisResolutionError, Determinacy, PathResult, CrateLint};
use rustc::bug;
use rustc::hir::def::{self, *};
@ -32,8 +32,7 @@ use syntax::attr;
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
use syntax::token::{self, Token};
use syntax::print::pprust;
use syntax::{span_err, struct_span_err};
use syntax::span_err;
use syntax::source_map::{respan, Spanned};
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
@ -192,14 +191,25 @@ impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
self.resolve_visibility_speculative(vis, false).unwrap_or_else(|err| {
self.r.report_vis_error(err);
ty::Visibility::Public
})
}
fn resolve_visibility_speculative<'ast>(
&mut self,
vis: &'ast ast::Visibility,
speculative: bool,
) -> Result<ty::Visibility, VisResolutionError<'ast>> {
let parent_scope = &self.parent_scope;
match vis.node {
ast::VisibilityKind::Public => ty::Visibility::Public,
ast::VisibilityKind::Public => Ok(ty::Visibility::Public),
ast::VisibilityKind::Crate(..) => {
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
}
ast::VisibilityKind::Inherited => {
ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id)
Ok(ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id))
}
ast::VisibilityKind::Restricted { ref path, id, .. } => {
// For visibilities we are not ready to provide correct implementation of "uniform
@ -209,86 +219,67 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let ident = path.segments.get(0).expect("empty path in visibility").ident;
let crate_root = if ident.is_path_segment_keyword() {
None
} else if ident.span.rust_2018() {
let msg = "relative paths are not supported in visibilities on 2018 edition";
self.r.session.struct_span_err(ident.span, msg)
.span_suggestion(
path.span,
"try",
format!("crate::{}", pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
)
.emit();
return ty::Visibility::Public;
} else {
let ctxt = ident.span.ctxt();
} else if ident.span.rust_2015() {
Some(Segment::from_ident(Ident::new(
kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ctxt)
kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ident.span.ctxt())
)))
} else {
return Err(VisResolutionError::Relative2018(ident.span, path));
};
let segments = crate_root.into_iter()
.chain(path.segments.iter().map(|seg| seg.into())).collect::<Vec<_>>();
let expected_found_error = |this: &Self, res: Res| {
let path_str = Segment::names_to_string(&segments);
struct_span_err!(this.r.session, path.span, E0577,
"expected module, found {} `{}`", res.descr(), path_str)
.span_label(path.span, "not a module").emit();
};
let expected_found_error = |res| Err(VisResolutionError::ExpectedFound(
path.span, Segment::names_to_string(&segments), res
));
match self.r.resolve_path(
&segments,
Some(TypeNS),
parent_scope,
true,
!speculative,
path.span,
CrateLint::SimplePath(id),
) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
let res = module.res().expect("visibility resolved to unnamed block");
self.r.record_partial_res(id, PartialRes::new(res));
if !speculative {
self.r.record_partial_res(id, PartialRes::new(res));
}
if module.is_normal() {
if res == Res::Err {
ty::Visibility::Public
Ok(ty::Visibility::Public)
} else {
let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) {
vis
Ok(vis)
} else {
struct_span_err!(self.r.session, path.span, E0742,
"visibilities can only be restricted to ancestor modules")
.emit();
ty::Visibility::Public
Err(VisResolutionError::AncestorOnly(path.span))
}
}
} else {
expected_found_error(self, res);
ty::Visibility::Public
expected_found_error(res)
}
}
PathResult::Module(..) => {
self.r.session.span_err(path.span, "visibility must resolve to a module");
ty::Visibility::Public
}
PathResult::NonModule(partial_res) => {
expected_found_error(self, partial_res.base_res());
ty::Visibility::Public
}
PathResult::Failed { span, label, suggestion, .. } => {
self.r.report_error(
span, ResolutionError::FailedToResolve { label, suggestion }
);
ty::Visibility::Public
}
PathResult::Indeterminate => {
span_err!(self.r.session, path.span, E0578,
"cannot determine resolution for the visibility");
ty::Visibility::Public
}
PathResult::Module(..) =>
Err(VisResolutionError::ModuleOnly(path.span)),
PathResult::NonModule(partial_res) =>
expected_found_error(partial_res.base_res()),
PathResult::Failed { span, label, suggestion, .. } =>
Err(VisResolutionError::FailedToResolve(span, label, suggestion)),
PathResult::Indeterminate =>
Err(VisResolutionError::Indeterminate(path.span)),
}
}
}
}
fn insert_field_names_local(&mut self, def_id: DefId, vdata: &ast::VariantData) {
let field_names = vdata.fields().iter().map(|field| {
respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
}).collect();
self.insert_field_names(def_id, field_names);
}
fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Spanned<Name>>) {
if !field_names.is_empty() {
self.r.field_names.insert(def_id, field_names);
@ -726,59 +717,52 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
// These items live in both the type and value namespaces.
ItemKind::Struct(ref struct_def, _) => {
ItemKind::Struct(ref vdata, _) => {
// Define a name in the type namespace.
let def_id = self.r.definitions.local_def_id(item.id);
let res = Res::Def(DefKind::Struct, def_id);
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
let mut ctor_vis = vis;
let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive);
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
if has_non_exhaustive && vis == ty::Visibility::Public {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}
// Record field names for error reporting.
let field_names = struct_def.fields().iter().map(|field| {
// NOTE: The field may be an expansion placeholder, but expansion sets correct
// visibilities for unnamed field placeholders specifically, so the constructor
// visibility should still be determined correctly.
let field_vis = self.resolve_visibility(&field.vis);
if ctor_vis.is_at_least(field_vis, &*self.r) {
ctor_vis = field_vis;
}
respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
}).collect();
let item_def_id = self.r.definitions.local_def_id(item.id);
self.insert_field_names(item_def_id, field_names);
self.insert_field_names_local(def_id, vdata);
// If this is a tuple or unit struct, define a name
// in the value namespace as well.
if let Some(ctor_node_id) = struct_def.ctor_id() {
if let Some(ctor_node_id) = vdata.ctor_id() {
let mut ctor_vis = vis;
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
if vis == ty::Visibility::Public &&
attr::contains_name(&item.attrs, sym::non_exhaustive) {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}
for field in vdata.fields() {
// NOTE: The field may be an expansion placeholder, but expansion sets
// correct visibilities for unnamed field placeholders specifically, so the
// constructor visibility should still be determined correctly.
if let Ok(field_vis) =
self.resolve_visibility_speculative(&field.vis, true) {
if ctor_vis.is_at_least(field_vis, &*self.r) {
ctor_vis = field_vis;
}
}
}
let ctor_res = Res::Def(
DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)),
DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)),
self.r.definitions.local_def_id(ctor_node_id),
);
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
self.r.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis));
self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis));
}
}
ItemKind::Union(ref vdata, _) => {
let res = Res::Def(DefKind::Union, self.r.definitions.local_def_id(item.id));
let def_id = self.r.definitions.local_def_id(item.id);
let res = Res::Def(DefKind::Union, def_id);
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
// Record field names for error reporting.
let field_names = vdata.fields().iter().map(|field| {
self.resolve_visibility(&field.vis);
respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
}).collect();
let item_def_id = self.r.definitions.local_def_id(item.id);
self.insert_field_names(item_def_id, field_names);
self.insert_field_names_local(def_id, vdata);
}
ItemKind::Impl(.., ref impl_items) => {
@ -1281,6 +1265,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
if sf.is_placeholder {
self.visit_invoc(sf.id);
} else {
self.resolve_visibility(&sf.vis);
visit::walk_struct_field(self, sf);
}
}

View file

@ -11,6 +11,7 @@ use rustc::ty::{self, DefIdTree};
use rustc::util::nodemap::FxHashSet;
use rustc_feature::BUILTIN_ATTRIBUTES;
use syntax::ast::{self, Ident, Path};
use syntax::print::pprust;
use syntax::source_map::SourceMap;
use syntax::struct_span_err;
use syntax::symbol::{Symbol, kw};
@ -22,6 +23,7 @@ use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportRes
use crate::path_names_to_string;
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};
use crate::VisResolutionError;
use rustc_error_codes::*;
@ -357,6 +359,44 @@ impl<'a> Resolver<'a> {
}
}
crate fn report_vis_error(&self, vis_resolution_error: VisResolutionError<'_>) {
match vis_resolution_error {
VisResolutionError::Relative2018(span, path) => {
let mut err = self.session.struct_span_err(span,
"relative paths are not supported in visibilities on 2018 edition");
err.span_suggestion(
path.span,
"try",
format!("crate::{}", pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
);
err
}
VisResolutionError::AncestorOnly(span) => {
struct_span_err!(self.session, span, E0742,
"visibilities can only be restricted to ancestor modules")
}
VisResolutionError::FailedToResolve(span, label, suggestion) => {
self.into_struct_error(
span, ResolutionError::FailedToResolve { label, suggestion }
)
}
VisResolutionError::ExpectedFound(span, path_str, res) => {
let mut err = struct_span_err!(self.session, span, E0577,
"expected module, found {} `{}`", res.descr(), path_str);
err.span_label(span, "not a module");
err
}
VisResolutionError::Indeterminate(span) => {
struct_span_err!(self.session, span, E0578,
"cannot determine resolution for the visibility")
}
VisResolutionError::ModuleOnly(span) => {
self.session.struct_span_err(span, "visibility must resolve to a module")
}
}.emit()
}
/// Lookup typo candidate in scope for a macro or import.
fn early_lookup_typo_candidate(
&mut self,

View file

@ -218,6 +218,15 @@ enum ResolutionError<'a> {
SelfInTyParamDefault,
}
enum VisResolutionError<'a> {
Relative2018(Span, &'a ast::Path),
AncestorOnly(Span),
FailedToResolve(Span, String, Option<Suggestion>),
ExpectedFound(Span, String, Res),
Indeterminate(Span),
ModuleOnly(Span),
}
// A minimal representation of a path segment. We use this in resolve because
// we synthesize 'path segments' which don't have the rest of an AST or HIR
// `PathSegment`.

View file

@ -495,11 +495,13 @@ impl OsStr {
///
/// let os_str = OsStr::new("foo");
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
s.as_ref()
}
#[inline]
fn from_inner(inner: &Slice) -> &OsStr {
unsafe { &*(inner as *const Slice as *const OsStr) }
}
@ -658,6 +660,7 @@ impl OsStr {
///
/// Note: it is *crucial* that this API is private, to avoid
/// revealing the internal, platform-specific encodings.
#[inline]
fn bytes(&self) -> &[u8] {
unsafe { &*(&self.inner as *const _ as *const [u8]) }
}
@ -797,6 +800,7 @@ impl Default for &OsStr {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
#[inline]
fn eq(&self, other: &OsStr) -> bool {
self.bytes().eq(other.bytes())
}
@ -804,6 +808,7 @@ impl PartialEq for OsStr {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
#[inline]
fn eq(&self, other: &str) -> bool {
*self == *OsStr::new(other)
}
@ -811,6 +816,7 @@ impl PartialEq<str> for OsStr {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
#[inline]
fn eq(&self, other: &OsStr) -> bool {
*other == *OsStr::new(self)
}
@ -944,6 +950,7 @@ impl AsRef<OsStr> for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
#[inline]
fn as_ref(&self) -> &OsStr {
OsStr::from_inner(Slice::from_str(self))
}
@ -951,6 +958,7 @@ impl AsRef<OsStr> for str {
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
#[inline]
fn as_ref(&self) -> &OsStr {
(&**self).as_ref()
}

View file

@ -128,6 +128,7 @@ impl Buf {
}
impl Slice {
#[inline]
pub fn from_str(s: &str) -> &Slice {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}

View file

@ -139,10 +139,12 @@ impl Buf {
}
impl Slice {
#[inline]
fn from_u8_slice(s: &[u8]) -> &Slice {
unsafe { mem::transmute(s) }
}
#[inline]
pub fn from_str(s: &str) -> &Slice {
Slice::from_u8_slice(s.as_bytes())
}

View file

@ -1518,6 +1518,7 @@ impl<'a> State<'a> {
crate fn print_variant(&mut self, v: &ast::Variant) {
self.head("");
self.print_visibility(&v.vis);
let generics = ast::Generics::default();
self.print_struct(&v.data, &generics, v.ident, v.span, false);
match v.disr_expr {

View file

@ -0,0 +1,8 @@
// pp-exact
// Check that the visibility is printed on an enum variant.
fn main() { }
#[cfg(FALSE)]
enum Foo { pub V, }

View file

@ -0,0 +1,25 @@
// Non-builtin attributes do not mess with field visibility resolution (issue #67006).
mod internal {
struct S {
#[rustfmt::skip]
pub(in crate::internal) field: u8 // OK
}
struct Z(
#[rustfmt::skip]
pub(in crate::internal) u8 // OK
);
}
struct S {
#[rustfmt::skip]
pub(in nonexistent) field: u8 //~ ERROR failed to resolve
}
struct Z(
#[rustfmt::skip]
pub(in nonexistent) u8 //~ ERROR failed to resolve
);
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:17:12
|
LL | pub(in nonexistent) field: u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:22:12
|
LL | pub(in nonexistent) u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0433`.

View file

@ -0,0 +1,5 @@
fn foo<T>(t: T) {
|| { t; t; }; //~ ERROR: use of moved value
}
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0382]: use of moved value: `t`
--> $DIR/issue-67123.rs:2:13
|
LL | fn foo<T>(t: T) {
| - help: consider restricting this bound: `T: Copy`
LL | || { t; t; };
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because `t` has type `T`, which does not implement the `Copy` trait
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.