Auto merge of #66917 - Centril:rollup-xj2enik, r=Centril
Rollup of 9 pull requests Successful merges: - #66503 (More useful test error messages on should_panic(expected=...) mismatch) - #66662 (Miri: run panic-catching tests in liballoc) - #66679 (Improve lifetime errors with implicit trait object lifetimes) - #66726 (Use recursion_limit for const eval stack limit) - #66790 (Do `min_const_fn` checks for `SetDiscriminant`s target) - #66832 (const_prop: detect and avoid catching Miri errors that require allocation) - #66880 (Add long error code explanation message for E0203) - #66890 (Format liballoc with rustfmt) - #66896 (pass Queries to compiler callbacks) Failed merges: r? @ghost
This commit is contained in:
commit
4007d4ef26
|
@ -1,15 +1,15 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
use test::Bencher;
|
|
||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
|
use test::Bencher;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn allocate_zeroed() {
|
fn allocate_zeroed() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let layout = Layout::from_size_align(1024, 1).unwrap();
|
let layout = Layout::from_size_align(1024, 1).unwrap();
|
||||||
let ptr = Global.alloc_zeroed(layout.clone())
|
let ptr =
|
||||||
.unwrap_or_else(|_| handle_alloc_error(layout));
|
Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));
|
||||||
|
|
||||||
let mut i = ptr.cast::<u8>().as_ptr();
|
let mut i = ptr.cast::<u8>().as_ptr();
|
||||||
let end = i.add(layout.size());
|
let end = i.add(layout.size());
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use rand::{Rng, seq::SliceRandom, thread_rng};
|
use rand::{seq::SliceRandom, thread_rng, Rng};
|
||||||
use test::{Bencher, black_box};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
macro_rules! map_insert_rand_bench {
|
macro_rules! map_insert_rand_bench {
|
||||||
($name: ident, $n: expr, $map: ident) => (
|
($name: ident, $n: expr, $map: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn $name(b: &mut Bencher) {
|
pub fn $name(b: &mut Bencher) {
|
||||||
let n: usize = $n;
|
let n: usize = $n;
|
||||||
|
@ -27,11 +27,11 @@ macro_rules! map_insert_rand_bench {
|
||||||
});
|
});
|
||||||
black_box(map);
|
black_box(map);
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! map_insert_seq_bench {
|
macro_rules! map_insert_seq_bench {
|
||||||
($name: ident, $n: expr, $map: ident) => (
|
($name: ident, $n: expr, $map: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn $name(b: &mut Bencher) {
|
pub fn $name(b: &mut Bencher) {
|
||||||
let mut map = $map::new();
|
let mut map = $map::new();
|
||||||
|
@ -50,11 +50,11 @@ macro_rules! map_insert_seq_bench {
|
||||||
});
|
});
|
||||||
black_box(map);
|
black_box(map);
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! map_find_rand_bench {
|
macro_rules! map_find_rand_bench {
|
||||||
($name: ident, $n: expr, $map: ident) => (
|
($name: ident, $n: expr, $map: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn $name(b: &mut Bencher) {
|
pub fn $name(b: &mut Bencher) {
|
||||||
let mut map = $map::new();
|
let mut map = $map::new();
|
||||||
|
@ -78,11 +78,11 @@ macro_rules! map_find_rand_bench {
|
||||||
black_box(t);
|
black_box(t);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! map_find_seq_bench {
|
macro_rules! map_find_seq_bench {
|
||||||
($name: ident, $n: expr, $map: ident) => (
|
($name: ident, $n: expr, $map: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn $name(b: &mut Bencher) {
|
pub fn $name(b: &mut Bencher) {
|
||||||
let mut map = $map::new();
|
let mut map = $map::new();
|
||||||
|
@ -101,20 +101,20 @@ macro_rules! map_find_seq_bench {
|
||||||
black_box(x);
|
black_box(x);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
map_insert_rand_bench!{insert_rand_100, 100, BTreeMap}
|
map_insert_rand_bench! {insert_rand_100, 100, BTreeMap}
|
||||||
map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
|
map_insert_rand_bench! {insert_rand_10_000, 10_000, BTreeMap}
|
||||||
|
|
||||||
map_insert_seq_bench!{insert_seq_100, 100, BTreeMap}
|
map_insert_seq_bench! {insert_seq_100, 100, BTreeMap}
|
||||||
map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
|
map_insert_seq_bench! {insert_seq_10_000, 10_000, BTreeMap}
|
||||||
|
|
||||||
map_find_rand_bench!{find_rand_100, 100, BTreeMap}
|
map_find_rand_bench! {find_rand_100, 100, BTreeMap}
|
||||||
map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
|
map_find_rand_bench! {find_rand_10_000, 10_000, BTreeMap}
|
||||||
|
|
||||||
map_find_seq_bench!{find_seq_100, 100, BTreeMap}
|
map_find_seq_bench! {find_seq_100, 100, BTreeMap}
|
||||||
map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
|
map_find_seq_bench! {find_seq_10_000, 10_000, BTreeMap}
|
||||||
|
|
||||||
fn bench_iter(b: &mut Bencher, size: i32) {
|
fn bench_iter(b: &mut Bencher, size: i32) {
|
||||||
let mut map = BTreeMap::<i32, i32>::new();
|
let mut map = BTreeMap::<i32, i32>::new();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
|
use rand::distributions::{Alphanumeric, Standard};
|
||||||
use rand::{thread_rng, Rng, SeedableRng};
|
use rand::{thread_rng, Rng, SeedableRng};
|
||||||
use rand::distributions::{Standard, Alphanumeric};
|
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
use test::{Bencher, black_box};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn iterator(b: &mut Bencher) {
|
fn iterator(b: &mut Bencher) {
|
||||||
|
@ -239,7 +239,7 @@ macro_rules! sort {
|
||||||
b.iter(|| v.clone().$f());
|
b.iter(|| v.clone().$f());
|
||||||
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sort_strings {
|
macro_rules! sort_strings {
|
||||||
|
@ -251,7 +251,7 @@ macro_rules! sort_strings {
|
||||||
b.iter(|| v.clone().$f());
|
b.iter(|| v.clone().$f());
|
||||||
b.bytes = $len * mem::size_of::<&str>() as u64;
|
b.bytes = $len * mem::size_of::<&str>() as u64;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sort_expensive {
|
macro_rules! sort_expensive {
|
||||||
|
@ -273,7 +273,7 @@ macro_rules! sort_expensive {
|
||||||
});
|
});
|
||||||
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sort_lexicographic {
|
macro_rules! sort_lexicographic {
|
||||||
|
@ -284,7 +284,7 @@ macro_rules! sort_lexicographic {
|
||||||
b.iter(|| v.clone().$f(|x| x.to_string()));
|
b.iter(|| v.clone().$f(|x| x.to_string()));
|
||||||
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sort!(sort, sort_small_ascending, gen_ascending, 10);
|
sort!(sort, sort_small_ascending, gen_ascending, 10);
|
||||||
|
@ -325,24 +325,25 @@ macro_rules! reverse {
|
||||||
fn $name(b: &mut Bencher) {
|
fn $name(b: &mut Bencher) {
|
||||||
// odd length and offset by 1 to be as unaligned as possible
|
// odd length and offset by 1 to be as unaligned as possible
|
||||||
let n = 0xFFFFF;
|
let n = 0xFFFFF;
|
||||||
let mut v: Vec<_> =
|
let mut v: Vec<_> = (0..1 + (n / mem::size_of::<$ty>() as u64)).map($f).collect();
|
||||||
(0..1+(n / mem::size_of::<$ty>() as u64))
|
|
||||||
.map($f)
|
|
||||||
.collect();
|
|
||||||
b.iter(|| black_box(&mut v[1..]).reverse());
|
b.iter(|| black_box(&mut v[1..]).reverse());
|
||||||
b.bytes = n;
|
b.bytes = n;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
reverse!(reverse_u8, u8, |x| x as u8);
|
reverse!(reverse_u8, u8, |x| x as u8);
|
||||||
reverse!(reverse_u16, u16, |x| x as u16);
|
reverse!(reverse_u16, u16, |x| x as u16);
|
||||||
reverse!(reverse_u8x3, [u8;3], |x| [x as u8, (x>>8) as u8, (x>>16) as u8]);
|
reverse!(reverse_u8x3, [u8; 3], |x| [x as u8, (x >> 8) as u8, (x >> 16) as u8]);
|
||||||
reverse!(reverse_u32, u32, |x| x as u32);
|
reverse!(reverse_u32, u32, |x| x as u32);
|
||||||
reverse!(reverse_u64, u64, |x| x as u64);
|
reverse!(reverse_u64, u64, |x| x as u64);
|
||||||
reverse!(reverse_u128, u128, |x| x as u128);
|
reverse!(reverse_u128, u128, |x| x as u128);
|
||||||
#[repr(simd)] struct F64x4(f64, f64, f64, f64);
|
#[repr(simd)]
|
||||||
reverse!(reverse_simd_f64x4, F64x4, |x| { let x = x as f64; F64x4(x,x,x,x) });
|
struct F64x4(f64, f64, f64, f64);
|
||||||
|
reverse!(reverse_simd_f64x4, F64x4, |x| {
|
||||||
|
let x = x as f64;
|
||||||
|
F64x4(x, x, x, x)
|
||||||
|
});
|
||||||
|
|
||||||
macro_rules! rotate {
|
macro_rules! rotate {
|
||||||
($name:ident, $gen:expr, $len:expr, $mid:expr) => {
|
($name:ident, $gen:expr, $len:expr, $mid:expr) => {
|
||||||
|
@ -350,32 +351,32 @@ macro_rules! rotate {
|
||||||
fn $name(b: &mut Bencher) {
|
fn $name(b: &mut Bencher) {
|
||||||
let size = mem::size_of_val(&$gen(1)[0]);
|
let size = mem::size_of_val(&$gen(1)[0]);
|
||||||
let mut v = $gen($len * 8 / size);
|
let mut v = $gen($len * 8 / size);
|
||||||
b.iter(|| black_box(&mut v).rotate_left(($mid*8+size-1)/size));
|
b.iter(|| black_box(&mut v).rotate_left(($mid * 8 + size - 1) / size));
|
||||||
b.bytes = (v.len() * size) as u64;
|
b.bytes = (v.len() * size) as u64;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate!(rotate_tiny_by1, gen_random, 16, 1);
|
rotate!(rotate_tiny_by1, gen_random, 16, 1);
|
||||||
rotate!(rotate_tiny_half, gen_random, 16, 16/2);
|
rotate!(rotate_tiny_half, gen_random, 16, 16 / 2);
|
||||||
rotate!(rotate_tiny_half_plus_one, gen_random, 16, 16/2+1);
|
rotate!(rotate_tiny_half_plus_one, gen_random, 16, 16 / 2 + 1);
|
||||||
|
|
||||||
rotate!(rotate_medium_by1, gen_random, 9158, 1);
|
rotate!(rotate_medium_by1, gen_random, 9158, 1);
|
||||||
rotate!(rotate_medium_by727_u64, gen_random, 9158, 727);
|
rotate!(rotate_medium_by727_u64, gen_random, 9158, 727);
|
||||||
rotate!(rotate_medium_by727_bytes, gen_random_bytes, 9158, 727);
|
rotate!(rotate_medium_by727_bytes, gen_random_bytes, 9158, 727);
|
||||||
rotate!(rotate_medium_by727_strings, gen_strings, 9158, 727);
|
rotate!(rotate_medium_by727_strings, gen_strings, 9158, 727);
|
||||||
rotate!(rotate_medium_half, gen_random, 9158, 9158/2);
|
rotate!(rotate_medium_half, gen_random, 9158, 9158 / 2);
|
||||||
rotate!(rotate_medium_half_plus_one, gen_random, 9158, 9158/2+1);
|
rotate!(rotate_medium_half_plus_one, gen_random, 9158, 9158 / 2 + 1);
|
||||||
|
|
||||||
// Intended to use more RAM than the machine has cache
|
// Intended to use more RAM than the machine has cache
|
||||||
rotate!(rotate_huge_by1, gen_random, 5*1024*1024, 1);
|
rotate!(rotate_huge_by1, gen_random, 5 * 1024 * 1024, 1);
|
||||||
rotate!(rotate_huge_by9199_u64, gen_random, 5*1024*1024, 9199);
|
rotate!(rotate_huge_by9199_u64, gen_random, 5 * 1024 * 1024, 9199);
|
||||||
rotate!(rotate_huge_by9199_bytes, gen_random_bytes, 5*1024*1024, 9199);
|
rotate!(rotate_huge_by9199_bytes, gen_random_bytes, 5 * 1024 * 1024, 9199);
|
||||||
rotate!(rotate_huge_by9199_strings, gen_strings, 5*1024*1024, 9199);
|
rotate!(rotate_huge_by9199_strings, gen_strings, 5 * 1024 * 1024, 9199);
|
||||||
rotate!(rotate_huge_by9199_big, gen_big_random, 5*1024*1024, 9199);
|
rotate!(rotate_huge_by9199_big, gen_big_random, 5 * 1024 * 1024, 9199);
|
||||||
rotate!(rotate_huge_by1234577_u64, gen_random, 5*1024*1024, 1234577);
|
rotate!(rotate_huge_by1234577_u64, gen_random, 5 * 1024 * 1024, 1234577);
|
||||||
rotate!(rotate_huge_by1234577_bytes, gen_random_bytes, 5*1024*1024, 1234577);
|
rotate!(rotate_huge_by1234577_bytes, gen_random_bytes, 5 * 1024 * 1024, 1234577);
|
||||||
rotate!(rotate_huge_by1234577_strings, gen_strings, 5*1024*1024, 1234577);
|
rotate!(rotate_huge_by1234577_strings, gen_strings, 5 * 1024 * 1024, 1234577);
|
||||||
rotate!(rotate_huge_by1234577_big, gen_big_random, 5*1024*1024, 1234577);
|
rotate!(rotate_huge_by1234577_big, gen_big_random, 5 * 1024 * 1024, 1234577);
|
||||||
rotate!(rotate_huge_half, gen_random, 5*1024*1024, 5*1024*1024/2);
|
rotate!(rotate_huge_half, gen_random, 5 * 1024 * 1024, 5 * 1024 * 1024 / 2);
|
||||||
rotate!(rotate_huge_half_plus_one, gen_random, 5*1024*1024, 5*1024*1024/2+1);
|
rotate!(rotate_huge_half_plus_one, gen_random, 5 * 1024 * 1024, 5 * 1024 * 1024 / 2 + 1);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use test::{Bencher, black_box};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn char_iterator(b: &mut Bencher) {
|
fn char_iterator(b: &mut Bencher) {
|
||||||
|
@ -12,7 +12,9 @@ fn char_iterator_for(b: &mut Bencher) {
|
||||||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for ch in s.chars() { black_box(ch); }
|
for ch in s.chars() {
|
||||||
|
black_box(ch);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +42,9 @@ fn char_iterator_rev_for(b: &mut Bencher) {
|
||||||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for ch in s.chars().rev() { black_box(ch); }
|
for ch in s.chars().rev() {
|
||||||
|
black_box(ch);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +83,9 @@ fn split_ascii(b: &mut Bencher) {
|
||||||
fn split_extern_fn(b: &mut Bencher) {
|
fn split_extern_fn(b: &mut Bencher) {
|
||||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||||
let len = s.split(' ').count();
|
let len = s.split(' ').count();
|
||||||
fn pred(c: char) -> bool { c == ' ' }
|
fn pred(c: char) -> bool {
|
||||||
|
c == ' '
|
||||||
|
}
|
||||||
|
|
||||||
b.iter(|| assert_eq!(s.split(pred).count(), len));
|
b.iter(|| assert_eq!(s.split(pred).count(), len));
|
||||||
}
|
}
|
||||||
|
@ -185,16 +191,19 @@ fn bench_contains_equal(b: &mut Bencher) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! make_test_inner {
|
macro_rules! make_test_inner {
|
||||||
($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => {
|
($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn $name(bencher: &mut Bencher) {
|
fn $name(bencher: &mut Bencher) {
|
||||||
let mut $s = $str;
|
let mut $s = $str;
|
||||||
black_box(&mut $s);
|
black_box(&mut $s);
|
||||||
bencher.iter(|| for _ in 0..$iters { black_box($code); });
|
bencher.iter(|| {
|
||||||
|
for _ in 0..$iters {
|
||||||
|
black_box($code);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! make_test {
|
macro_rules! make_test {
|
||||||
|
@ -261,15 +270,9 @@ make_test!(match_indices_a_str, s, s.match_indices("a").count());
|
||||||
|
|
||||||
make_test!(split_a_str, s, s.split("a").count());
|
make_test!(split_a_str, s, s.split("a").count());
|
||||||
|
|
||||||
make_test!(trim_ascii_char, s, {
|
make_test!(trim_ascii_char, s, { s.trim_matches(|c: char| c.is_ascii()) });
|
||||||
s.trim_matches(|c: char| c.is_ascii())
|
make_test!(trim_start_ascii_char, s, { s.trim_start_matches(|c: char| c.is_ascii()) });
|
||||||
});
|
make_test!(trim_end_ascii_char, s, { s.trim_end_matches(|c: char| c.is_ascii()) });
|
||||||
make_test!(trim_start_ascii_char, s, {
|
|
||||||
s.trim_start_matches(|c: char| c.is_ascii())
|
|
||||||
});
|
|
||||||
make_test!(trim_end_ascii_char, s, {
|
|
||||||
s.trim_end_matches(|c: char| c.is_ascii())
|
|
||||||
});
|
|
||||||
|
|
||||||
make_test!(find_underscore_char, s, s.find('_'));
|
make_test!(find_underscore_char, s, s.find('_'));
|
||||||
make_test!(rfind_underscore_char, s, s.rfind('_'));
|
make_test!(rfind_underscore_char, s, s.rfind('_'));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use test::{Bencher, black_box};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_new(b: &mut Bencher) {
|
fn bench_new(b: &mut Bencher) {
|
||||||
|
|
|
@ -30,8 +30,5 @@ fn main() {
|
||||||
|
|
||||||
assert!(BENCH_N % 2 == 0);
|
assert!(BENCH_N % 2 == 0);
|
||||||
let median = (durations[(l / 2) - 1] + durations[l / 2]) / 2;
|
let median = (durations[(l / 2) - 1] + durations[l / 2]) / 2;
|
||||||
println!(
|
println!("\ncustom-bench vec_deque_append {:?} ns/iter\n", median.as_nanos());
|
||||||
"\ncustom-bench vec_deque_append {:?} ns/iter\n",
|
|
||||||
median.as_nanos()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
pub mod map;
|
||||||
mod node;
|
mod node;
|
||||||
mod search;
|
mod search;
|
||||||
pub mod map;
|
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use super::node::{Handle, NodeRef, marker, ForceResult::*};
|
use super::node::{marker, ForceResult::*, Handle, NodeRef};
|
||||||
|
|
||||||
use SearchResult::*;
|
use SearchResult::*;
|
||||||
|
|
||||||
pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
|
pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
|
||||||
Found(Handle<NodeRef<BorrowType, K, V, FoundType>, marker::KV>),
|
Found(Handle<NodeRef<BorrowType, K, V, FoundType>, marker::KV>),
|
||||||
GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>)
|
GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
|
pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
|
||||||
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
||||||
key: &Q
|
key: &Q,
|
||||||
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
||||||
where Q: Ord, K: Borrow<Q> {
|
where
|
||||||
|
Q: Ord,
|
||||||
|
K: Borrow<Q>,
|
||||||
|
{
|
||||||
loop {
|
loop {
|
||||||
match search_node(node, key) {
|
match search_node(node, key) {
|
||||||
Found(handle) => return Found(handle),
|
Found(handle) => return Found(handle),
|
||||||
|
@ -25,38 +27,38 @@ pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
|
||||||
node = internal.descend();
|
node = internal.descend();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
|
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
|
||||||
node: NodeRef<BorrowType, K, V, Type>,
|
node: NodeRef<BorrowType, K, V, Type>,
|
||||||
key: &Q
|
key: &Q,
|
||||||
) -> SearchResult<BorrowType, K, V, Type, Type>
|
) -> SearchResult<BorrowType, K, V, Type, Type>
|
||||||
where Q: Ord, K: Borrow<Q> {
|
where
|
||||||
|
Q: Ord,
|
||||||
|
K: Borrow<Q>,
|
||||||
|
{
|
||||||
match search_linear(&node, key) {
|
match search_linear(&node, key) {
|
||||||
(idx, true) => Found(
|
(idx, true) => Found(Handle::new_kv(node, idx)),
|
||||||
Handle::new_kv(node, idx)
|
(idx, false) => SearchResult::GoDown(Handle::new_edge(node, idx)),
|
||||||
),
|
|
||||||
(idx, false) => SearchResult::GoDown(
|
|
||||||
Handle::new_edge(node, idx)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
|
pub fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
|
||||||
node: &NodeRef<BorrowType, K, V, Type>,
|
node: &NodeRef<BorrowType, K, V, Type>,
|
||||||
key: &Q
|
key: &Q,
|
||||||
) -> (usize, bool)
|
) -> (usize, bool)
|
||||||
where Q: Ord, K: Borrow<Q> {
|
where
|
||||||
|
Q: Ord,
|
||||||
|
K: Borrow<Q>,
|
||||||
|
{
|
||||||
for (i, k) in node.keys().iter().enumerate() {
|
for (i, k) in node.keys().iter().enumerate() {
|
||||||
match key.cmp(k.borrow()) {
|
match key.cmp(k.borrow()) {
|
||||||
Ordering::Greater => {},
|
Ordering::Greater => {}
|
||||||
Ordering::Equal => return (i, true),
|
Ordering::Equal => return (i, true),
|
||||||
Ordering::Less => return (i, false)
|
Ordering::Less => return (i, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(node.keys().len(), false)
|
(node.keys().len(), false)
|
||||||
|
|
|
@ -177,8 +177,7 @@ fn test_insert_prev() {
|
||||||
}
|
}
|
||||||
check_links(&m);
|
check_links(&m);
|
||||||
assert_eq!(m.len(), 3 + len * 2);
|
assert_eq!(m.len(), 3 + len * 2);
|
||||||
assert_eq!(m.into_iter().collect::<Vec<_>>(),
|
assert_eq!(m.into_iter().collect::<Vec<_>>(), [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
|
||||||
[-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -187,13 +186,13 @@ fn test_insert_prev() {
|
||||||
fn test_send() {
|
fn test_send() {
|
||||||
let n = list_from(&[1, 2, 3]);
|
let n = list_from(&[1, 2, 3]);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
check_links(&n);
|
check_links(&n);
|
||||||
let a: &[_] = &[&1, &2, &3];
|
let a: &[_] = &[&1, &2, &3];
|
||||||
assert_eq!(a, &*n.iter().collect::<Vec<_>>());
|
assert_eq!(a, &*n.iter().collect::<Vec<_>>());
|
||||||
})
|
})
|
||||||
.join()
|
.join()
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -66,11 +66,8 @@ fn test_swap_front_back_remove() {
|
||||||
let final_len = usable_cap / 2;
|
let final_len = usable_cap / 2;
|
||||||
|
|
||||||
for len in 0..final_len {
|
for len in 0..final_len {
|
||||||
let expected: VecDeque<_> = if back {
|
let expected: VecDeque<_> =
|
||||||
(0..len).collect()
|
if back { (0..len).collect() } else { (0..len).rev().collect() };
|
||||||
} else {
|
|
||||||
(0..len).rev().collect()
|
|
||||||
};
|
|
||||||
for tail_pos in 0..usable_cap {
|
for tail_pos in 0..usable_cap {
|
||||||
tester.tail = tail_pos;
|
tester.tail = tail_pos;
|
||||||
tester.head = tail_pos;
|
tester.head = tail_pos;
|
||||||
|
@ -111,7 +108,6 @@ fn test_insert() {
|
||||||
// this test isn't covering what it wants to
|
// this test isn't covering what it wants to
|
||||||
let cap = tester.capacity();
|
let cap = tester.capacity();
|
||||||
|
|
||||||
|
|
||||||
// len is the length *after* insertion
|
// len is the length *after* insertion
|
||||||
for len in 1..cap {
|
for len in 1..cap {
|
||||||
// 0, 1, 2, .., len - 1
|
// 0, 1, 2, .., len - 1
|
||||||
|
@ -198,9 +194,7 @@ fn test_drain() {
|
||||||
assert!(tester.head < tester.cap());
|
assert!(tester.head < tester.cap());
|
||||||
|
|
||||||
// We should see the correct values in the VecDeque
|
// We should see the correct values in the VecDeque
|
||||||
let expected: VecDeque<_> = (0..drain_start)
|
let expected: VecDeque<_> = (0..drain_start).chain(drain_end..len).collect();
|
||||||
.chain(drain_end..len)
|
|
||||||
.collect();
|
|
||||||
assert_eq!(expected, tester);
|
assert_eq!(expected, tester);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,24 +516,24 @@
|
||||||
|
|
||||||
#[unstable(feature = "fmt_internals", issue = "0")]
|
#[unstable(feature = "fmt_internals", issue = "0")]
|
||||||
pub use core::fmt::rt;
|
pub use core::fmt::rt;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
|
||||||
pub use core::fmt::{Formatter, Result, Write};
|
pub use core::fmt::Alignment;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use core::fmt::{Binary, Octal};
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use core::fmt::{Debug, Display};
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use core::fmt::{LowerHex, Pointer, UpperHex};
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use core::fmt::{LowerExp, UpperExp};
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::fmt::Error;
|
pub use core::fmt::Error;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::fmt::{write, ArgumentV1, Arguments};
|
pub use core::fmt::{write, ArgumentV1, Arguments};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::fmt::{Binary, Octal};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::fmt::{Debug, Display};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||||
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::fmt::{Alignment};
|
pub use core::fmt::{Formatter, Result, Write};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::fmt::{LowerExp, UpperExp};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::fmt::{LowerHex, Pointer, UpperHex};
|
||||||
|
|
||||||
use crate::string;
|
use crate::string;
|
||||||
|
|
||||||
|
@ -568,8 +568,6 @@ use crate::string;
|
||||||
pub fn format(args: Arguments<'_>) -> string::String {
|
pub fn format(args: Arguments<'_>) -> string::String {
|
||||||
let capacity = args.estimated_capacity();
|
let capacity = args.estimated_capacity();
|
||||||
let mut output = string::String::with_capacity(capacity);
|
let mut output = string::String::with_capacity(capacity);
|
||||||
output
|
output.write_fmt(args).expect("a formatting trait implementation returned an error");
|
||||||
.write_fmt(args)
|
|
||||||
.expect("a formatting trait implementation returned an error");
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
#![unstable(feature = "alloc_prelude", issue = "58935")]
|
#![unstable(feature = "alloc_prelude", issue = "58935")]
|
||||||
|
|
||||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
|
#[unstable(feature = "alloc_prelude", issue = "58935")]
|
||||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
|
pub use crate::borrow::ToOwned;
|
||||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
|
#[unstable(feature = "alloc_prelude", issue = "58935")]
|
||||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
|
pub use crate::boxed::Box;
|
||||||
|
#[unstable(feature = "alloc_prelude", issue = "58935")]
|
||||||
|
pub use crate::string::{String, ToString};
|
||||||
|
#[unstable(feature = "alloc_prelude", issue = "58935")]
|
||||||
|
pub use crate::vec::Vec;
|
||||||
|
|
|
@ -16,7 +16,9 @@ fn allocator_param() {
|
||||||
|
|
||||||
// A dumb allocator that consumes a fixed amount of fuel
|
// A dumb allocator that consumes a fixed amount of fuel
|
||||||
// before allocation attempts start failing.
|
// before allocation attempts start failing.
|
||||||
struct BoundedAlloc { fuel: usize }
|
struct BoundedAlloc {
|
||||||
|
fuel: usize,
|
||||||
|
}
|
||||||
unsafe impl Alloc for BoundedAlloc {
|
unsafe impl Alloc for BoundedAlloc {
|
||||||
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
|
||||||
let size = layout.size();
|
let size = layout.size();
|
||||||
|
@ -24,7 +26,10 @@ fn allocator_param() {
|
||||||
return Err(AllocErr);
|
return Err(AllocErr);
|
||||||
}
|
}
|
||||||
match Global.alloc(layout) {
|
match Global.alloc(layout) {
|
||||||
ok @ Ok(_) => { self.fuel -= size; ok }
|
ok @ Ok(_) => {
|
||||||
|
self.fuel -= size;
|
||||||
|
ok
|
||||||
|
}
|
||||||
err @ Err(_) => err,
|
err @ Err(_) => err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@
|
||||||
//! [`.chunks`]: ../../std/primitive.slice.html#method.chunks
|
//! [`.chunks`]: ../../std/primitive.slice.html#method.chunks
|
||||||
//! [`.windows`]: ../../std/primitive.slice.html#method.windows
|
//! [`.windows`]: ../../std/primitive.slice.html#method.windows
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
// Many of the usings in this module are only used in the test configuration.
|
// Many of the usings in this module are only used in the test configuration.
|
||||||
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
||||||
#![cfg_attr(test, allow(unused_imports, dead_code))]
|
#![cfg_attr(test, allow(unused_imports, dead_code))]
|
||||||
|
@ -91,32 +90,32 @@ use core::borrow::{Borrow, BorrowMut};
|
||||||
use core::cmp::Ordering::{self, Less};
|
use core::cmp::Ordering::{self, Less};
|
||||||
use core::mem::{self, size_of};
|
use core::mem::{self, size_of};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::{u8, u16, u32};
|
use core::{u16, u32, u8};
|
||||||
|
|
||||||
use crate::borrow::ToOwned;
|
use crate::borrow::ToOwned;
|
||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
use crate::vec::Vec;
|
use crate::vec::Vec;
|
||||||
|
|
||||||
|
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
||||||
|
pub use core::slice::SliceIndex;
|
||||||
|
#[stable(feature = "from_ref", since = "1.28.0")]
|
||||||
|
pub use core::slice::{from_mut, from_ref};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::slice::{Chunks, Windows};
|
pub use core::slice::{Chunks, Windows};
|
||||||
|
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||||
|
pub use core::slice::{ChunksExact, ChunksExactMut};
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use core::slice::{ChunksMut, Split, SplitMut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::slice::{Iter, IterMut};
|
pub use core::slice::{Iter, IterMut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||||
pub use core::slice::{SplitMut, ChunksMut, Split};
|
pub use core::slice::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
|
|
||||||
#[stable(feature = "slice_rsplit", since = "1.27.0")]
|
#[stable(feature = "slice_rsplit", since = "1.27.0")]
|
||||||
pub use core::slice::{RSplit, RSplitMut};
|
pub use core::slice::{RSplit, RSplitMut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
|
pub use core::slice::{RSplitN, RSplitNMut, SplitN, SplitNMut};
|
||||||
#[stable(feature = "from_ref", since = "1.28.0")]
|
|
||||||
pub use core::slice::{from_ref, from_mut};
|
|
||||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
|
||||||
pub use core::slice::SliceIndex;
|
|
||||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
|
||||||
pub use core::slice::{ChunksExact, ChunksExactMut};
|
|
||||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
|
||||||
pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Basic slice extension methods
|
// Basic slice extension methods
|
||||||
|
@ -138,9 +137,9 @@ pub use hack::to_vec;
|
||||||
// `test_permutations` test
|
// `test_permutations` test
|
||||||
mod hack {
|
mod hack {
|
||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
use crate::vec::Vec;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::string::ToString;
|
use crate::string::ToString;
|
||||||
|
use crate::vec::Vec;
|
||||||
|
|
||||||
pub fn into_vec<T>(b: Box<[T]>) -> Vec<T> {
|
pub fn into_vec<T>(b: Box<[T]>) -> Vec<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -153,7 +152,8 @@ mod hack {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_vec<T>(s: &[T]) -> Vec<T>
|
pub fn to_vec<T>(s: &[T]) -> Vec<T>
|
||||||
where T: Clone
|
where
|
||||||
|
T: Clone,
|
||||||
{
|
{
|
||||||
let mut vector = Vec::with_capacity(s.len());
|
let mut vector = Vec::with_capacity(s.len());
|
||||||
vector.extend_from_slice(s);
|
vector.extend_from_slice(s);
|
||||||
|
@ -193,7 +193,8 @@ impl<T> [T] {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort(&mut self)
|
pub fn sort(&mut self)
|
||||||
where T: Ord
|
where
|
||||||
|
T: Ord,
|
||||||
{
|
{
|
||||||
merge_sort(self, |a, b| a.lt(b));
|
merge_sort(self, |a, b| a.lt(b));
|
||||||
}
|
}
|
||||||
|
@ -246,7 +247,8 @@ impl<T> [T] {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_by<F>(&mut self, mut compare: F)
|
pub fn sort_by<F>(&mut self, mut compare: F)
|
||||||
where F: FnMut(&T, &T) -> Ordering
|
where
|
||||||
|
F: FnMut(&T, &T) -> Ordering,
|
||||||
{
|
{
|
||||||
merge_sort(self, |a, b| compare(a, b) == Less);
|
merge_sort(self, |a, b| compare(a, b) == Less);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +287,9 @@ impl<T> [T] {
|
||||||
#[stable(feature = "slice_sort_by_key", since = "1.7.0")]
|
#[stable(feature = "slice_sort_by_key", since = "1.7.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_by_key<K, F>(&mut self, mut f: F)
|
pub fn sort_by_key<K, F>(&mut self, mut f: F)
|
||||||
where F: FnMut(&T) -> K, K: Ord
|
where
|
||||||
|
F: FnMut(&T) -> K,
|
||||||
|
K: Ord,
|
||||||
{
|
{
|
||||||
merge_sort(self, |a, b| f(a).lt(&f(b)));
|
merge_sort(self, |a, b| f(a).lt(&f(b)));
|
||||||
}
|
}
|
||||||
|
@ -325,11 +329,13 @@ impl<T> [T] {
|
||||||
#[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
|
#[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_by_cached_key<K, F>(&mut self, f: F)
|
pub fn sort_by_cached_key<K, F>(&mut self, f: F)
|
||||||
where F: FnMut(&T) -> K, K: Ord
|
where
|
||||||
|
F: FnMut(&T) -> K,
|
||||||
|
K: Ord,
|
||||||
{
|
{
|
||||||
// Helper macro for indexing our vector by the smallest possible type, to reduce allocation.
|
// Helper macro for indexing our vector by the smallest possible type, to reduce allocation.
|
||||||
macro_rules! sort_by_key {
|
macro_rules! sort_by_key {
|
||||||
($t:ty, $slice:ident, $f:ident) => ({
|
($t:ty, $slice:ident, $f:ident) => {{
|
||||||
let mut indices: Vec<_> =
|
let mut indices: Vec<_> =
|
||||||
$slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect();
|
$slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect();
|
||||||
// The elements of `indices` are unique, as they are indexed, so any sort will be
|
// The elements of `indices` are unique, as they are indexed, so any sort will be
|
||||||
|
@ -344,19 +350,27 @@ impl<T> [T] {
|
||||||
indices[i].1 = index;
|
indices[i].1 = index;
|
||||||
$slice.swap(i, index as usize);
|
$slice.swap(i, index as usize);
|
||||||
}
|
}
|
||||||
})
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
let sz_u8 = mem::size_of::<(K, u8)>();
|
let sz_u8 = mem::size_of::<(K, u8)>();
|
||||||
let sz_u16 = mem::size_of::<(K, u16)>();
|
let sz_u16 = mem::size_of::<(K, u16)>();
|
||||||
let sz_u32 = mem::size_of::<(K, u32)>();
|
let sz_u32 = mem::size_of::<(K, u32)>();
|
||||||
let sz_usize = mem::size_of::<(K, usize)>();
|
let sz_usize = mem::size_of::<(K, usize)>();
|
||||||
|
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
if len < 2 { return }
|
if len < 2 {
|
||||||
if sz_u8 < sz_u16 && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) }
|
return;
|
||||||
if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) }
|
}
|
||||||
if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) }
|
if sz_u8 < sz_u16 && len <= (u8::MAX as usize) {
|
||||||
|
return sort_by_key!(u8, self, f);
|
||||||
|
}
|
||||||
|
if sz_u16 < sz_u32 && len <= (u16::MAX as usize) {
|
||||||
|
return sort_by_key!(u16, self, f);
|
||||||
|
}
|
||||||
|
if sz_u32 < sz_usize && len <= (u32::MAX as usize) {
|
||||||
|
return sort_by_key!(u32, self, f);
|
||||||
|
}
|
||||||
sort_by_key!(usize, self, f)
|
sort_by_key!(usize, self, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +387,8 @@ impl<T> [T] {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_vec(&self) -> Vec<T>
|
pub fn to_vec(&self) -> Vec<T>
|
||||||
where T: Clone
|
where
|
||||||
|
T: Clone,
|
||||||
{
|
{
|
||||||
// N.B., see the `hack` module in this file for more details.
|
// N.B., see the `hack` module in this file for more details.
|
||||||
hack::to_vec(self)
|
hack::to_vec(self)
|
||||||
|
@ -421,7 +436,10 @@ impl<T> [T] {
|
||||||
/// b"0123456789abcdef".repeat(usize::max_value());
|
/// b"0123456789abcdef".repeat(usize::max_value());
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "repeat_generic_slice", since = "1.40.0")]
|
#[stable(feature = "repeat_generic_slice", since = "1.40.0")]
|
||||||
pub fn repeat(&self, n: usize) -> Vec<T> where T: Copy {
|
pub fn repeat(&self, n: usize) -> Vec<T>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
@ -486,7 +504,8 @@ impl<T> [T] {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
|
pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
|
||||||
where Self: Concat<Item>
|
where
|
||||||
|
Self: Concat<Item>,
|
||||||
{
|
{
|
||||||
Concat::concat(self)
|
Concat::concat(self)
|
||||||
}
|
}
|
||||||
|
@ -503,7 +522,8 @@ impl<T> [T] {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
||||||
pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
||||||
where Self: Join<Separator>
|
where
|
||||||
|
Self: Join<Separator>,
|
||||||
{
|
{
|
||||||
Join::join(self, sep)
|
Join::join(self, sep)
|
||||||
}
|
}
|
||||||
|
@ -521,11 +541,11 @@ impl<T> [T] {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
|
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
|
||||||
pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
||||||
where Self: Join<Separator>
|
where
|
||||||
|
Self: Join<Separator>,
|
||||||
{
|
{
|
||||||
Join::join(self, sep)
|
Join::join(self, sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "slice_u8_alloc"]
|
#[lang = "slice_u8_alloc"]
|
||||||
|
@ -668,8 +688,8 @@ impl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] {
|
||||||
Some(first) => first,
|
Some(first) => first,
|
||||||
None => return vec![],
|
None => return vec![],
|
||||||
};
|
};
|
||||||
let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() +
|
let size =
|
||||||
sep.len() * (slice.len() - 1);
|
slice.iter().map(|v| v.borrow().len()).sum::<usize>() + sep.len() * (slice.len() - 1);
|
||||||
let mut result = Vec::with_capacity(size);
|
let mut result = Vec::with_capacity(size);
|
||||||
result.extend_from_slice(first.borrow());
|
result.extend_from_slice(first.borrow());
|
||||||
|
|
||||||
|
@ -734,7 +754,8 @@ impl<T: Clone> ToOwned for [T] {
|
||||||
///
|
///
|
||||||
/// This is the integral subroutine of insertion sort.
|
/// This is the integral subroutine of insertion sort.
|
||||||
fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
|
fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
|
||||||
where F: FnMut(&T, &T) -> bool
|
where
|
||||||
|
F: FnMut(&T, &T) -> bool,
|
||||||
{
|
{
|
||||||
if v.len() >= 2 && is_less(&v[1], &v[0]) {
|
if v.len() >= 2 && is_less(&v[1], &v[0]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -767,10 +788,7 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
|
||||||
// If `is_less` panics at any point during the process, `hole` will get dropped and
|
// If `is_less` panics at any point during the process, `hole` will get dropped and
|
||||||
// fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it
|
// fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it
|
||||||
// initially held exactly once.
|
// initially held exactly once.
|
||||||
let mut hole = InsertionHole {
|
let mut hole = InsertionHole { src: &mut *tmp, dest: &mut v[1] };
|
||||||
src: &mut *tmp,
|
|
||||||
dest: &mut v[1],
|
|
||||||
};
|
|
||||||
ptr::copy_nonoverlapping(&v[1], &mut v[0], 1);
|
ptr::copy_nonoverlapping(&v[1], &mut v[0], 1);
|
||||||
|
|
||||||
for i in 2..v.len() {
|
for i in 2..v.len() {
|
||||||
|
@ -792,7 +810,9 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
|
||||||
|
|
||||||
impl<T> Drop for InsertionHole<T> {
|
impl<T> Drop for InsertionHole<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { ptr::copy_nonoverlapping(self.src, self.dest, 1); }
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(self.src, self.dest, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -805,7 +825,8 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
|
||||||
/// The two slices must be non-empty and `mid` must be in bounds. Buffer `buf` must be long enough
|
/// The two slices must be non-empty and `mid` must be in bounds. Buffer `buf` must be long enough
|
||||||
/// to hold a copy of the shorter slice. Also, `T` must not be a zero-sized type.
|
/// to hold a copy of the shorter slice. Also, `T` must not be a zero-sized type.
|
||||||
unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
||||||
where F: FnMut(&T, &T) -> bool
|
where
|
||||||
|
F: FnMut(&T, &T) -> bool,
|
||||||
{
|
{
|
||||||
let len = v.len();
|
let len = v.len();
|
||||||
let v = v.as_mut_ptr();
|
let v = v.as_mut_ptr();
|
||||||
|
@ -834,11 +855,7 @@ unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
||||||
if mid <= len - mid {
|
if mid <= len - mid {
|
||||||
// The left run is shorter.
|
// The left run is shorter.
|
||||||
ptr::copy_nonoverlapping(v, buf, mid);
|
ptr::copy_nonoverlapping(v, buf, mid);
|
||||||
hole = MergeHole {
|
hole = MergeHole { start: buf, end: buf.add(mid), dest: v };
|
||||||
start: buf,
|
|
||||||
end: buf.add(mid),
|
|
||||||
dest: v,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initially, these pointers point to the beginnings of their arrays.
|
// Initially, these pointers point to the beginnings of their arrays.
|
||||||
let left = &mut hole.start;
|
let left = &mut hole.start;
|
||||||
|
@ -858,11 +875,7 @@ unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
||||||
} else {
|
} else {
|
||||||
// The right run is shorter.
|
// The right run is shorter.
|
||||||
ptr::copy_nonoverlapping(v_mid, buf, len - mid);
|
ptr::copy_nonoverlapping(v_mid, buf, len - mid);
|
||||||
hole = MergeHole {
|
hole = MergeHole { start: buf, end: buf.add(len - mid), dest: v_mid };
|
||||||
start: buf,
|
|
||||||
end: buf.add(len - mid),
|
|
||||||
dest: v_mid,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initially, these pointers point past the ends of their arrays.
|
// Initially, these pointers point past the ends of their arrays.
|
||||||
let left = &mut hole.dest;
|
let left = &mut hole.dest;
|
||||||
|
@ -905,7 +918,9 @@ unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// `T` is not a zero-sized type, so it's okay to divide by its size.
|
// `T` is not a zero-sized type, so it's okay to divide by its size.
|
||||||
let len = (self.end as usize - self.start as usize) / mem::size_of::<T>();
|
let len = (self.end as usize - self.start as usize) / mem::size_of::<T>();
|
||||||
unsafe { ptr::copy_nonoverlapping(self.start, self.dest, len); }
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(self.start, self.dest, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -923,7 +938,8 @@ unsafe fn merge<T, F>(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F)
|
||||||
///
|
///
|
||||||
/// The invariants ensure that the total running time is `O(n log n)` worst-case.
|
/// The invariants ensure that the total running time is `O(n log n)` worst-case.
|
||||||
fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
where F: FnMut(&T, &T) -> bool
|
where
|
||||||
|
F: FnMut(&T, &T) -> bool,
|
||||||
{
|
{
|
||||||
// Slices of up to this length get sorted using insertion sort.
|
// Slices of up to this length get sorted using insertion sort.
|
||||||
const MAX_INSERTION: usize = 20;
|
const MAX_INSERTION: usize = 20;
|
||||||
|
@ -940,7 +956,7 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
// Short arrays get sorted in-place via insertion sort to avoid allocations.
|
// Short arrays get sorted in-place via insertion sort to avoid allocations.
|
||||||
if len <= MAX_INSERTION {
|
if len <= MAX_INSERTION {
|
||||||
if len >= 2 {
|
if len >= 2 {
|
||||||
for i in (0..len-1).rev() {
|
for i in (0..len - 1).rev() {
|
||||||
insert_head(&mut v[i..], &mut is_less);
|
insert_head(&mut v[i..], &mut is_less);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -966,14 +982,13 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
start -= 1;
|
start -= 1;
|
||||||
unsafe {
|
unsafe {
|
||||||
if is_less(v.get_unchecked(start + 1), v.get_unchecked(start)) {
|
if is_less(v.get_unchecked(start + 1), v.get_unchecked(start)) {
|
||||||
while start > 0 && is_less(v.get_unchecked(start),
|
while start > 0 && is_less(v.get_unchecked(start), v.get_unchecked(start - 1)) {
|
||||||
v.get_unchecked(start - 1)) {
|
|
||||||
start -= 1;
|
start -= 1;
|
||||||
}
|
}
|
||||||
v[start..end].reverse();
|
v[start..end].reverse();
|
||||||
} else {
|
} else {
|
||||||
while start > 0 && !is_less(v.get_unchecked(start),
|
while start > 0 && !is_less(v.get_unchecked(start), v.get_unchecked(start - 1))
|
||||||
v.get_unchecked(start - 1)) {
|
{
|
||||||
start -= 1;
|
start -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,10 +1003,7 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push this run onto the stack.
|
// Push this run onto the stack.
|
||||||
runs.push(Run {
|
runs.push(Run { start, len: end - start });
|
||||||
start,
|
|
||||||
len: end - start,
|
|
||||||
});
|
|
||||||
end = start;
|
end = start;
|
||||||
|
|
||||||
// Merge some pairs of adjacent runs to satisfy the invariants.
|
// Merge some pairs of adjacent runs to satisfy the invariants.
|
||||||
|
@ -999,13 +1011,14 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
let left = runs[r + 1];
|
let left = runs[r + 1];
|
||||||
let right = runs[r];
|
let right = runs[r];
|
||||||
unsafe {
|
unsafe {
|
||||||
merge(&mut v[left.start .. right.start + right.len], left.len, buf.as_mut_ptr(),
|
merge(
|
||||||
&mut is_less);
|
&mut v[left.start..right.start + right.len],
|
||||||
|
left.len,
|
||||||
|
buf.as_mut_ptr(),
|
||||||
|
&mut is_less,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
runs[r] = Run {
|
runs[r] = Run { start: left.start, len: left.len + right.len };
|
||||||
start: left.start,
|
|
||||||
len: left.len + right.len,
|
|
||||||
};
|
|
||||||
runs.remove(r + 1);
|
runs.remove(r + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1030,15 +1043,13 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
|
||||||
#[inline]
|
#[inline]
|
||||||
fn collapse(runs: &[Run]) -> Option<usize> {
|
fn collapse(runs: &[Run]) -> Option<usize> {
|
||||||
let n = runs.len();
|
let n = runs.len();
|
||||||
if n >= 2 && (runs[n - 1].start == 0 ||
|
if n >= 2
|
||||||
runs[n - 2].len <= runs[n - 1].len ||
|
&& (runs[n - 1].start == 0
|
||||||
(n >= 3 && runs[n - 3].len <= runs[n - 2].len + runs[n - 1].len) ||
|
|| runs[n - 2].len <= runs[n - 1].len
|
||||||
(n >= 4 && runs[n - 4].len <= runs[n - 3].len + runs[n - 2].len)) {
|
|| (n >= 3 && runs[n - 3].len <= runs[n - 2].len + runs[n - 1].len)
|
||||||
if n >= 3 && runs[n - 3].len < runs[n - 1].len {
|
|| (n >= 4 && runs[n - 4].len <= runs[n - 3].len + runs[n - 2].len))
|
||||||
Some(n - 3)
|
{
|
||||||
} else {
|
if n >= 3 && runs[n - 3].len < runs[n - 1].len { Some(n - 3) } else { Some(n - 2) }
|
||||||
Some(n - 2)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//! Test for `boxed` mod.
|
//! Test for `boxed` mod.
|
||||||
|
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::convert::TryInto;
|
|
||||||
use core::ops::Deref;
|
|
||||||
use core::result::Result::{Err, Ok};
|
|
||||||
use core::clone::Clone;
|
use core::clone::Clone;
|
||||||
|
use core::convert::TryInto;
|
||||||
use core::f64;
|
use core::f64;
|
||||||
use core::i64;
|
use core::i64;
|
||||||
|
use core::ops::Deref;
|
||||||
|
use core::result::Result::{Err, Ok};
|
||||||
|
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::{Arc, Weak};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
use std::iter::TrustedLen;
|
use std::iter::TrustedLen;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uninhabited() {
|
fn uninhabited() {
|
||||||
|
@ -12,7 +12,7 @@ fn uninhabited() {
|
||||||
a = a.clone();
|
a = a.clone();
|
||||||
assert!(a.upgrade().is_none());
|
assert!(a.upgrade().is_none());
|
||||||
|
|
||||||
let mut a: Weak<dyn Any> = a; // Unsizing
|
let mut a: Weak<dyn Any> = a; // Unsizing
|
||||||
a = a.clone();
|
a = a.clone();
|
||||||
assert!(a.upgrade().is_none());
|
assert!(a.upgrade().is_none());
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ fn uninhabited() {
|
||||||
#[test]
|
#[test]
|
||||||
fn slice() {
|
fn slice() {
|
||||||
let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
|
let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
|
||||||
let a: Arc<[u32]> = a; // Unsizing
|
let a: Arc<[u32]> = a; // Unsizing
|
||||||
let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion
|
let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
|
||||||
// Exercise is_dangling() with a DST
|
// Exercise is_dangling() with a DST
|
||||||
|
@ -33,7 +33,7 @@ fn slice() {
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_object() {
|
fn trait_object() {
|
||||||
let a: Arc<u32> = Arc::new(4);
|
let a: Arc<u32> = Arc::new(4);
|
||||||
let a: Arc<dyn Any> = a; // Unsizing
|
let a: Arc<dyn Any> = a; // Unsizing
|
||||||
|
|
||||||
// Exercise is_dangling() with a DST
|
// Exercise is_dangling() with a DST
|
||||||
let mut a = Arc::downgrade(&a);
|
let mut a = Arc::downgrade(&a);
|
||||||
|
@ -43,7 +43,7 @@ fn trait_object() {
|
||||||
let mut b = Weak::<u32>::new();
|
let mut b = Weak::<u32>::new();
|
||||||
b = b.clone();
|
b = b.clone();
|
||||||
assert!(b.upgrade().is_none());
|
assert!(b.upgrade().is_none());
|
||||||
let mut b: Weak<dyn Any> = b; // Unsizing
|
let mut b: Weak<dyn Any> = b; // Unsizing
|
||||||
b = b.clone();
|
b = b.clone();
|
||||||
assert!(b.upgrade().is_none());
|
assert!(b.upgrade().is_none());
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ fn float_nan_ne() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn partial_eq() {
|
fn partial_eq() {
|
||||||
struct TestPEq (RefCell<usize>);
|
struct TestPEq(RefCell<usize>);
|
||||||
impl PartialEq for TestPEq {
|
impl PartialEq for TestPEq {
|
||||||
fn eq(&self, other: &TestPEq) -> bool {
|
fn eq(&self, other: &TestPEq) -> bool {
|
||||||
*self.0.borrow_mut() += 1;
|
*self.0.borrow_mut() += 1;
|
||||||
|
@ -74,7 +74,7 @@ fn partial_eq() {
|
||||||
#[test]
|
#[test]
|
||||||
fn eq() {
|
fn eq() {
|
||||||
#[derive(Eq)]
|
#[derive(Eq)]
|
||||||
struct TestEq (RefCell<usize>);
|
struct TestEq(RefCell<usize>);
|
||||||
impl PartialEq for TestEq {
|
impl PartialEq for TestEq {
|
||||||
fn eq(&self, other: &TestEq) -> bool {
|
fn eq(&self, other: &TestEq) -> bool {
|
||||||
*self.0.borrow_mut() += 1;
|
*self.0.borrow_mut() += 1;
|
||||||
|
@ -160,13 +160,10 @@ fn shared_from_iter_trustedlen_normal() {
|
||||||
fn shared_from_iter_trustedlen_panic() {
|
fn shared_from_iter_trustedlen_panic() {
|
||||||
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
||||||
let iter = (0..SHARED_ITER_MAX)
|
let iter = (0..SHARED_ITER_MAX).map(|val| match val {
|
||||||
.map(|val| {
|
98 => panic!("I've almost got 99 problems."),
|
||||||
match val {
|
_ => Box::new(val),
|
||||||
98 => panic!("I've almost got 99 problems."),
|
});
|
||||||
_ => Box::new(val),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assert_trusted_len(&iter);
|
assert_trusted_len(&iter);
|
||||||
let _ = iter.collect::<Rc<[_]>>();
|
let _ = iter.collect::<Rc<[_]>>();
|
||||||
|
|
||||||
|
@ -193,16 +190,8 @@ fn shared_from_iter_trustedlen_no_fuse() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vec = vec![
|
let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))];
|
||||||
Some(Box::new(42)),
|
|
||||||
Some(Box::new(24)),
|
|
||||||
None,
|
|
||||||
Some(Box::new(12)),
|
|
||||||
];
|
|
||||||
let iter = Iter(vec.into_iter());
|
let iter = Iter(vec.into_iter());
|
||||||
assert_trusted_len(&iter);
|
assert_trusted_len(&iter);
|
||||||
assert_eq!(
|
assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>());
|
||||||
&[Box::new(42), Box::new(24)],
|
|
||||||
&*iter.collect::<Rc<[_]>>()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ fn assert_covariance() {
|
||||||
// Destructors must be called exactly once per element.
|
// Destructors must be called exactly once per element.
|
||||||
// FIXME: re-enable emscripten once it can unwind again
|
// FIXME: re-enable emscripten once it can unwind again
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
fn panic_safe() {
|
fn panic_safe() {
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::panic::{self, AssertUnwindSafe};
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
|
@ -376,7 +376,10 @@ fn panic_safe() {
|
||||||
}
|
}
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
const DATASZ: usize = 32;
|
const DATASZ: usize = 32;
|
||||||
|
#[cfg(not(miri))] // Miri is too slow
|
||||||
const NTEST: usize = 10;
|
const NTEST: usize = 10;
|
||||||
|
#[cfg(miri)]
|
||||||
|
const NTEST: usize = 1;
|
||||||
|
|
||||||
// don't use 0 in the data -- we want to catch the zeroed-out case.
|
// don't use 0 in the data -- we want to catch the zeroed-out case.
|
||||||
let data = (1..=DATASZ).collect::<Vec<_>>();
|
let data = (1..=DATASZ).collect::<Vec<_>>();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::ptr::NonNull;
|
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unitialized_zero_size_box() {
|
fn unitialized_zero_size_box() {
|
||||||
|
|
|
@ -11,12 +11,7 @@ struct DeterministicRng {
|
||||||
|
|
||||||
impl DeterministicRng {
|
impl DeterministicRng {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
DeterministicRng {
|
DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
|
||||||
x: 0x193a6754,
|
|
||||||
y: 0xa8a7d469,
|
|
||||||
z: 0x97830e05,
|
|
||||||
w: 0x113ba7bb,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next(&mut self) -> u32 {
|
fn next(&mut self) -> u32 {
|
||||||
|
|
|
@ -102,7 +102,6 @@ fn test_split_off() {
|
||||||
assert_eq!(m.back(), Some(&1));
|
assert_eq!(m.back(), Some(&1));
|
||||||
assert_eq!(m.front(), Some(&1));
|
assert_eq!(m.front(), Some(&1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -305,8 +304,7 @@ fn test_show() {
|
||||||
assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
||||||
|
|
||||||
let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
|
let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
|
||||||
assert_eq!(format!("{:?}", list),
|
assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
|
||||||
"[\"just\", \"one\", \"test\", \"more\"]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -446,19 +444,14 @@ fn drain_filter_true() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn drain_filter_complex() {
|
fn drain_filter_complex() {
|
||||||
|
{
|
||||||
{ // [+xxx++++++xxxxx++++x+x++]
|
// [+xxx++++++xxxxx++++x+x++]
|
||||||
let mut list = vec![
|
let mut list = vec![
|
||||||
1,
|
1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37,
|
||||||
2, 4, 6,
|
39,
|
||||||
7, 9, 11, 13, 15, 17,
|
]
|
||||||
18, 20, 22, 24, 26,
|
.into_iter()
|
||||||
27, 29, 31, 33,
|
.collect::<LinkedList<_>>();
|
||||||
34,
|
|
||||||
35,
|
|
||||||
36,
|
|
||||||
37, 39
|
|
||||||
].into_iter().collect::<LinkedList<_>>();
|
|
||||||
|
|
||||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||||
assert_eq!(removed.len(), 10);
|
assert_eq!(removed.len(), 10);
|
||||||
|
@ -471,17 +464,13 @@ fn drain_filter_complex() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // [xxx++++++xxxxx++++x+x++]
|
{
|
||||||
|
// [xxx++++++xxxxx++++x+x++]
|
||||||
let mut list = vec![
|
let mut list = vec![
|
||||||
2, 4, 6,
|
2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39,
|
||||||
7, 9, 11, 13, 15, 17,
|
]
|
||||||
18, 20, 22, 24, 26,
|
.into_iter()
|
||||||
27, 29, 31, 33,
|
.collect::<LinkedList<_>>();
|
||||||
34,
|
|
||||||
35,
|
|
||||||
36,
|
|
||||||
37, 39
|
|
||||||
].into_iter().collect::<LinkedList<_>>();
|
|
||||||
|
|
||||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||||
assert_eq!(removed.len(), 10);
|
assert_eq!(removed.len(), 10);
|
||||||
|
@ -494,16 +483,12 @@ fn drain_filter_complex() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // [xxx++++++xxxxx++++x+x]
|
{
|
||||||
let mut list = vec![
|
// [xxx++++++xxxxx++++x+x]
|
||||||
2, 4, 6,
|
let mut list =
|
||||||
7, 9, 11, 13, 15, 17,
|
vec![2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]
|
||||||
18, 20, 22, 24, 26,
|
.into_iter()
|
||||||
27, 29, 31, 33,
|
.collect::<LinkedList<_>>();
|
||||||
34,
|
|
||||||
35,
|
|
||||||
36
|
|
||||||
].into_iter().collect::<LinkedList<_>>();
|
|
||||||
|
|
||||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||||
assert_eq!(removed.len(), 10);
|
assert_eq!(removed.len(), 10);
|
||||||
|
@ -516,11 +501,11 @@ fn drain_filter_complex() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // [xxxxxxxxxx+++++++++++]
|
{
|
||||||
let mut list = vec![
|
// [xxxxxxxxxx+++++++++++]
|
||||||
2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
|
let mut list = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
|
||||||
1, 3, 5, 7, 9, 11, 13, 15, 17, 19
|
.into_iter()
|
||||||
].into_iter().collect::<LinkedList<_>>();
|
.collect::<LinkedList<_>>();
|
||||||
|
|
||||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||||
assert_eq!(removed.len(), 10);
|
assert_eq!(removed.len(), 10);
|
||||||
|
@ -530,11 +515,11 @@ fn drain_filter_complex() {
|
||||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // [+++++++++++xxxxxxxxxx]
|
{
|
||||||
let mut list = vec![
|
// [+++++++++++xxxxxxxxxx]
|
||||||
1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
|
let mut list = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
|
||||||
2, 4, 6, 8, 10, 12, 14, 16, 18, 20
|
.into_iter()
|
||||||
].into_iter().collect::<LinkedList<_>>();
|
.collect::<LinkedList<_>>();
|
||||||
|
|
||||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||||
assert_eq!(removed.len(), 10);
|
assert_eq!(removed.len(), 10);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::rc::{Rc, Weak};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
use std::mem;
|
|
||||||
use std::iter::TrustedLen;
|
use std::iter::TrustedLen;
|
||||||
|
use std::mem;
|
||||||
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uninhabited() {
|
fn uninhabited() {
|
||||||
|
@ -12,7 +12,7 @@ fn uninhabited() {
|
||||||
a = a.clone();
|
a = a.clone();
|
||||||
assert!(a.upgrade().is_none());
|
assert!(a.upgrade().is_none());
|
||||||
|
|
||||||
let mut a: Weak<dyn Any> = a; // Unsizing
|
let mut a: Weak<dyn Any> = a; // Unsizing
|
||||||
a = a.clone();
|
a = a.clone();
|
||||||
assert!(a.upgrade().is_none());
|
assert!(a.upgrade().is_none());
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ fn uninhabited() {
|
||||||
#[test]
|
#[test]
|
||||||
fn slice() {
|
fn slice() {
|
||||||
let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
|
let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
|
||||||
let a: Rc<[u32]> = a; // Unsizing
|
let a: Rc<[u32]> = a; // Unsizing
|
||||||
let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
|
let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
|
||||||
// Exercise is_dangling() with a DST
|
// Exercise is_dangling() with a DST
|
||||||
|
@ -33,7 +33,7 @@ fn slice() {
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_object() {
|
fn trait_object() {
|
||||||
let a: Rc<u32> = Rc::new(4);
|
let a: Rc<u32> = Rc::new(4);
|
||||||
let a: Rc<dyn Any> = a; // Unsizing
|
let a: Rc<dyn Any> = a; // Unsizing
|
||||||
|
|
||||||
// Exercise is_dangling() with a DST
|
// Exercise is_dangling() with a DST
|
||||||
let mut a = Rc::downgrade(&a);
|
let mut a = Rc::downgrade(&a);
|
||||||
|
@ -43,7 +43,7 @@ fn trait_object() {
|
||||||
let mut b = Weak::<u32>::new();
|
let mut b = Weak::<u32>::new();
|
||||||
b = b.clone();
|
b = b.clone();
|
||||||
assert!(b.upgrade().is_none());
|
assert!(b.upgrade().is_none());
|
||||||
let mut b: Weak<dyn Any> = b; // Unsizing
|
let mut b: Weak<dyn Any> = b; // Unsizing
|
||||||
b = b.clone();
|
b = b.clone();
|
||||||
assert!(b.upgrade().is_none());
|
assert!(b.upgrade().is_none());
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ fn float_nan_ne() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn partial_eq() {
|
fn partial_eq() {
|
||||||
struct TestPEq (RefCell<usize>);
|
struct TestPEq(RefCell<usize>);
|
||||||
impl PartialEq for TestPEq {
|
impl PartialEq for TestPEq {
|
||||||
fn eq(&self, other: &TestPEq) -> bool {
|
fn eq(&self, other: &TestPEq) -> bool {
|
||||||
*self.0.borrow_mut() += 1;
|
*self.0.borrow_mut() += 1;
|
||||||
|
@ -74,7 +74,7 @@ fn partial_eq() {
|
||||||
#[test]
|
#[test]
|
||||||
fn eq() {
|
fn eq() {
|
||||||
#[derive(Eq)]
|
#[derive(Eq)]
|
||||||
struct TestEq (RefCell<usize>);
|
struct TestEq(RefCell<usize>);
|
||||||
impl PartialEq for TestEq {
|
impl PartialEq for TestEq {
|
||||||
fn eq(&self, other: &TestEq) -> bool {
|
fn eq(&self, other: &TestEq) -> bool {
|
||||||
*self.0.borrow_mut() += 1;
|
*self.0.borrow_mut() += 1;
|
||||||
|
@ -156,13 +156,10 @@ fn shared_from_iter_trustedlen_normal() {
|
||||||
fn shared_from_iter_trustedlen_panic() {
|
fn shared_from_iter_trustedlen_panic() {
|
||||||
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
||||||
let iter = (0..SHARED_ITER_MAX)
|
let iter = (0..SHARED_ITER_MAX).map(|val| match val {
|
||||||
.map(|val| {
|
98 => panic!("I've almost got 99 problems."),
|
||||||
match val {
|
_ => Box::new(val),
|
||||||
98 => panic!("I've almost got 99 problems."),
|
});
|
||||||
_ => Box::new(val),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assert_trusted_len(&iter);
|
assert_trusted_len(&iter);
|
||||||
let _ = iter.collect::<Rc<[_]>>();
|
let _ = iter.collect::<Rc<[_]>>();
|
||||||
|
|
||||||
|
@ -189,16 +186,8 @@ fn shared_from_iter_trustedlen_no_fuse() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vec = vec![
|
let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))];
|
||||||
Some(Box::new(42)),
|
|
||||||
Some(Box::new(24)),
|
|
||||||
None,
|
|
||||||
Some(Box::new(12)),
|
|
||||||
];
|
|
||||||
let iter = Iter(vec.into_iter());
|
let iter = Iter(vec.into_iter());
|
||||||
assert_trusted_len(&iter);
|
assert_trusted_len(&iter);
|
||||||
assert_eq!(
|
assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>());
|
||||||
&[Box::new(42), Box::new(24)],
|
|
||||||
&*iter.collect::<Rc<[_]>>()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::mem;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{Ordering::Relaxed, AtomicUsize};
|
use std::sync::atomic::{Ordering::Relaxed, AtomicUsize};
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use rand::{Rng, RngCore, thread_rng};
|
use rand::{Rng, RngCore, thread_rng};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
@ -1406,11 +1405,9 @@ fn test_box_slice_clone() {
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
|
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
|
||||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||||
#[cfg(not(miri))] // Miri does not support threads
|
|
||||||
fn test_box_slice_clone_panics() {
|
fn test_box_slice_clone_panics() {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::thread::spawn;
|
|
||||||
|
|
||||||
struct Canary {
|
struct Canary {
|
||||||
count: Arc<AtomicUsize>,
|
count: Arc<AtomicUsize>,
|
||||||
|
@ -1446,7 +1443,7 @@ fn test_box_slice_clone_panics() {
|
||||||
panics: true,
|
panics: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
spawn(move || {
|
std::panic::catch_unwind(move || {
|
||||||
// When xs is dropped, +5.
|
// When xs is dropped, +5.
|
||||||
let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
|
let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
|
||||||
.into_boxed_slice();
|
.into_boxed_slice();
|
||||||
|
@ -1454,7 +1451,6 @@ fn test_box_slice_clone_panics() {
|
||||||
// When panic is cloned, +3.
|
// When panic is cloned, +3.
|
||||||
xs.clone();
|
xs.clone();
|
||||||
})
|
})
|
||||||
.join()
|
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// Total = 8
|
// Total = 8
|
||||||
|
@ -1566,7 +1562,7 @@ macro_rules! test {
|
||||||
}
|
}
|
||||||
|
|
||||||
let v = $input.to_owned();
|
let v = $input.to_owned();
|
||||||
let _ = thread::spawn(move || {
|
let _ = std::panic::catch_unwind(move || {
|
||||||
let mut v = v;
|
let mut v = v;
|
||||||
let mut panic_countdown = panic_countdown;
|
let mut panic_countdown = panic_countdown;
|
||||||
v.$func(|a, b| {
|
v.$func(|a, b| {
|
||||||
|
@ -1577,7 +1573,7 @@ macro_rules! test {
|
||||||
panic_countdown -= 1;
|
panic_countdown -= 1;
|
||||||
a.cmp(b)
|
a.cmp(b)
|
||||||
})
|
})
|
||||||
}).join();
|
});
|
||||||
|
|
||||||
// Check that the number of things dropped is exactly
|
// Check that the number of things dropped is exactly
|
||||||
// what we expect (i.e., the contents of `v`).
|
// what we expect (i.e., the contents of `v`).
|
||||||
|
@ -1598,7 +1594,6 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
|
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
|
||||||
#[cfg(not(miri))] // Miri does not support threads
|
|
||||||
fn panic_safe() {
|
fn panic_safe() {
|
||||||
let prev = panic::take_hook();
|
let prev = panic::take_hook();
|
||||||
panic::set_hook(Box::new(move |info| {
|
panic::set_hook(Box::new(move |info| {
|
||||||
|
@ -1609,8 +1604,18 @@ fn panic_safe() {
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
for len in (1..20).chain(70..MAX_LEN) {
|
#[cfg(not(miri))] // Miri is too slow
|
||||||
for &modulus in &[5, 20, 50] {
|
let lens = (1..20).chain(70..MAX_LEN);
|
||||||
|
#[cfg(not(miri))] // Miri is too slow
|
||||||
|
let moduli = &[5, 20, 50];
|
||||||
|
|
||||||
|
#[cfg(miri)]
|
||||||
|
let lens = (1..13);
|
||||||
|
#[cfg(miri)]
|
||||||
|
let moduli = &[10];
|
||||||
|
|
||||||
|
for len in lens {
|
||||||
|
for &modulus in moduli {
|
||||||
for &has_runs in &[false, true] {
|
for &has_runs in &[false, true] {
|
||||||
let mut input = (0..len)
|
let mut input = (0..len)
|
||||||
.map(|id| {
|
.map(|id| {
|
||||||
|
@ -1643,6 +1648,9 @@ fn panic_safe() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default panic hook again.
|
||||||
|
drop(panic::take_hook());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -944,10 +944,9 @@ fn drain_filter_complex() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Miri does not support catching panics
|
|
||||||
// FIXME: re-enable emscripten once it can unwind again
|
// FIXME: re-enable emscripten once it can unwind again
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(any(miri, target_os = "emscripten")))]
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
fn drain_filter_consumed_panic() {
|
fn drain_filter_consumed_panic() {
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -999,7 +998,7 @@ fn drain_filter_consumed_panic() {
|
||||||
|
|
||||||
// FIXME: Re-enable emscripten once it can catch panics
|
// FIXME: Re-enable emscripten once it can catch panics
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
fn drain_filter_unconsumed_panic() {
|
fn drain_filter_unconsumed_panic() {
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::collections::{VecDeque, vec_deque::Drain};
|
|
||||||
use std::collections::TryReserveError::*;
|
use std::collections::TryReserveError::*;
|
||||||
|
use std::collections::{vec_deque::Drain, VecDeque};
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::{usize, isize};
|
use std::{isize, usize};
|
||||||
|
|
||||||
use crate::hash;
|
use crate::hash;
|
||||||
|
|
||||||
|
@ -148,34 +148,20 @@ fn test_param_taggy() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_param_taggypar() {
|
fn test_param_taggypar() {
|
||||||
test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
|
test_parameterized::<Taggypar<i32>>(
|
||||||
Twopar::<i32>(1, 2),
|
Onepar::<i32>(1),
|
||||||
Threepar::<i32>(1, 2, 3),
|
Twopar::<i32>(1, 2),
|
||||||
Twopar::<i32>(17, 42));
|
Threepar::<i32>(1, 2, 3),
|
||||||
|
Twopar::<i32>(17, 42),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_param_reccy() {
|
fn test_param_reccy() {
|
||||||
let reccy1 = RecCy {
|
let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
|
||||||
x: 1,
|
let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
|
||||||
y: 2,
|
let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
|
||||||
t: One(1),
|
let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
|
||||||
};
|
|
||||||
let reccy2 = RecCy {
|
|
||||||
x: 345,
|
|
||||||
y: 2,
|
|
||||||
t: Two(1, 2),
|
|
||||||
};
|
|
||||||
let reccy3 = RecCy {
|
|
||||||
x: 1,
|
|
||||||
y: 777,
|
|
||||||
t: Three(1, 2, 3),
|
|
||||||
};
|
|
||||||
let reccy4 = RecCy {
|
|
||||||
x: 19,
|
|
||||||
y: 252,
|
|
||||||
t: Two(17, 42),
|
|
||||||
};
|
|
||||||
test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
|
test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,8 +306,7 @@ fn test_mut_rev_iter_wrap() {
|
||||||
assert_eq!(d.pop_front(), Some(1));
|
assert_eq!(d.pop_front(), Some(1));
|
||||||
d.push_back(4);
|
d.push_back(4);
|
||||||
|
|
||||||
assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<_>>(),
|
assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<_>>(), vec![4, 3, 2]);
|
||||||
vec![4, 3, 2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -372,7 +357,6 @@ fn test_mut_rev_iter() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_into_iter() {
|
fn test_into_iter() {
|
||||||
|
|
||||||
// Empty iter
|
// Empty iter
|
||||||
{
|
{
|
||||||
let d: VecDeque<i32> = VecDeque::new();
|
let d: VecDeque<i32> = VecDeque::new();
|
||||||
|
@ -431,7 +415,6 @@ fn test_into_iter() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drain() {
|
fn test_drain() {
|
||||||
|
|
||||||
// Empty iter
|
// Empty iter
|
||||||
{
|
{
|
||||||
let mut d: VecDeque<i32> = VecDeque::new();
|
let mut d: VecDeque<i32> = VecDeque::new();
|
||||||
|
@ -650,12 +633,8 @@ fn test_show() {
|
||||||
let ringbuf: VecDeque<_> = (0..10).collect();
|
let ringbuf: VecDeque<_> = (0..10).collect();
|
||||||
assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
||||||
|
|
||||||
let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"]
|
let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
|
||||||
.iter()
|
assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]");
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
assert_eq!(format!("{:?}", ringbuf),
|
|
||||||
"[\"just\", \"one\", \"test\", \"more\"]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -955,7 +934,6 @@ fn test_append_permutations() {
|
||||||
// doesn't pop more values than are pushed
|
// doesn't pop more values than are pushed
|
||||||
for src_pop_back in 0..(src_push_back + src_push_front) {
|
for src_pop_back in 0..(src_push_back + src_push_front) {
|
||||||
for src_pop_front in 0..(src_push_back + src_push_front - src_pop_back) {
|
for src_pop_front in 0..(src_push_back + src_push_front - src_pop_back) {
|
||||||
|
|
||||||
let src = construct_vec_deque(
|
let src = construct_vec_deque(
|
||||||
src_push_back,
|
src_push_back,
|
||||||
src_pop_back,
|
src_pop_back,
|
||||||
|
@ -966,8 +944,8 @@ fn test_append_permutations() {
|
||||||
for dst_push_back in 0..MAX {
|
for dst_push_back in 0..MAX {
|
||||||
for dst_push_front in 0..MAX {
|
for dst_push_front in 0..MAX {
|
||||||
for dst_pop_back in 0..(dst_push_back + dst_push_front) {
|
for dst_pop_back in 0..(dst_push_back + dst_push_front) {
|
||||||
for dst_pop_front
|
for dst_pop_front in
|
||||||
in 0..(dst_push_back + dst_push_front - dst_pop_back)
|
0..(dst_push_back + dst_push_front - dst_pop_back)
|
||||||
{
|
{
|
||||||
let mut dst = construct_vec_deque(
|
let mut dst = construct_vec_deque(
|
||||||
dst_push_back,
|
dst_push_back,
|
||||||
|
@ -1124,7 +1102,6 @@ fn test_reserve_exact_2() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(miri))] // Miri does not support signalling OOM
|
#[cfg(not(miri))] // Miri does not support signalling OOM
|
||||||
fn test_try_reserve() {
|
fn test_try_reserve() {
|
||||||
|
|
||||||
// These are the interesting cases:
|
// These are the interesting cases:
|
||||||
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
|
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
|
||||||
// * > isize::MAX should always fail
|
// * > isize::MAX should always fail
|
||||||
|
@ -1158,22 +1135,27 @@ fn test_try_reserve() {
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
// Check isize::MAX + 1 does count as overflow
|
// Check isize::MAX + 1 does count as overflow
|
||||||
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
|
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!")
|
||||||
|
}
|
||||||
|
|
||||||
// Check usize::MAX does count as overflow
|
// Check usize::MAX does count as overflow
|
||||||
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
|
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
|
||||||
} else { panic!("usize::MAX should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("usize::MAX should trigger an overflow!")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check isize::MAX is an OOM
|
// Check isize::MAX is an OOM
|
||||||
// VecDeque starts with capacity 7, always adds 1 to the capacity
|
// VecDeque starts with capacity 7, always adds 1 to the capacity
|
||||||
// and also rounds the number to next power of 2 so this is the
|
// and also rounds the number to next power of 2 so this is the
|
||||||
// furthest we can go without triggering CapacityOverflow
|
// furthest we can go without triggering CapacityOverflow
|
||||||
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP) {
|
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Same basic idea, but with non-zero len
|
// Same basic idea, but with non-zero len
|
||||||
let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||||
|
@ -1186,33 +1168,42 @@ fn test_try_reserve() {
|
||||||
}
|
}
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
|
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
|
if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Should always overflow in the add-to-len
|
// Should always overflow in the add-to-len
|
||||||
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
|
if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
|
||||||
} else { panic!("usize::MAX should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("usize::MAX should trigger an overflow!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Same basic idea, but with interesting type size
|
// Same basic idea, but with interesting type size
|
||||||
let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||||
|
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
|
||||||
panic!("isize::MAX shouldn't trigger an overflow!");
|
panic!("isize::MAX shouldn't trigger an overflow!");
|
||||||
}
|
}
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
|
||||||
panic!("isize::MAX shouldn't trigger an overflow!");
|
panic!("isize::MAX shouldn't trigger an overflow!");
|
||||||
}
|
}
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
|
if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Should fail in the mul-by-size
|
// Should fail in the mul-by-size
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
|
||||||
|
@ -1220,13 +1211,11 @@ fn test_try_reserve() {
|
||||||
panic!("usize::MAX should trigger an overflow!");
|
panic!("usize::MAX should trigger an overflow!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(miri))] // Miri does not support signalling OOM
|
#[cfg(not(miri))] // Miri does not support signalling OOM
|
||||||
fn test_try_reserve_exact() {
|
fn test_try_reserve_exact() {
|
||||||
|
|
||||||
// This is exactly the same as test_try_reserve with the method changed.
|
// This is exactly the same as test_try_reserve with the method changed.
|
||||||
// See that test for comments.
|
// See that test for comments.
|
||||||
|
|
||||||
|
@ -1247,21 +1236,26 @@ fn test_try_reserve_exact() {
|
||||||
|
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
|
if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!")
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
|
if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
|
||||||
} else { panic!("usize::MAX should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("usize::MAX should trigger an overflow!")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check isize::MAX is an OOM
|
// Check isize::MAX is an OOM
|
||||||
// VecDeque starts with capacity 7, always adds 1 to the capacity
|
// VecDeque starts with capacity 7, always adds 1 to the capacity
|
||||||
// and also rounds the number to next power of 2 so this is the
|
// and also rounds the number to next power of 2 so this is the
|
||||||
// furthest we can go without triggering CapacityOverflow
|
// furthest we can go without triggering CapacityOverflow
|
||||||
if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP) {
|
if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||||
|
|
||||||
|
@ -1273,36 +1267,46 @@ fn test_try_reserve_exact() {
|
||||||
}
|
}
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
|
if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
|
if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
|
if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
|
||||||
} else { panic!("usize::MAX should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("usize::MAX should trigger an overflow!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||||
|
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
|
||||||
panic!("isize::MAX shouldn't trigger an overflow!");
|
panic!("isize::MAX shouldn't trigger an overflow!");
|
||||||
}
|
}
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
|
||||||
panic!("isize::MAX shouldn't trigger an overflow!");
|
panic!("isize::MAX shouldn't trigger an overflow!");
|
||||||
}
|
}
|
||||||
if guards_against_isize {
|
if guards_against_isize {
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an overflow!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
|
if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
|
||||||
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
|
} else {
|
||||||
|
panic!("isize::MAX + 1 should trigger an OOM!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
|
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
|
||||||
} else { panic!("usize::MAX should trigger an overflow!") }
|
} else {
|
||||||
|
panic!("usize::MAX should trigger an overflow!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1404,9 +1408,8 @@ fn test_rotate_right_parts() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rotate_left_random() {
|
fn test_rotate_left_random() {
|
||||||
let shifts = [
|
let shifts = [
|
||||||
6, 1, 0, 11, 12, 1, 11, 7, 9, 3, 6, 1,
|
6, 1, 0, 11, 12, 1, 11, 7, 9, 3, 6, 1, 4, 0, 5, 1, 3, 1, 12, 8, 3, 1, 11, 11, 9, 4, 12, 3,
|
||||||
4, 0, 5, 1, 3, 1, 12, 8, 3, 1, 11, 11,
|
12, 9, 11, 1, 7, 9, 7, 2,
|
||||||
9, 4, 12, 3, 12, 9, 11, 1, 7, 9, 7, 2,
|
|
||||||
];
|
];
|
||||||
let n = 12;
|
let n = 12;
|
||||||
let mut v: VecDeque<_> = (0..n).collect();
|
let mut v: VecDeque<_> = (0..n).collect();
|
||||||
|
@ -1423,9 +1426,8 @@ fn test_rotate_left_random() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rotate_right_random() {
|
fn test_rotate_right_random() {
|
||||||
let shifts = [
|
let shifts = [
|
||||||
6, 1, 0, 11, 12, 1, 11, 7, 9, 3, 6, 1,
|
6, 1, 0, 11, 12, 1, 11, 7, 9, 3, 6, 1, 4, 0, 5, 1, 3, 1, 12, 8, 3, 1, 11, 11, 9, 4, 12, 3,
|
||||||
4, 0, 5, 1, 3, 1, 12, 8, 3, 1, 11, 11,
|
12, 9, 11, 1, 7, 9, 7, 2,
|
||||||
9, 4, 12, 3, 12, 9, 11, 1, 7, 9, 7, 2,
|
|
||||||
];
|
];
|
||||||
let n = 12;
|
let n = 12;
|
||||||
let mut v: VecDeque<_> = (0..n).collect();
|
let mut v: VecDeque<_> = (0..n).collect();
|
||||||
|
@ -1447,8 +1449,7 @@ fn test_try_fold_empty() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try_fold_none() {
|
fn test_try_fold_none() {
|
||||||
let v: VecDeque<u32> = (0..12).collect();
|
let v: VecDeque<u32> = (0..12).collect();
|
||||||
assert_eq!(None, v.into_iter().try_fold(0, |a, b|
|
assert_eq!(None, v.into_iter().try_fold(0, |a, b| if b < 11 { Some(a + b) } else { None }));
|
||||||
if b < 11 { Some(a + b) } else { None }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1463,7 +1464,6 @@ fn test_try_fold_unit() {
|
||||||
assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(())));
|
assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try_fold_unit_none() {
|
fn test_try_fold_unit_none() {
|
||||||
let v: std::collections::VecDeque<()> = [(); 10].iter().cloned().collect();
|
let v: std::collections::VecDeque<()> = [(); 10].iter().cloned().collect();
|
||||||
|
@ -1534,7 +1534,7 @@ fn test_try_rfold_rotated() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try_rfold_moves_iter() {
|
fn test_try_rfold_moves_iter() {
|
||||||
let v : VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect();
|
let v: VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect();
|
||||||
let mut iter = v.into_iter();
|
let mut iter = v.into_iter();
|
||||||
assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None);
|
assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None);
|
||||||
assert_eq!(iter.next_back(), Some(&70));
|
assert_eq!(iter.next_back(), Some(&70));
|
||||||
|
|
|
@ -44,14 +44,14 @@ CloneTypeFoldableImpls! {
|
||||||
pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
|
pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
|
||||||
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
|
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ConstEvalErr<'tcx> {
|
pub struct ConstEvalErr<'tcx> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub error: crate::mir::interpret::InterpError<'tcx>,
|
pub error: crate::mir::interpret::InterpError<'tcx>,
|
||||||
pub stacktrace: Vec<FrameInfo<'tcx>>,
|
pub stacktrace: Vec<FrameInfo<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FrameInfo<'tcx> {
|
pub struct FrameInfo<'tcx> {
|
||||||
/// This span is in the caller.
|
/// This span is in the caller.
|
||||||
pub call_site: Span,
|
pub call_site: Span,
|
||||||
|
@ -331,7 +331,7 @@ impl<O: fmt::Debug> fmt::Debug for PanicInfo<O> {
|
||||||
/// Error information for when the program we executed turned out not to actually be a valid
|
/// Error information for when the program we executed turned out not to actually be a valid
|
||||||
/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp
|
/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp
|
||||||
/// where we work on generic code or execution does not have all information available.
|
/// where we work on generic code or execution does not have all information available.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, HashStable)]
|
||||||
pub enum InvalidProgramInfo<'tcx> {
|
pub enum InvalidProgramInfo<'tcx> {
|
||||||
/// Resolution can fail if we are in a too generic context.
|
/// Resolution can fail if we are in a too generic context.
|
||||||
TooGeneric,
|
TooGeneric,
|
||||||
|
@ -361,7 +361,7 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error information for when the program caused Undefined Behavior.
|
/// Error information for when the program caused Undefined Behavior.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, HashStable)]
|
||||||
pub enum UndefinedBehaviorInfo {
|
pub enum UndefinedBehaviorInfo {
|
||||||
/// Free-form case. Only for errors that are never caught!
|
/// Free-form case. Only for errors that are never caught!
|
||||||
Ub(String),
|
Ub(String),
|
||||||
|
@ -394,11 +394,15 @@ impl fmt::Debug for UndefinedBehaviorInfo {
|
||||||
///
|
///
|
||||||
/// Currently, we also use this as fall-back error kind for errors that have not been
|
/// Currently, we also use this as fall-back error kind for errors that have not been
|
||||||
/// categorized yet.
|
/// categorized yet.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, HashStable)]
|
||||||
pub enum UnsupportedOpInfo<'tcx> {
|
pub enum UnsupportedOpInfo<'tcx> {
|
||||||
/// Free-form case. Only for errors that are never caught!
|
/// Free-form case. Only for errors that are never caught!
|
||||||
Unsupported(String),
|
Unsupported(String),
|
||||||
|
|
||||||
|
/// When const-prop encounters a situation it does not support, it raises this error.
|
||||||
|
/// This must not allocate for performance reasons.
|
||||||
|
ConstPropUnsupported(&'tcx str),
|
||||||
|
|
||||||
// -- Everything below is not categorized yet --
|
// -- Everything below is not categorized yet --
|
||||||
FunctionAbiMismatch(Abi, Abi),
|
FunctionAbiMismatch(Abi, Abi),
|
||||||
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
|
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
|
||||||
|
@ -559,13 +563,15 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
|
||||||
not a power of two"),
|
not a power of two"),
|
||||||
Unsupported(ref msg) =>
|
Unsupported(ref msg) =>
|
||||||
write!(f, "{}", msg),
|
write!(f, "{}", msg),
|
||||||
|
ConstPropUnsupported(ref msg) =>
|
||||||
|
write!(f, "Constant propagation encountered an unsupported situation: {}", msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error information for when the program exhausted the resources granted to it
|
/// Error information for when the program exhausted the resources granted to it
|
||||||
/// by the interpreter.
|
/// by the interpreter.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, HashStable)]
|
||||||
pub enum ResourceExhaustionInfo {
|
pub enum ResourceExhaustionInfo {
|
||||||
/// The stack grew too big.
|
/// The stack grew too big.
|
||||||
StackFrameLimitReached,
|
StackFrameLimitReached,
|
||||||
|
@ -586,7 +592,7 @@ impl fmt::Debug for ResourceExhaustionInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, HashStable)]
|
||||||
pub enum InterpError<'tcx> {
|
pub enum InterpError<'tcx> {
|
||||||
/// The program panicked.
|
/// The program panicked.
|
||||||
Panic(PanicInfo<u64>),
|
Panic(PanicInfo<u64>),
|
||||||
|
|
|
@ -94,9 +94,6 @@ pub struct Session {
|
||||||
/// The maximum length of types during monomorphization.
|
/// The maximum length of types during monomorphization.
|
||||||
pub type_length_limit: Once<usize>,
|
pub type_length_limit: Once<usize>,
|
||||||
|
|
||||||
/// The maximum number of stackframes allowed in const eval.
|
|
||||||
pub const_eval_stack_frame_limit: usize,
|
|
||||||
|
|
||||||
/// Map from imported macro spans (which consist of
|
/// Map from imported macro spans (which consist of
|
||||||
/// the localized span for the macro body) to the
|
/// the localized span for the macro body) to the
|
||||||
/// macro name and definition span in the source crate.
|
/// macro name and definition span in the source crate.
|
||||||
|
@ -1158,7 +1155,6 @@ fn build_session_(
|
||||||
features: Once::new(),
|
features: Once::new(),
|
||||||
recursion_limit: Once::new(),
|
recursion_limit: Once::new(),
|
||||||
type_length_limit: Once::new(),
|
type_length_limit: Once::new(),
|
||||||
const_eval_stack_frame_limit: 100,
|
|
||||||
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
|
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
|
||||||
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
|
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
|
||||||
cgu_reuse_tracker,
|
cgu_reuse_tracker,
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub enum BoundRegion {
|
||||||
impl BoundRegion {
|
impl BoundRegion {
|
||||||
pub fn is_named(&self) -> bool {
|
pub fn is_named(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
BoundRegion::BrNamed(..) => true,
|
BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorRe
|
||||||
use rustc_metadata::locator;
|
use rustc_metadata::locator;
|
||||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||||
use errors::{PResult, registry::Registry};
|
use errors::{PResult, registry::Registry};
|
||||||
use rustc_interface::interface;
|
use rustc_interface::{interface, Queries};
|
||||||
use rustc_interface::util::get_codegen_sysroot;
|
use rustc_interface::util::get_codegen_sysroot;
|
||||||
use rustc_data_structures::sync::SeqCst;
|
use rustc_data_structures::sync::SeqCst;
|
||||||
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
||||||
|
@ -98,17 +98,29 @@ pub trait Callbacks {
|
||||||
fn config(&mut self, _config: &mut interface::Config) {}
|
fn config(&mut self, _config: &mut interface::Config) {}
|
||||||
/// Called after parsing. Return value instructs the compiler whether to
|
/// Called after parsing. Return value instructs the compiler whether to
|
||||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||||
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
fn after_parsing<'tcx>(
|
||||||
|
&mut self,
|
||||||
|
_compiler: &interface::Compiler,
|
||||||
|
_queries: &'tcx Queries<'tcx>,
|
||||||
|
) -> Compilation {
|
||||||
Compilation::Continue
|
Compilation::Continue
|
||||||
}
|
}
|
||||||
/// Called after expansion. Return value instructs the compiler whether to
|
/// Called after expansion. Return value instructs the compiler whether to
|
||||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||||
fn after_expansion(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
fn after_expansion<'tcx>(
|
||||||
|
&mut self,
|
||||||
|
_compiler: &interface::Compiler,
|
||||||
|
_queries: &'tcx Queries<'tcx>,
|
||||||
|
) -> Compilation {
|
||||||
Compilation::Continue
|
Compilation::Continue
|
||||||
}
|
}
|
||||||
/// Called after analysis. Return value instructs the compiler whether to
|
/// Called after analysis. Return value instructs the compiler whether to
|
||||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||||
fn after_analysis(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
fn after_analysis<'tcx>(
|
||||||
|
&mut self,
|
||||||
|
_compiler: &interface::Compiler,
|
||||||
|
_queries: &'tcx Queries<'tcx>,
|
||||||
|
) -> Compilation {
|
||||||
Compilation::Continue
|
Compilation::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,7 +324,7 @@ pub fn run_compiler(
|
||||||
return early_exit();
|
return early_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if callbacks.after_parsing(compiler) == Compilation::Stop {
|
if callbacks.after_parsing(compiler, queries) == Compilation::Stop {
|
||||||
return early_exit();
|
return early_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +345,7 @@ pub fn run_compiler(
|
||||||
}
|
}
|
||||||
|
|
||||||
queries.expansion()?;
|
queries.expansion()?;
|
||||||
if callbacks.after_expansion(compiler) == Compilation::Stop {
|
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
|
||||||
return early_exit();
|
return early_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +394,7 @@ pub fn run_compiler(
|
||||||
|
|
||||||
queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
|
queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
|
||||||
|
|
||||||
if callbacks.after_analysis(compiler) == Compilation::Stop {
|
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
|
||||||
return early_exit();
|
return early_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,7 @@ E0199: include_str!("./error_codes/E0199.md"),
|
||||||
E0200: include_str!("./error_codes/E0200.md"),
|
E0200: include_str!("./error_codes/E0200.md"),
|
||||||
E0201: include_str!("./error_codes/E0201.md"),
|
E0201: include_str!("./error_codes/E0201.md"),
|
||||||
E0202: include_str!("./error_codes/E0202.md"),
|
E0202: include_str!("./error_codes/E0202.md"),
|
||||||
|
E0203: include_str!("./error_codes/E0203.md"),
|
||||||
E0204: include_str!("./error_codes/E0204.md"),
|
E0204: include_str!("./error_codes/E0204.md"),
|
||||||
E0205: include_str!("./error_codes/E0205.md"),
|
E0205: include_str!("./error_codes/E0205.md"),
|
||||||
E0206: include_str!("./error_codes/E0206.md"),
|
E0206: include_str!("./error_codes/E0206.md"),
|
||||||
|
@ -446,8 +447,6 @@ E0745: include_str!("./error_codes/E0745.md"),
|
||||||
// E0190, // deprecated: can only cast a &-pointer to an &-object
|
// E0190, // deprecated: can only cast a &-pointer to an &-object
|
||||||
// E0194, // merged into E0403
|
// E0194, // merged into E0403
|
||||||
// E0196, // cannot determine a type for this closure
|
// E0196, // cannot determine a type for this closure
|
||||||
E0203, // type parameter has more than one relaxed default bound,
|
|
||||||
// and only one is supported
|
|
||||||
E0208,
|
E0208,
|
||||||
// E0209, // builtin traits can only be implemented on structs or enums
|
// E0209, // builtin traits can only be implemented on structs or enums
|
||||||
E0212, // cannot extract an associated type from a higher-ranked trait bound
|
E0212, // cannot extract an associated type from a higher-ranked trait bound
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
Having multiple relaxed default bounds is unsupported.
|
||||||
|
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
|
```compile_fail,E0203
|
||||||
|
struct Bad<T: ?Sized + ?Send>{
|
||||||
|
inner: T
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here the type `T` cannot have a relaxed bound for multiple default traits
|
||||||
|
(`Sized` and `Send`). This can be fixed by only using one relaxed bound.
|
||||||
|
|
||||||
|
```
|
||||||
|
struct Good<T: ?Sized>{
|
||||||
|
inner: T
|
||||||
|
}
|
||||||
|
```
|
|
@ -18,6 +18,7 @@ pub mod util;
|
||||||
mod proc_macro_decls;
|
mod proc_macro_decls;
|
||||||
|
|
||||||
pub use interface::{run_compiler, Config};
|
pub use interface::{run_compiler, Config};
|
||||||
|
pub use queries::Queries;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
|
@ -78,17 +78,7 @@ impl OutlivesSuggestionBuilder<'a> {
|
||||||
match name.source {
|
match name.source {
|
||||||
RegionNameSource::NamedEarlyBoundRegion(..)
|
RegionNameSource::NamedEarlyBoundRegion(..)
|
||||||
| RegionNameSource::NamedFreeRegion(..)
|
| RegionNameSource::NamedFreeRegion(..)
|
||||||
| RegionNameSource::Static => {
|
| RegionNameSource::Static => true,
|
||||||
// FIXME: This is a bit hacky. We should ideally have a semantic way for checking
|
|
||||||
// if the name is `'_`...
|
|
||||||
if name.name().with(|name| name != "'_") {
|
|
||||||
debug!("Region {:?} is suggestable", name);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
debug!("Region {:?} is NOT suggestable", name);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't give suggestions for upvars, closure return types, or other unnamable
|
// Don't give suggestions for upvars, closure return types, or other unnamable
|
||||||
// regions.
|
// regions.
|
||||||
|
@ -98,7 +88,8 @@ impl OutlivesSuggestionBuilder<'a> {
|
||||||
| RegionNameSource::MatchedAdtAndSegment(..)
|
| RegionNameSource::MatchedAdtAndSegment(..)
|
||||||
| RegionNameSource::AnonRegionFromUpvar(..)
|
| RegionNameSource::AnonRegionFromUpvar(..)
|
||||||
| RegionNameSource::AnonRegionFromOutput(..)
|
| RegionNameSource::AnonRegionFromOutput(..)
|
||||||
| RegionNameSource::AnonRegionFromYieldTy(..) => {
|
| RegionNameSource::AnonRegionFromYieldTy(..)
|
||||||
|
| RegionNameSource::AnonRegionFromAsyncFn(..) => {
|
||||||
debug!("Region {:?} is NOT suggestable", name);
|
debug!("Region {:?} is NOT suggestable", name);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer::InferCtxt;
|
use rustc::infer::InferCtxt;
|
||||||
use rustc::mir::{Local, Body};
|
use rustc::mir::{Local, Body};
|
||||||
use rustc::ty::subst::{SubstsRef, GenericArgKind};
|
use rustc::ty::subst::{SubstsRef, GenericArgKind};
|
||||||
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
|
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
use rustc::ty::print::RegionHighlightMode;
|
use rustc::ty::print::RegionHighlightMode;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_errors::DiagnosticBuilder;
|
use rustc_errors::DiagnosticBuilder;
|
||||||
use syntax::symbol::kw;
|
use syntax::symbol::kw;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use syntax_pos::{Span, symbol::Symbol};
|
use syntax_pos::{Span, symbol::Symbol, DUMMY_SP};
|
||||||
|
|
||||||
/// A name for a particular region used in emitting diagnostics. This name could be a generated
|
/// A name for a particular region used in emitting diagnostics. This name could be a generated
|
||||||
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
|
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
|
||||||
|
@ -55,7 +55,10 @@ crate enum RegionNameSource {
|
||||||
AnonRegionFromUpvar(Span, String),
|
AnonRegionFromUpvar(Span, String),
|
||||||
/// The region corresponding to the return type of a closure.
|
/// The region corresponding to the return type of a closure.
|
||||||
AnonRegionFromOutput(Span, String, String),
|
AnonRegionFromOutput(Span, String, String),
|
||||||
|
/// The region from a type yielded by a generator.
|
||||||
AnonRegionFromYieldTy(Span, String),
|
AnonRegionFromYieldTy(Span, String),
|
||||||
|
/// An anonymous region from an async fn.
|
||||||
|
AnonRegionFromAsyncFn(Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Records region names that have been assigned before so that we can use the same ones in later
|
/// Records region names that have been assigned before so that we can use the same ones in later
|
||||||
|
@ -113,14 +116,11 @@ impl RegionName {
|
||||||
RegionNameSource::MatchedAdtAndSegment(..) |
|
RegionNameSource::MatchedAdtAndSegment(..) |
|
||||||
RegionNameSource::AnonRegionFromUpvar(..) |
|
RegionNameSource::AnonRegionFromUpvar(..) |
|
||||||
RegionNameSource::AnonRegionFromOutput(..) |
|
RegionNameSource::AnonRegionFromOutput(..) |
|
||||||
RegionNameSource::AnonRegionFromYieldTy(..) => false,
|
RegionNameSource::AnonRegionFromYieldTy(..) |
|
||||||
|
RegionNameSource::AnonRegionFromAsyncFn(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn name(&self) -> Symbol {
|
|
||||||
self.name
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) {
|
crate fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) {
|
||||||
match &self.source {
|
match &self.source {
|
||||||
RegionNameSource::NamedFreeRegion(span)
|
RegionNameSource::NamedFreeRegion(span)
|
||||||
|
@ -137,7 +137,8 @@ impl RegionName {
|
||||||
RegionNameSource::CannotMatchHirTy(span, type_name) => {
|
RegionNameSource::CannotMatchHirTy(span, type_name) => {
|
||||||
diag.span_label(*span, format!("has type `{}`", type_name));
|
diag.span_label(*span, format!("has type `{}`", type_name));
|
||||||
}
|
}
|
||||||
RegionNameSource::MatchedHirTy(span) => {
|
RegionNameSource::MatchedHirTy(span) |
|
||||||
|
RegionNameSource::AnonRegionFromAsyncFn(span) => {
|
||||||
diag.span_label(
|
diag.span_label(
|
||||||
*span,
|
*span,
|
||||||
format!("let's call the lifetime of this reference `{}`", self),
|
format!("let's call the lifetime of this reference `{}`", self),
|
||||||
|
@ -270,7 +271,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
match error_region {
|
match error_region {
|
||||||
ty::ReEarlyBound(ebr) => {
|
ty::ReEarlyBound(ebr) => {
|
||||||
if ebr.has_name() {
|
if ebr.has_name() {
|
||||||
let span = self.get_named_span(tcx, error_region, ebr.name);
|
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
|
||||||
Some(RegionName {
|
Some(RegionName {
|
||||||
name: ebr.name,
|
name: ebr.name,
|
||||||
source: RegionNameSource::NamedEarlyBoundRegion(span),
|
source: RegionNameSource::NamedEarlyBoundRegion(span),
|
||||||
|
@ -286,12 +287,30 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ty::ReFree(free_region) => match free_region.bound_region {
|
ty::ReFree(free_region) => match free_region.bound_region {
|
||||||
ty::BoundRegion::BrNamed(_, name) => {
|
ty::BoundRegion::BrNamed(region_def_id, name) => {
|
||||||
let span = self.get_named_span(tcx, error_region, name);
|
// Get the span to point to, even if we don't use the name.
|
||||||
Some(RegionName {
|
let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP);
|
||||||
name,
|
debug!("bound region named: {:?}, is_named: {:?}",
|
||||||
source: RegionNameSource::NamedFreeRegion(span),
|
name, free_region.bound_region.is_named());
|
||||||
})
|
|
||||||
|
if free_region.bound_region.is_named() {
|
||||||
|
// A named region that is actually named.
|
||||||
|
Some(RegionName {
|
||||||
|
name,
|
||||||
|
source: RegionNameSource::NamedFreeRegion(span),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// If we spuriously thought that the region is named, we should let the
|
||||||
|
// system generate a true name for error messages. Currently this can
|
||||||
|
// happen if we have an elided name in an async fn for example: the
|
||||||
|
// compiler will generate a region named `'_`, but reporting such a name is
|
||||||
|
// not actually useful, so we synthesize a name for it instead.
|
||||||
|
let name = renctx.synthesize_region_name();
|
||||||
|
Some(RegionName {
|
||||||
|
name,
|
||||||
|
source: RegionNameSource::AnonRegionFromAsyncFn(span),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::BoundRegion::BrEnv => {
|
ty::BoundRegion::BrEnv => {
|
||||||
|
@ -350,40 +369,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a span of a named region to provide context for error messages that
|
|
||||||
/// mention that span, for example:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// |
|
|
||||||
/// | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
|
||||||
/// | -- -- lifetime `'b` defined here
|
|
||||||
/// | |
|
|
||||||
/// | lifetime `'a` defined here
|
|
||||||
/// |
|
|
||||||
/// | with_signature(cell, t, |cell, t| require(cell, t));
|
|
||||||
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must
|
|
||||||
/// | outlive `'a`
|
|
||||||
/// ```
|
|
||||||
fn get_named_span(
|
|
||||||
&self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
error_region: &RegionKind,
|
|
||||||
name: Symbol,
|
|
||||||
) -> Span {
|
|
||||||
let scope = error_region.free_region_binding_scope(tcx);
|
|
||||||
let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID);
|
|
||||||
|
|
||||||
let span = tcx.sess.source_map().def_span(tcx.hir().span(node));
|
|
||||||
if let Some(param) = tcx.hir()
|
|
||||||
.get_generics(scope)
|
|
||||||
.and_then(|generics| generics.get_named(name))
|
|
||||||
{
|
|
||||||
param.span
|
|
||||||
} else {
|
|
||||||
span
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds an argument that contains `fr` and label it with a fully
|
/// Finds an argument that contains `fr` and label it with a fully
|
||||||
/// elaborated type, returning something like `'1`. Result looks
|
/// elaborated type, returning something like `'1`. Result looks
|
||||||
/// like:
|
/// like:
|
||||||
|
|
|
@ -548,7 +548,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
|
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
|
||||||
|
|
||||||
if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit {
|
if self.stack.len() > *self.tcx.sess.recursion_limit.get() {
|
||||||
throw_exhaust!(StackFrameLimitReached)
|
throw_exhaust!(StackFrameLimitReached)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -560,7 +560,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
|
||||||
trace!("visit_statement: statement={:?} location={:?}", statement, location);
|
trace!("visit_statement: statement={:?} location={:?}", statement, location);
|
||||||
|
|
||||||
match statement.kind {
|
match statement.kind {
|
||||||
StatementKind::Assign(..) => {
|
StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } => {
|
||||||
self.super_statement(statement, location);
|
self.super_statement(statement, location);
|
||||||
}
|
}
|
||||||
StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => {
|
StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => {
|
||||||
|
@ -568,7 +568,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
// FIXME(eddyb) should these really do nothing?
|
// FIXME(eddyb) should these really do nothing?
|
||||||
StatementKind::FakeRead(..) |
|
StatementKind::FakeRead(..) |
|
||||||
StatementKind::SetDiscriminant { .. } |
|
|
||||||
StatementKind::StorageLive(_) |
|
StatementKind::StorageLive(_) |
|
||||||
StatementKind::StorageDead(_) |
|
StatementKind::StorageDead(_) |
|
||||||
StatementKind::InlineAsm {..} |
|
StatementKind::InlineAsm {..} |
|
||||||
|
|
|
@ -168,14 +168,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||||
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
|
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
|
||||||
_unwind: Option<BasicBlock>
|
_unwind: Option<BasicBlock>
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
throw_unsup_format!("calling intrinsics isn't supported in ConstProp");
|
throw_unsup!(ConstPropUnsupported("calling intrinsics isn't supported in ConstProp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ptr_to_int(
|
fn ptr_to_int(
|
||||||
_mem: &Memory<'mir, 'tcx, Self>,
|
_mem: &Memory<'mir, 'tcx, Self>,
|
||||||
_ptr: Pointer,
|
_ptr: Pointer,
|
||||||
) -> InterpResult<'tcx, u64> {
|
) -> InterpResult<'tcx, u64> {
|
||||||
throw_unsup_format!("ptr-to-int casts aren't supported in ConstProp");
|
throw_unsup!(ConstPropUnsupported("ptr-to-int casts aren't supported in ConstProp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary_ptr_op(
|
fn binary_ptr_op(
|
||||||
|
@ -185,7 +185,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||||
_right: ImmTy<'tcx>,
|
_right: ImmTy<'tcx>,
|
||||||
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
|
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
|
||||||
// We can't do this because aliasing of memory can differ between const eval and llvm
|
// We can't do this because aliasing of memory can differ between const eval and llvm
|
||||||
throw_unsup_format!("pointer arithmetic or comparisons aren't supported in ConstProp");
|
throw_unsup!(ConstPropUnsupported("pointer arithmetic or comparisons aren't supported \
|
||||||
|
in ConstProp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_foreign_static(
|
fn find_foreign_static(
|
||||||
|
@ -218,7 +219,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_dest: PlaceTy<'tcx>,
|
_dest: PlaceTy<'tcx>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
throw_unsup_format!("can't const prop `box` keyword");
|
throw_unsup!(ConstPropUnsupported("can't const prop `box` keyword"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn access_local(
|
fn access_local(
|
||||||
|
@ -229,7 +230,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||||
let l = &frame.locals[local];
|
let l = &frame.locals[local];
|
||||||
|
|
||||||
if l.value == LocalValue::Uninitialized {
|
if l.value == LocalValue::Uninitialized {
|
||||||
throw_unsup_format!("tried to access an uninitialized local");
|
throw_unsup!(ConstPropUnsupported("tried to access an uninitialized local"));
|
||||||
}
|
}
|
||||||
|
|
||||||
l.access()
|
l.access()
|
||||||
|
@ -241,7 +242,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||||
// if the static allocation is mutable or if it has relocations (it may be legal to mutate
|
// if the static allocation is mutable or if it has relocations (it may be legal to mutate
|
||||||
// the memory behind that in the future), then we can't const prop it
|
// the memory behind that in the future), then we can't const prop it
|
||||||
if allocation.mutability == Mutability::Mutable || allocation.relocations().len() > 0 {
|
if allocation.mutability == Mutability::Mutable || allocation.relocations().len() > 0 {
|
||||||
throw_unsup_format!("can't eval mutable statics in ConstProp");
|
throw_unsup!(ConstPropUnsupported("can't eval mutable statics in ConstProp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -389,9 +390,26 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
let r = match f(self) {
|
let r = match f(self) {
|
||||||
Ok(val) => Some(val),
|
Ok(val) => Some(val),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
use rustc::mir::interpret::InterpError::*;
|
use rustc::mir::interpret::{
|
||||||
|
UnsupportedOpInfo,
|
||||||
|
UndefinedBehaviorInfo,
|
||||||
|
InterpError::*
|
||||||
|
};
|
||||||
match error.kind {
|
match error.kind {
|
||||||
Exit(_) => bug!("the CTFE program cannot exit"),
|
Exit(_) => bug!("the CTFE program cannot exit"),
|
||||||
|
|
||||||
|
// Some error shouldn't come up because creating them causes
|
||||||
|
// an allocation, which we should avoid. When that happens,
|
||||||
|
// dedicated error variants should be introduced instead.
|
||||||
|
// Only test this in debug builds though to avoid disruptions.
|
||||||
|
Unsupported(UnsupportedOpInfo::Unsupported(_))
|
||||||
|
| Unsupported(UnsupportedOpInfo::ValidationFailure(_))
|
||||||
|
| UndefinedBehavior(UndefinedBehaviorInfo::Ub(_))
|
||||||
|
| UndefinedBehavior(UndefinedBehaviorInfo::UbExperimental(_))
|
||||||
|
if cfg!(debug_assertions) => {
|
||||||
|
bug!("const-prop encountered allocating error: {:?}", error.kind);
|
||||||
|
}
|
||||||
|
|
||||||
Unsupported(_)
|
Unsupported(_)
|
||||||
| UndefinedBehavior(_)
|
| UndefinedBehavior(_)
|
||||||
| InvalidProgram(_)
|
| InvalidProgram(_)
|
||||||
|
|
|
@ -225,7 +225,7 @@ fn check_statement(
|
||||||
StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
|
StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
|
||||||
|
|
||||||
// just an assignment
|
// just an assignment
|
||||||
StatementKind::SetDiscriminant { .. } => Ok(()),
|
StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body),
|
||||||
|
|
||||||
| StatementKind::InlineAsm { .. } => {
|
| StatementKind::InlineAsm { .. } => {
|
||||||
Err((span, "cannot use inline assembly in const fn".into()))
|
Err((span, "cannot use inline assembly in const fn".into()))
|
||||||
|
|
|
@ -37,22 +37,30 @@ pub fn calc_result<'a>(
|
||||||
let result = match (&desc.should_panic, task_result) {
|
let result = match (&desc.should_panic, task_result) {
|
||||||
(&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
|
(&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
|
||||||
(&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
|
(&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
|
||||||
if err
|
let maybe_panic_str = err
|
||||||
.downcast_ref::<String>()
|
.downcast_ref::<String>()
|
||||||
.map(|e| &**e)
|
.map(|e| &**e)
|
||||||
.or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
|
.or_else(|| err.downcast_ref::<&'static str>().map(|e| *e));
|
||||||
.map(|e| e.contains(msg))
|
|
||||||
.unwrap_or(false)
|
if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
|
||||||
{
|
|
||||||
TestResult::TrOk
|
TestResult::TrOk
|
||||||
|
} else if desc.allow_fail {
|
||||||
|
TestResult::TrAllowedFail
|
||||||
|
} else if let Some(panic_str) = maybe_panic_str {
|
||||||
|
TestResult::TrFailedMsg(format!(
|
||||||
|
r#"panic did not contain expected string
|
||||||
|
panic message: `{:?}`,
|
||||||
|
expected substring: `{:?}`"#,
|
||||||
|
panic_str, msg
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
if desc.allow_fail {
|
TestResult::TrFailedMsg(format!(
|
||||||
TestResult::TrAllowedFail
|
r#"expected panic with string value,
|
||||||
} else {
|
found non-string value: `{:?}`
|
||||||
TestResult::TrFailedMsg(
|
expected substring: `{:?}`"#,
|
||||||
format!("panic did not include expected string '{}'", msg)
|
(**err).type_id(),
|
||||||
)
|
msg
|
||||||
}
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ShouldPanic::Yes, Ok(())) => {
|
(&ShouldPanic::Yes, Ok(())) => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use crate::{
|
||||||
// TestType, TrFailedMsg, TrIgnored, TrOk,
|
// TestType, TrFailedMsg, TrIgnored, TrOk,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use std::any::TypeId;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ pub fn do_not_run_ignored_tests() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result != TrOk);
|
assert_ne!(result, TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -103,7 +104,7 @@ pub fn ignored_tests_result_in_ignored() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result == TrIgnored);
|
assert_eq!(result, TrIgnored);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
||||||
|
@ -126,7 +127,7 @@ fn test_should_panic() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result == TrOk);
|
assert_eq!(result, TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
||||||
|
@ -149,7 +150,7 @@ fn test_should_panic_good_message() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result == TrOk);
|
assert_eq!(result, TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
||||||
|
@ -161,7 +162,9 @@ fn test_should_panic_bad_message() {
|
||||||
panic!("an error message");
|
panic!("an error message");
|
||||||
}
|
}
|
||||||
let expected = "foobar";
|
let expected = "foobar";
|
||||||
let failed_msg = "panic did not include expected string";
|
let failed_msg = r#"panic did not contain expected string
|
||||||
|
panic message: `"an error message"`,
|
||||||
|
expected substring: `"foobar"`"#;
|
||||||
let desc = TestDescAndFn {
|
let desc = TestDescAndFn {
|
||||||
desc: TestDesc {
|
desc: TestDesc {
|
||||||
name: StaticTestName("whatever"),
|
name: StaticTestName("whatever"),
|
||||||
|
@ -175,7 +178,35 @@ fn test_should_panic_bad_message() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
|
assert_eq!(result, TrFailedMsg(failed_msg.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(target_os = "emscripten"))]
|
||||||
|
fn test_should_panic_non_string_message_type() {
|
||||||
|
use crate::tests::TrFailedMsg;
|
||||||
|
fn f() {
|
||||||
|
panic!(1i32);
|
||||||
|
}
|
||||||
|
let expected = "foobar";
|
||||||
|
let failed_msg = format!(r#"expected panic with string value,
|
||||||
|
found non-string value: `{:?}`
|
||||||
|
expected substring: `"foobar"`"#, TypeId::of::<i32>());
|
||||||
|
let desc = TestDescAndFn {
|
||||||
|
desc: TestDesc {
|
||||||
|
name: StaticTestName("whatever"),
|
||||||
|
ignore: false,
|
||||||
|
should_panic: ShouldPanic::YesWithMessage(expected),
|
||||||
|
allow_fail: false,
|
||||||
|
test_type: TestType::Unknown,
|
||||||
|
},
|
||||||
|
testfn: DynTestFn(Box::new(f)),
|
||||||
|
};
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
|
let result = rx.recv().unwrap().result;
|
||||||
|
assert_eq!(result, TrFailedMsg(failed_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
|
||||||
|
@ -196,7 +227,7 @@ fn test_should_panic_but_succeeds() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||||
let result = rx.recv().unwrap().result;
|
let result = rx.recv().unwrap().result;
|
||||||
assert!(result == TrFailedMsg("test did not panic as expected".to_string()));
|
assert_eq!(result, TrFailedMsg("test did not panic as expected".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
|
fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
|
||||||
|
@ -570,7 +601,7 @@ pub fn sort_tests() {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (a, b) in expected.iter().zip(filtered) {
|
for (a, b) in expected.iter().zip(filtered) {
|
||||||
assert!(*a == b.desc.name.to_string());
|
assert_eq!(*a, b.desc.name.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,12 @@ error: lifetime may not live long enough
|
||||||
LL | async fn do_sth<'a>(
|
LL | async fn do_sth<'a>(
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | &'a self, foo: &dyn Foo
|
LL | &'a self, foo: &dyn Foo
|
||||||
| - lifetime `'_` defined here
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | ) -> &dyn Foo
|
LL | ) -> &dyn Foo
|
||||||
LL | / {
|
LL | / {
|
||||||
LL | | foo
|
LL | | foo
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'_`
|
| |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -42,3 +42,4 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0203`.
|
||||||
|
|
|
@ -2,11 +2,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
|
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
|
||||||
|
|
|
|
||||||
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
|
||||||
| - ^^^^^^^^ returning this value requires that `'_` must outlive `'static`
|
| - ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'1`
|
||||||
|
|
|
|
||||||
help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint
|
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint
|
||||||
|
|
|
|
||||||
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -10,19 +10,19 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
|
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
|
||||||
|
|
|
|
||||||
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
|
||||||
| - ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
| |
|
| | |
|
||||||
| lifetime `'_` defined here
|
| | let's call the lifetime of this reference `'1`
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
|
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
|
||||||
|
|
|
|
||||||
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
|
||||||
| - ^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
| |
|
| | |
|
||||||
| lifetime `'_` defined here
|
| | let's call the lifetime of this reference `'1`
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
|
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
|
||||||
|
@ -36,8 +36,9 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
|
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
|
||||||
|
|
|
|
||||||
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
|
||||||
| -- - lifetime `'_` defined here ^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
|
| -- - ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
|
||||||
| |
|
| | |
|
||||||
|
| | let's call the lifetime of this reference `'1`
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
|
@ -10,12 +10,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:13:9
|
--> $DIR/lt-ref-self-async.rs:13:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_self(&self, f: &u32) -> &u32 {
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/lt-ref-self-async.rs:18:48
|
--> $DIR/lt-ref-self-async.rs:18:48
|
||||||
|
@ -29,12 +28,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:19:9
|
--> $DIR/lt-ref-self-async.rs:19:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/lt-ref-self-async.rs:22:57
|
--> $DIR/lt-ref-self-async.rs:22:57
|
||||||
|
@ -48,12 +46,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:23:9
|
--> $DIR/lt-ref-self-async.rs:23:9
|
||||||
|
|
|
|
||||||
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/lt-ref-self-async.rs:26:57
|
--> $DIR/lt-ref-self-async.rs:26:57
|
||||||
|
@ -67,12 +64,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:27:9
|
--> $DIR/lt-ref-self-async.rs:27:9
|
||||||
|
|
|
|
||||||
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/lt-ref-self-async.rs:30:66
|
--> $DIR/lt-ref-self-async.rs:30:66
|
||||||
|
@ -86,12 +82,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:31:9
|
--> $DIR/lt-ref-self-async.rs:31:9
|
||||||
|
|
|
|
||||||
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/lt-ref-self-async.rs:34:62
|
--> $DIR/lt-ref-self-async.rs:34:62
|
||||||
|
@ -105,12 +100,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/lt-ref-self-async.rs:35:9
|
--> $DIR/lt-ref-self-async.rs:35:9
|
||||||
|
|
|
|
||||||
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:13:9
|
--> $DIR/ref-mut-self-async.rs:13:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-self-async.rs:18:52
|
--> $DIR/ref-mut-self-async.rs:18:52
|
||||||
|
@ -29,12 +28,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:19:9
|
--> $DIR/ref-mut-self-async.rs:19:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-self-async.rs:22:61
|
--> $DIR/ref-mut-self-async.rs:22:61
|
||||||
|
@ -48,12 +46,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:23:9
|
--> $DIR/ref-mut-self-async.rs:23:9
|
||||||
|
|
|
|
||||||
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-self-async.rs:26:61
|
--> $DIR/ref-mut-self-async.rs:26:61
|
||||||
|
@ -67,12 +64,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:27:9
|
--> $DIR/ref-mut-self-async.rs:27:9
|
||||||
|
|
|
|
||||||
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-self-async.rs:30:70
|
--> $DIR/ref-mut-self-async.rs:30:70
|
||||||
|
@ -86,12 +82,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:31:9
|
--> $DIR/ref-mut-self-async.rs:31:9
|
||||||
|
|
|
|
||||||
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-self-async.rs:34:70
|
--> $DIR/ref-mut-self-async.rs:34:70
|
||||||
|
@ -105,12 +100,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-self-async.rs:35:9
|
--> $DIR/ref-mut-self-async.rs:35:9
|
||||||
|
|
|
|
||||||
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-struct-async.rs:13:9
|
--> $DIR/ref-mut-struct-async.rs:13:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-struct-async.rs:16:65
|
--> $DIR/ref-mut-struct-async.rs:16:65
|
||||||
|
@ -29,12 +28,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-struct-async.rs:17:9
|
--> $DIR/ref-mut-struct-async.rs:17:9
|
||||||
|
|
|
|
||||||
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-struct-async.rs:20:65
|
--> $DIR/ref-mut-struct-async.rs:20:65
|
||||||
|
@ -48,12 +46,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-struct-async.rs:21:9
|
--> $DIR/ref-mut-struct-async.rs:21:9
|
||||||
|
|
|
|
||||||
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-struct-async.rs:24:74
|
--> $DIR/ref-mut-struct-async.rs:24:74
|
||||||
|
@ -67,12 +64,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-struct-async.rs:25:9
|
--> $DIR/ref-mut-struct-async.rs:25:9
|
||||||
|
|
|
|
||||||
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-mut-struct-async.rs:28:74
|
--> $DIR/ref-mut-struct-async.rs:28:74
|
||||||
|
@ -86,12 +82,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-mut-struct-async.rs:29:9
|
--> $DIR/ref-mut-struct-async.rs:29:9
|
||||||
|
|
|
|
||||||
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-struct-async.rs:13:9
|
--> $DIR/ref-struct-async.rs:13:9
|
||||||
|
|
|
|
||||||
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-struct-async.rs:16:61
|
--> $DIR/ref-struct-async.rs:16:61
|
||||||
|
@ -29,12 +28,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-struct-async.rs:17:9
|
--> $DIR/ref-struct-async.rs:17:9
|
||||||
|
|
|
|
||||||
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-struct-async.rs:20:61
|
--> $DIR/ref-struct-async.rs:20:61
|
||||||
|
@ -48,12 +46,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-struct-async.rs:21:9
|
--> $DIR/ref-struct-async.rs:21:9
|
||||||
|
|
|
|
||||||
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-struct-async.rs:24:70
|
--> $DIR/ref-struct-async.rs:24:70
|
||||||
|
@ -67,12 +64,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-struct-async.rs:25:9
|
--> $DIR/ref-struct-async.rs:25:9
|
||||||
|
|
|
|
||||||
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ref-struct-async.rs:28:66
|
--> $DIR/ref-struct-async.rs:28:66
|
||||||
|
@ -86,12 +82,11 @@ error: lifetime may not live long enough
|
||||||
--> $DIR/ref-struct-async.rs:29:9
|
--> $DIR/ref-struct-async.rs:29:9
|
||||||
|
|
|
|
||||||
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
|
||||||
| -
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| |
|
| |
|
||||||
| lifetime `'_` defined here
|
| let's call the lifetime of this reference `'2`
|
||||||
| lifetime `'_` defined here
|
|
||||||
LL | f
|
LL | f
|
||||||
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
|
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue