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:
bors 2019-12-01 06:00:33 +00:00
commit 4007d4ef26
47 changed files with 660 additions and 634 deletions

View File

@ -1,15 +1,15 @@
use super::*;
extern crate test;
use test::Bencher;
use crate::boxed::Box;
use test::Bencher;
#[test]
fn allocate_zeroed() {
unsafe {
let layout = Layout::from_size_align(1024, 1).unwrap();
let ptr = Global.alloc_zeroed(layout.clone())
.unwrap_or_else(|_| handle_alloc_error(layout));
let ptr =
Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));
let mut i = ptr.cast::<u8>().as_ptr();
let end = i.add(layout.size());

View File

@ -1,12 +1,12 @@
use std::collections::BTreeMap;
use std::iter::Iterator;
use std::vec::Vec;
use std::collections::BTreeMap;
use rand::{Rng, seq::SliceRandom, thread_rng};
use test::{Bencher, black_box};
use rand::{seq::SliceRandom, thread_rng, Rng};
use test::{black_box, Bencher};
macro_rules! map_insert_rand_bench {
($name: ident, $n: expr, $map: ident) => (
($name: ident, $n: expr, $map: ident) => {
#[bench]
pub fn $name(b: &mut Bencher) {
let n: usize = $n;
@ -27,11 +27,11 @@ macro_rules! map_insert_rand_bench {
});
black_box(map);
}
)
};
}
macro_rules! map_insert_seq_bench {
($name: ident, $n: expr, $map: ident) => (
($name: ident, $n: expr, $map: ident) => {
#[bench]
pub fn $name(b: &mut Bencher) {
let mut map = $map::new();
@ -50,11 +50,11 @@ macro_rules! map_insert_seq_bench {
});
black_box(map);
}
)
};
}
macro_rules! map_find_rand_bench {
($name: ident, $n: expr, $map: ident) => (
($name: ident, $n: expr, $map: ident) => {
#[bench]
pub fn $name(b: &mut Bencher) {
let mut map = $map::new();
@ -78,11 +78,11 @@ macro_rules! map_find_rand_bench {
black_box(t);
})
}
)
};
}
macro_rules! map_find_seq_bench {
($name: ident, $n: expr, $map: ident) => (
($name: ident, $n: expr, $map: ident) => {
#[bench]
pub fn $name(b: &mut Bencher) {
let mut map = $map::new();
@ -101,20 +101,20 @@ macro_rules! map_find_seq_bench {
black_box(x);
})
}
)
};
}
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_100, 100, 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_10_000, 10_000, BTreeMap}
map_insert_seq_bench! {insert_seq_100, 100, 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_10_000, 10_000, BTreeMap}
map_find_rand_bench! {find_rand_100, 100, 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_10_000, 10_000, BTreeMap}
map_find_seq_bench! {find_seq_100, 100, BTreeMap}
map_find_seq_bench! {find_seq_10_000, 10_000, BTreeMap}
fn bench_iter(b: &mut Bencher, size: i32) {
let mut map = BTreeMap::<i32, i32>::new();

View File

@ -1,9 +1,9 @@
use std::{mem, ptr};
use rand::distributions::{Alphanumeric, Standard};
use rand::{thread_rng, Rng, SeedableRng};
use rand::distributions::{Standard, Alphanumeric};
use rand_xorshift::XorShiftRng;
use test::{Bencher, black_box};
use test::{black_box, Bencher};
#[bench]
fn iterator(b: &mut Bencher) {
@ -239,7 +239,7 @@ macro_rules! sort {
b.iter(|| v.clone().$f());
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
}
}
};
}
macro_rules! sort_strings {
@ -251,7 +251,7 @@ macro_rules! sort_strings {
b.iter(|| v.clone().$f());
b.bytes = $len * mem::size_of::<&str>() as u64;
}
}
};
}
macro_rules! sort_expensive {
@ -273,7 +273,7 @@ macro_rules! sort_expensive {
});
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
}
}
};
}
macro_rules! sort_lexicographic {
@ -284,7 +284,7 @@ macro_rules! sort_lexicographic {
b.iter(|| v.clone().$f(|x| x.to_string()));
b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
}
}
};
}
sort!(sort, sort_small_ascending, gen_ascending, 10);
@ -325,24 +325,25 @@ macro_rules! reverse {
fn $name(b: &mut Bencher) {
// odd length and offset by 1 to be as unaligned as possible
let n = 0xFFFFF;
let mut v: Vec<_> =
(0..1+(n / mem::size_of::<$ty>() as u64))
.map($f)
.collect();
let mut v: Vec<_> = (0..1 + (n / mem::size_of::<$ty>() as u64)).map($f).collect();
b.iter(|| black_box(&mut v[1..]).reverse());
b.bytes = n;
}
}
};
}
reverse!(reverse_u8, u8, |x| x as u8);
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_u64, u64, |x| x as u64);
reverse!(reverse_u128, u128, |x| x as u128);
#[repr(simd)] struct F64x4(f64, f64, f64, f64);
reverse!(reverse_simd_f64x4, F64x4, |x| { let x = x as f64; F64x4(x,x,x,x) });
#[repr(simd)]
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 {
($name:ident, $gen:expr, $len:expr, $mid:expr) => {
@ -350,32 +351,32 @@ macro_rules! rotate {
fn $name(b: &mut Bencher) {
let size = mem::size_of_val(&$gen(1)[0]);
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;
}
}
};
}
rotate!(rotate_tiny_by1, gen_random, 16, 1);
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, gen_random, 16, 16 / 2);
rotate!(rotate_tiny_half_plus_one, gen_random, 16, 16 / 2 + 1);
rotate!(rotate_medium_by1, gen_random, 9158, 1);
rotate!(rotate_medium_by727_u64, gen_random, 9158, 727);
rotate!(rotate_medium_by727_bytes, gen_random_bytes, 9158, 727);
rotate!(rotate_medium_by727_strings, gen_strings, 9158, 727);
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, gen_random, 9158, 9158 / 2);
rotate!(rotate_medium_half_plus_one, gen_random, 9158, 9158 / 2 + 1);
// Intended to use more RAM than the machine has cache
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_bytes, gen_random_bytes, 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_by1234577_u64, gen_random, 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_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_plus_one, gen_random, 5*1024*1024, 5*1024*1024/2+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_bytes, gen_random_bytes, 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_by1234577_u64, gen_random, 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_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_plus_one, gen_random, 5 * 1024 * 1024, 5 * 1024 * 1024 / 2 + 1);

View File

@ -1,4 +1,4 @@
use test::{Bencher, black_box};
use test::{black_box, Bencher};
#[bench]
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";
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";
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) {
let s = "Mary had a little lamb, Little lamb, little-lamb.";
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));
}
@ -185,16 +191,19 @@ fn bench_contains_equal(b: &mut Bencher) {
})
}
macro_rules! make_test_inner {
($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => {
#[bench]
fn $name(bencher: &mut Bencher) {
let mut $s = $str;
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 {
@ -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!(trim_ascii_char, s, {
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_ascii_char, s, { 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!(find_underscore_char, s, s.find('_'));
make_test!(rfind_underscore_char, s, s.rfind('_'));

View File

@ -1,5 +1,5 @@
use std::collections::VecDeque;
use test::{Bencher, black_box};
use test::{black_box, Bencher};
#[bench]
fn bench_new(b: &mut Bencher) {

View File

@ -30,8 +30,5 @@ fn main() {
assert!(BENCH_N % 2 == 0);
let median = (durations[(l / 2) - 1] + durations[l / 2]) / 2;
println!(
"\ncustom-bench vec_deque_append {:?} ns/iter\n",
median.as_nanos()
);
println!("\ncustom-bench vec_deque_append {:?} ns/iter\n", median.as_nanos());
}

View File

@ -1,6 +1,6 @@
pub mod map;
mod node;
mod search;
pub mod map;
pub mod set;
#[doc(hidden)]

View File

@ -1,21 +1,23 @@
use core::borrow::Borrow;
use core::cmp::Ordering;
use super::node::{Handle, NodeRef, marker, ForceResult::*};
use super::node::{marker, ForceResult::*, Handle, NodeRef};
use SearchResult::*;
pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
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>(
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
key: &Q
key: &Q,
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
where Q: Ord, K: Borrow<Q> {
where
Q: Ord,
K: Borrow<Q>,
{
loop {
match search_node(node, key) {
Found(handle) => return Found(handle),
@ -25,38 +27,38 @@ pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
node = internal.descend();
continue;
}
}
},
}
}
}
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
node: NodeRef<BorrowType, K, V, Type>,
key: &Q
key: &Q,
) -> SearchResult<BorrowType, K, V, Type, Type>
where Q: Ord, K: Borrow<Q> {
where
Q: Ord,
K: Borrow<Q>,
{
match search_linear(&node, key) {
(idx, true) => Found(
Handle::new_kv(node, idx)
),
(idx, false) => SearchResult::GoDown(
Handle::new_edge(node, idx)
)
(idx, true) => Found(Handle::new_kv(node, idx)),
(idx, false) => SearchResult::GoDown(Handle::new_edge(node, idx)),
}
}
pub fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
node: &NodeRef<BorrowType, K, V, Type>,
key: &Q
key: &Q,
) -> (usize, bool)
where Q: Ord, K: Borrow<Q> {
where
Q: Ord,
K: Borrow<Q>,
{
for (i, k) in node.keys().iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {},
Ordering::Greater => {}
Ordering::Equal => return (i, true),
Ordering::Less => return (i, false)
Ordering::Less => return (i, false),
}
}
(node.keys().len(), false)

View File

@ -177,8 +177,7 @@ fn test_insert_prev() {
}
check_links(&m);
assert_eq!(m.len(), 3 + len * 2);
assert_eq!(m.into_iter().collect::<Vec<_>>(),
[-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
assert_eq!(m.into_iter().collect::<Vec<_>>(), [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
}
#[test]
@ -187,13 +186,13 @@ fn test_insert_prev() {
fn test_send() {
let n = list_from(&[1, 2, 3]);
thread::spawn(move || {
check_links(&n);
let a: &[_] = &[&1, &2, &3];
assert_eq!(a, &*n.iter().collect::<Vec<_>>());
})
.join()
.ok()
.unwrap();
check_links(&n);
let a: &[_] = &[&1, &2, &3];
assert_eq!(a, &*n.iter().collect::<Vec<_>>());
})
.join()
.ok()
.unwrap();
}
#[test]

View File

@ -66,11 +66,8 @@ fn test_swap_front_back_remove() {
let final_len = usable_cap / 2;
for len in 0..final_len {
let expected: VecDeque<_> = if back {
(0..len).collect()
} else {
(0..len).rev().collect()
};
let expected: VecDeque<_> =
if back { (0..len).collect() } else { (0..len).rev().collect() };
for tail_pos in 0..usable_cap {
tester.tail = tail_pos;
tester.head = tail_pos;
@ -111,7 +108,6 @@ fn test_insert() {
// this test isn't covering what it wants to
let cap = tester.capacity();
// len is the length *after* insertion
for len in 1..cap {
// 0, 1, 2, .., len - 1
@ -198,9 +194,7 @@ fn test_drain() {
assert!(tester.head < tester.cap());
// We should see the correct values in the VecDeque
let expected: VecDeque<_> = (0..drain_start)
.chain(drain_end..len)
.collect();
let expected: VecDeque<_> = (0..drain_start).chain(drain_end..len).collect();
assert_eq!(expected, tester);
}
}

View File

@ -516,24 +516,24 @@
#[unstable(feature = "fmt_internals", issue = "0")]
pub use core::fmt::rt;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{Formatter, Result, Write};
#[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 = "fmt_flags_align", since = "1.28.0")]
pub use core::fmt::Alignment;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::Error;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{write, ArgumentV1, Arguments};
#[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};
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
pub use core::fmt::{Alignment};
#[stable(feature = "rust1", since = "1.0.0")]
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;
@ -568,8 +568,6 @@ use crate::string;
pub fn format(args: Arguments<'_>) -> string::String {
let capacity = args.estimated_capacity();
let mut output = string::String::with_capacity(capacity);
output
.write_fmt(args)
.expect("a formatting trait implementation returned an error");
output.write_fmt(args).expect("a formatting trait implementation returned an error");
output
}

View File

@ -4,7 +4,11 @@
#![unstable(feature = "alloc_prelude", issue = "58935")]
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
#[unstable(feature = "alloc_prelude", issue = "58935")] 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;
#[unstable(feature = "alloc_prelude", issue = "58935")]
pub use crate::borrow::ToOwned;
#[unstable(feature = "alloc_prelude", issue = "58935")]
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;

View File

@ -16,7 +16,9 @@ fn allocator_param() {
// A dumb allocator that consumes a fixed amount of fuel
// before allocation attempts start failing.
struct BoundedAlloc { fuel: usize }
struct BoundedAlloc {
fuel: usize,
}
unsafe impl Alloc for BoundedAlloc {
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
let size = layout.size();
@ -24,7 +26,10 @@ fn allocator_param() {
return Err(AllocErr);
}
match Global.alloc(layout) {
ok @ Ok(_) => { self.fuel -= size; ok }
ok @ Ok(_) => {
self.fuel -= size;
ok
}
err @ Err(_) => err,
}
}

View File

@ -82,7 +82,6 @@
//! [`.chunks`]: ../../std/primitive.slice.html#method.chunks
//! [`.windows`]: ../../std/primitive.slice.html#method.windows
#![stable(feature = "rust1", since = "1.0.0")]
// 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.
#![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::mem::{self, size_of};
use core::ptr;
use core::{u8, u16, u32};
use core::{u16, u32, u8};
use crate::borrow::ToOwned;
use crate::boxed::Box;
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")]
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")]
pub use core::slice::{Iter, IterMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{SplitMut, ChunksMut, Split};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
#[stable(feature = "rchunks", since = "1.31.0")]
pub use core::slice::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
#[stable(feature = "slice_rsplit", since = "1.27.0")]
pub use core::slice::{RSplit, RSplitMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
#[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};
pub use core::slice::{RSplitN, RSplitNMut, SplitN, SplitNMut};
////////////////////////////////////////////////////////////////////////////////
// Basic slice extension methods
@ -138,9 +137,9 @@ pub use hack::to_vec;
// `test_permutations` test
mod hack {
use crate::boxed::Box;
use crate::vec::Vec;
#[cfg(test)]
use crate::string::ToString;
use crate::vec::Vec;
pub fn into_vec<T>(b: Box<[T]>) -> Vec<T> {
unsafe {
@ -153,7 +152,8 @@ mod hack {
#[inline]
pub fn to_vec<T>(s: &[T]) -> Vec<T>
where T: Clone
where
T: Clone,
{
let mut vector = Vec::with_capacity(s.len());
vector.extend_from_slice(s);
@ -193,7 +193,8 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn sort(&mut self)
where T: Ord
where
T: Ord,
{
merge_sort(self, |a, b| a.lt(b));
}
@ -246,7 +247,8 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
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);
}
@ -285,7 +287,9 @@ impl<T> [T] {
#[stable(feature = "slice_sort_by_key", since = "1.7.0")]
#[inline]
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)));
}
@ -325,11 +329,13 @@ impl<T> [T] {
#[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
#[inline]
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.
macro_rules! sort_by_key {
($t:ty, $slice:ident, $f:ident) => ({
($t:ty, $slice:ident, $f:ident) => {{
let mut indices: Vec<_> =
$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
@ -344,19 +350,27 @@ impl<T> [T] {
indices[i].1 = index;
$slice.swap(i, index as usize);
}
})
}};
}
let sz_u8 = mem::size_of::<(K, u8)>();
let sz_u16 = mem::size_of::<(K, u16)>();
let sz_u32 = mem::size_of::<(K, u32)>();
let sz_u8 = mem::size_of::<(K, u8)>();
let sz_u16 = mem::size_of::<(K, u16)>();
let sz_u32 = mem::size_of::<(K, u32)>();
let sz_usize = mem::size_of::<(K, usize)>();
let len = self.len();
if len < 2 { return }
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) }
if len < 2 {
return;
}
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)
}
@ -373,7 +387,8 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
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.
hack::to_vec(self)
@ -421,7 +436,10 @@ impl<T> [T] {
/// b"0123456789abcdef".repeat(usize::max_value());
/// ```
#[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 {
return Vec::new();
}
@ -486,7 +504,8 @@ impl<T> [T] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
where Self: Concat<Item>
where
Self: Concat<Item>,
{
Concat::concat(self)
}
@ -503,7 +522,8 @@ impl<T> [T] {
/// ```
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
where Self: Join<Separator>
where
Self: Join<Separator>,
{
Join::join(self, sep)
}
@ -521,11 +541,11 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
where Self: Join<Separator>
where
Self: Join<Separator>,
{
Join::join(self, sep)
}
}
#[lang = "slice_u8_alloc"]
@ -668,8 +688,8 @@ impl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] {
Some(first) => first,
None => return vec![],
};
let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() +
sep.len() * (slice.len() - 1);
let size =
slice.iter().map(|v| v.borrow().len()).sum::<usize>() + sep.len() * (slice.len() - 1);
let mut result = Vec::with_capacity(size);
result.extend_from_slice(first.borrow());
@ -734,7 +754,8 @@ impl<T: Clone> ToOwned for [T] {
///
/// This is the integral subroutine of insertion sort.
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]) {
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
// fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it
// initially held exactly once.
let mut hole = InsertionHole {
src: &mut *tmp,
dest: &mut v[1],
};
let mut hole = InsertionHole { src: &mut *tmp, dest: &mut v[1] };
ptr::copy_nonoverlapping(&v[1], &mut v[0], 1);
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> {
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
/// 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)
where F: FnMut(&T, &T) -> bool
where
F: FnMut(&T, &T) -> bool,
{
let len = v.len();
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 {
// The left run is shorter.
ptr::copy_nonoverlapping(v, buf, mid);
hole = MergeHole {
start: buf,
end: buf.add(mid),
dest: v,
};
hole = MergeHole { start: buf, end: buf.add(mid), dest: v };
// Initially, these pointers point to the beginnings of their arrays.
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 {
// The right run is shorter.
ptr::copy_nonoverlapping(v_mid, buf, len - mid);
hole = MergeHole {
start: buf,
end: buf.add(len - mid),
dest: v_mid,
};
hole = MergeHole { start: buf, end: buf.add(len - mid), dest: v_mid };
// Initially, these pointers point past the ends of their arrays.
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) {
// `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>();
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.
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.
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.
if len <= MAX_INSERTION {
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);
}
}
@ -966,14 +982,13 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
start -= 1;
unsafe {
if is_less(v.get_unchecked(start + 1), v.get_unchecked(start)) {
while start > 0 && is_less(v.get_unchecked(start),
v.get_unchecked(start - 1)) {
while start > 0 && is_less(v.get_unchecked(start), v.get_unchecked(start - 1)) {
start -= 1;
}
v[start..end].reverse();
} else {
while start > 0 && !is_less(v.get_unchecked(start),
v.get_unchecked(start - 1)) {
while start > 0 && !is_less(v.get_unchecked(start), v.get_unchecked(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.
runs.push(Run {
start,
len: end - start,
});
runs.push(Run { start, len: end - start });
end = start;
// 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 right = runs[r];
unsafe {
merge(&mut v[left.start .. right.start + right.len], left.len, buf.as_mut_ptr(),
&mut is_less);
merge(
&mut v[left.start..right.start + right.len],
left.len,
buf.as_mut_ptr(),
&mut is_less,
);
}
runs[r] = Run {
start: left.start,
len: left.len + right.len,
};
runs[r] = Run { start: left.start, len: left.len + right.len };
runs.remove(r + 1);
}
}
@ -1030,15 +1043,13 @@ fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
#[inline]
fn collapse(runs: &[Run]) -> Option<usize> {
let n = runs.len();
if n >= 2 && (runs[n - 1].start == 0 ||
runs[n - 2].len <= runs[n - 1].len ||
(n >= 3 && runs[n - 3].len <= runs[n - 2].len + runs[n - 1].len) ||
(n >= 4 && runs[n - 4].len <= runs[n - 3].len + runs[n - 2].len)) {
if n >= 3 && runs[n - 3].len < runs[n - 1].len {
Some(n - 3)
} else {
Some(n - 2)
}
if n >= 2
&& (runs[n - 1].start == 0
|| runs[n - 2].len <= runs[n - 1].len
|| (n >= 3 && runs[n - 3].len <= runs[n - 2].len + runs[n - 1].len)
|| (n >= 4 && runs[n - 4].len <= runs[n - 3].len + runs[n - 2].len))
{
if n >= 3 && runs[n - 3].len < runs[n - 1].len { Some(n - 3) } else { Some(n - 2) }
} else {
None
}

View File

@ -1,12 +1,12 @@
//! Test for `boxed` mod.
use core::any::Any;
use core::convert::TryInto;
use core::ops::Deref;
use core::result::Result::{Err, Ok};
use core::clone::Clone;
use core::convert::TryInto;
use core::f64;
use core::i64;
use core::ops::Deref;
use core::result::Result::{Err, Ok};
use std::boxed::Box;

View File

@ -1,9 +1,9 @@
use std::any::Any;
use std::sync::{Arc, Weak};
use std::cell::RefCell;
use std::cmp::PartialEq;
use std::iter::TrustedLen;
use std::mem;
use std::sync::{Arc, Weak};
#[test]
fn uninhabited() {
@ -12,7 +12,7 @@ fn uninhabited() {
a = a.clone();
assert!(a.upgrade().is_none());
let mut a: Weak<dyn Any> = a; // Unsizing
let mut a: Weak<dyn Any> = a; // Unsizing
a = a.clone();
assert!(a.upgrade().is_none());
}
@ -20,8 +20,8 @@ fn uninhabited() {
#[test]
fn slice() {
let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
let a: Arc<[u32]> = a; // Unsizing
let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion
let a: Arc<[u32]> = a; // Unsizing
let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion
assert_eq!(a, b);
// Exercise is_dangling() with a DST
@ -33,7 +33,7 @@ fn slice() {
#[test]
fn trait_object() {
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
let mut a = Arc::downgrade(&a);
@ -43,7 +43,7 @@ fn trait_object() {
let mut b = Weak::<u32>::new();
b = b.clone();
assert!(b.upgrade().is_none());
let mut b: Weak<dyn Any> = b; // Unsizing
let mut b: Weak<dyn Any> = b; // Unsizing
b = b.clone();
assert!(b.upgrade().is_none());
}
@ -57,7 +57,7 @@ fn float_nan_ne() {
#[test]
fn partial_eq() {
struct TestPEq (RefCell<usize>);
struct TestPEq(RefCell<usize>);
impl PartialEq for TestPEq {
fn eq(&self, other: &TestPEq) -> bool {
*self.0.borrow_mut() += 1;
@ -74,7 +74,7 @@ fn partial_eq() {
#[test]
fn eq() {
#[derive(Eq)]
struct TestEq (RefCell<usize>);
struct TestEq(RefCell<usize>);
impl PartialEq for TestEq {
fn eq(&self, other: &TestEq) -> bool {
*self.0.borrow_mut() += 1;
@ -160,13 +160,10 @@ fn shared_from_iter_trustedlen_normal() {
fn shared_from_iter_trustedlen_panic() {
// Exercise the `TrustedLen` implementation when `size_hint()` matches
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
let iter = (0..SHARED_ITER_MAX)
.map(|val| {
match val {
98 => panic!("I've almost got 99 problems."),
_ => Box::new(val),
}
});
let iter = (0..SHARED_ITER_MAX).map(|val| match val {
98 => panic!("I've almost got 99 problems."),
_ => Box::new(val),
});
assert_trusted_len(&iter);
let _ = iter.collect::<Rc<[_]>>();
@ -193,16 +190,8 @@ fn shared_from_iter_trustedlen_no_fuse() {
}
}
let vec = vec![
Some(Box::new(42)),
Some(Box::new(24)),
None,
Some(Box::new(12)),
];
let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))];
let iter = Iter(vec.into_iter());
assert_trusted_len(&iter);
assert_eq!(
&[Box::new(42), Box::new(24)],
&*iter.collect::<Rc<[_]>>()
);
assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>());
}

View File

@ -347,7 +347,7 @@ fn assert_covariance() {
// Destructors must be called exactly once per element.
// FIXME: re-enable emscripten once it can unwind again
#[test]
#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
#[cfg(not(target_os = "emscripten"))]
fn panic_safe() {
use std::cmp;
use std::panic::{self, AssertUnwindSafe};
@ -376,7 +376,10 @@ fn panic_safe() {
}
let mut rng = thread_rng();
const DATASZ: usize = 32;
#[cfg(not(miri))] // Miri is too slow
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.
let data = (1..=DATASZ).collect::<Vec<_>>();

View File

@ -1,5 +1,5 @@
use std::ptr::NonNull;
use std::mem::MaybeUninit;
use std::ptr::NonNull;
#[test]
fn unitialized_zero_size_box() {

View File

@ -11,12 +11,7 @@ struct DeterministicRng {
impl DeterministicRng {
fn new() -> Self {
DeterministicRng {
x: 0x193a6754,
y: 0xa8a7d469,
z: 0x97830e05,
w: 0x113ba7bb,
}
DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
}
fn next(&mut self) -> u32 {

View File

@ -102,7 +102,6 @@ fn test_split_off() {
assert_eq!(m.back(), Some(&1));
assert_eq!(m.front(), Some(&1));
}
}
#[test]
@ -305,8 +304,7 @@ fn test_show() {
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();
assert_eq!(format!("{:?}", list),
"[\"just\", \"one\", \"test\", \"more\"]");
assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
}
#[test]
@ -446,19 +444,14 @@ fn drain_filter_true() {
#[test]
fn drain_filter_complex() {
{ // [+xxx++++++xxxxx++++x+x++]
{
// [+xxx++++++xxxxx++++x+x++]
let mut list = vec![
1,
2, 4, 6,
7, 9, 11, 13, 15, 17,
18, 20, 22, 24, 26,
27, 29, 31, 33,
34,
35,
36,
37, 39
].into_iter().collect::<LinkedList<_>>();
1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37,
39,
]
.into_iter()
.collect::<LinkedList<_>>();
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
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![
2, 4, 6,
7, 9, 11, 13, 15, 17,
18, 20, 22, 24, 26,
27, 29, 31, 33,
34,
35,
36,
37, 39
].into_iter().collect::<LinkedList<_>>();
2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39,
]
.into_iter()
.collect::<LinkedList<_>>();
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
assert_eq!(removed.len(), 10);
@ -494,16 +483,12 @@ fn drain_filter_complex() {
);
}
{ // [xxx++++++xxxxx++++x+x]
let mut list = vec![
2, 4, 6,
7, 9, 11, 13, 15, 17,
18, 20, 22, 24, 26,
27, 29, 31, 33,
34,
35,
36
].into_iter().collect::<LinkedList<_>>();
{
// [xxx++++++xxxxx++++x+x]
let mut list =
vec![2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]
.into_iter()
.collect::<LinkedList<_>>();
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
assert_eq!(removed.len(), 10);
@ -516,11 +501,11 @@ fn drain_filter_complex() {
);
}
{ // [xxxxxxxxxx+++++++++++]
let mut list = vec![
2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
1, 3, 5, 7, 9, 11, 13, 15, 17, 19
].into_iter().collect::<LinkedList<_>>();
{
// [xxxxxxxxxx+++++++++++]
let mut list = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
.into_iter()
.collect::<LinkedList<_>>();
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
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]);
}
{ // [+++++++++++xxxxxxxxxx]
let mut list = vec![
1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
2, 4, 6, 8, 10, 12, 14, 16, 18, 20
].into_iter().collect::<LinkedList<_>>();
{
// [+++++++++++xxxxxxxxxx]
let mut list = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
.into_iter()
.collect::<LinkedList<_>>();
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
assert_eq!(removed.len(), 10);

View File

@ -1,9 +1,9 @@
use std::any::Any;
use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::cmp::PartialEq;
use std::mem;
use std::iter::TrustedLen;
use std::mem;
use std::rc::{Rc, Weak};
#[test]
fn uninhabited() {
@ -12,7 +12,7 @@ fn uninhabited() {
a = a.clone();
assert!(a.upgrade().is_none());
let mut a: Weak<dyn Any> = a; // Unsizing
let mut a: Weak<dyn Any> = a; // Unsizing
a = a.clone();
assert!(a.upgrade().is_none());
}
@ -20,8 +20,8 @@ fn uninhabited() {
#[test]
fn slice() {
let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
let a: Rc<[u32]> = a; // Unsizing
let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
let a: Rc<[u32]> = a; // Unsizing
let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
assert_eq!(a, b);
// Exercise is_dangling() with a DST
@ -33,7 +33,7 @@ fn slice() {
#[test]
fn trait_object() {
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
let mut a = Rc::downgrade(&a);
@ -43,7 +43,7 @@ fn trait_object() {
let mut b = Weak::<u32>::new();
b = b.clone();
assert!(b.upgrade().is_none());
let mut b: Weak<dyn Any> = b; // Unsizing
let mut b: Weak<dyn Any> = b; // Unsizing
b = b.clone();
assert!(b.upgrade().is_none());
}
@ -57,7 +57,7 @@ fn float_nan_ne() {
#[test]
fn partial_eq() {
struct TestPEq (RefCell<usize>);
struct TestPEq(RefCell<usize>);
impl PartialEq for TestPEq {
fn eq(&self, other: &TestPEq) -> bool {
*self.0.borrow_mut() += 1;
@ -74,7 +74,7 @@ fn partial_eq() {
#[test]
fn eq() {
#[derive(Eq)]
struct TestEq (RefCell<usize>);
struct TestEq(RefCell<usize>);
impl PartialEq for TestEq {
fn eq(&self, other: &TestEq) -> bool {
*self.0.borrow_mut() += 1;
@ -156,13 +156,10 @@ fn shared_from_iter_trustedlen_normal() {
fn shared_from_iter_trustedlen_panic() {
// Exercise the `TrustedLen` implementation when `size_hint()` matches
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
let iter = (0..SHARED_ITER_MAX)
.map(|val| {
match val {
98 => panic!("I've almost got 99 problems."),
_ => Box::new(val),
}
});
let iter = (0..SHARED_ITER_MAX).map(|val| match val {
98 => panic!("I've almost got 99 problems."),
_ => Box::new(val),
});
assert_trusted_len(&iter);
let _ = iter.collect::<Rc<[_]>>();
@ -189,16 +186,8 @@ fn shared_from_iter_trustedlen_no_fuse() {
}
}
let vec = vec![
Some(Box::new(42)),
Some(Box::new(24)),
None,
Some(Box::new(12)),
];
let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))];
let iter = Iter(vec.into_iter());
assert_trusted_len(&iter);
assert_eq!(
&[Box::new(42), Box::new(24)],
&*iter.collect::<Rc<[_]>>()
);
assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>());
}

View File

@ -4,7 +4,6 @@ use std::mem;
use std::panic;
use std::rc::Rc;
use std::sync::atomic::{Ordering::Relaxed, AtomicUsize};
use std::thread;
use rand::{Rng, RngCore, thread_rng};
use rand::seq::SliceRandom;
@ -1406,11 +1405,9 @@ fn test_box_slice_clone() {
#[test]
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg(not(miri))] // Miri does not support threads
fn test_box_slice_clone_panics() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread::spawn;
struct Canary {
count: Arc<AtomicUsize>,
@ -1446,7 +1443,7 @@ fn test_box_slice_clone_panics() {
panics: true,
};
spawn(move || {
std::panic::catch_unwind(move || {
// When xs is dropped, +5.
let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
.into_boxed_slice();
@ -1454,7 +1451,6 @@ fn test_box_slice_clone_panics() {
// When panic is cloned, +3.
xs.clone();
})
.join()
.unwrap_err();
// Total = 8
@ -1566,7 +1562,7 @@ macro_rules! test {
}
let v = $input.to_owned();
let _ = thread::spawn(move || {
let _ = std::panic::catch_unwind(move || {
let mut v = v;
let mut panic_countdown = panic_countdown;
v.$func(|a, b| {
@ -1577,7 +1573,7 @@ macro_rules! test {
panic_countdown -= 1;
a.cmp(b)
})
}).join();
});
// Check that the number of things dropped is exactly
// what we expect (i.e., the contents of `v`).
@ -1598,7 +1594,6 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
#[test]
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
#[cfg(not(miri))] // Miri does not support threads
fn panic_safe() {
let prev = panic::take_hook();
panic::set_hook(Box::new(move |info| {
@ -1609,8 +1604,18 @@ fn panic_safe() {
let mut rng = thread_rng();
for len in (1..20).chain(70..MAX_LEN) {
for &modulus in &[5, 20, 50] {
#[cfg(not(miri))] // Miri is too slow
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] {
let mut input = (0..len)
.map(|id| {
@ -1643,6 +1648,9 @@ fn panic_safe() {
}
}
}
// Set default panic hook again.
drop(panic::take_hook());
}
#[test]

View File

@ -944,10 +944,9 @@ fn drain_filter_complex() {
}
}
// Miri does not support catching panics
// FIXME: re-enable emscripten once it can unwind again
#[test]
#[cfg(not(any(miri, target_os = "emscripten")))]
#[cfg(not(target_os = "emscripten"))]
fn drain_filter_consumed_panic() {
use std::rc::Rc;
use std::sync::Mutex;
@ -999,7 +998,7 @@ fn drain_filter_consumed_panic() {
// FIXME: Re-enable emscripten once it can catch panics
#[test]
#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
#[cfg(not(target_os = "emscripten"))]
fn drain_filter_unconsumed_panic() {
use std::rc::Rc;
use std::sync::Mutex;

View File

@ -1,8 +1,8 @@
use std::fmt::Debug;
use std::collections::{VecDeque, vec_deque::Drain};
use std::collections::TryReserveError::*;
use std::collections::{vec_deque::Drain, VecDeque};
use std::fmt::Debug;
use std::mem::size_of;
use std::{usize, isize};
use std::{isize, usize};
use crate::hash;
@ -148,34 +148,20 @@ fn test_param_taggy() {
#[test]
fn test_param_taggypar() {
test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
Twopar::<i32>(1, 2),
Threepar::<i32>(1, 2, 3),
Twopar::<i32>(17, 42));
test_parameterized::<Taggypar<i32>>(
Onepar::<i32>(1),
Twopar::<i32>(1, 2),
Threepar::<i32>(1, 2, 3),
Twopar::<i32>(17, 42),
);
}
#[test]
fn test_param_reccy() {
let reccy1 = RecCy {
x: 1,
y: 2,
t: One(1),
};
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),
};
let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
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);
}
@ -320,8 +306,7 @@ fn test_mut_rev_iter_wrap() {
assert_eq!(d.pop_front(), Some(1));
d.push_back(4);
assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<_>>(),
vec![4, 3, 2]);
assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<_>>(), vec![4, 3, 2]);
}
#[test]
@ -372,7 +357,6 @@ fn test_mut_rev_iter() {
#[test]
fn test_into_iter() {
// Empty iter
{
let d: VecDeque<i32> = VecDeque::new();
@ -431,7 +415,6 @@ fn test_into_iter() {
#[test]
fn test_drain() {
// Empty iter
{
let mut d: VecDeque<i32> = VecDeque::new();
@ -650,12 +633,8 @@ fn test_show() {
let ringbuf: VecDeque<_> = (0..10).collect();
assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"]
.iter()
.cloned()
.collect();
assert_eq!(format!("{:?}", ringbuf),
"[\"just\", \"one\", \"test\", \"more\"]");
let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]");
}
#[test]
@ -955,7 +934,6 @@ fn test_append_permutations() {
// doesn't pop more values than are pushed
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) {
let src = construct_vec_deque(
src_push_back,
src_pop_back,
@ -966,8 +944,8 @@ fn test_append_permutations() {
for dst_push_back 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_front
in 0..(dst_push_back + dst_push_front - dst_pop_back)
for dst_pop_front in
0..(dst_push_back + dst_push_front - dst_pop_back)
{
let mut dst = construct_vec_deque(
dst_push_back,
@ -1124,7 +1102,6 @@ fn test_reserve_exact_2() {
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
// * > isize::MAX should always fail
@ -1158,22 +1135,27 @@ fn test_try_reserve() {
if guards_against_isize {
// Check isize::MAX + 1 does count as overflow
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
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 {
// Check isize::MAX is an OOM
// 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
// furthest we can go without triggering CapacityOverflow
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
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 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 {
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
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
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!");
}
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!");
}
if guards_against_isize {
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
} else {
panic!("isize::MAX + 1 should trigger an overflow!");
}
} else {
if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
} else {
panic!("isize::MAX + 1 should trigger an OOM!")
}
}
// Should fail in the mul-by-size
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!");
}
}
}
#[test]
#[cfg(not(miri))] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
// See that test for comments.
@ -1247,21 +1236,26 @@ fn test_try_reserve_exact() {
if guards_against_isize {
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) {
} else { panic!("usize::MAX should trigger an overflow!") }
} else {
panic!("usize::MAX should trigger an overflow!")
}
} else {
// Check isize::MAX is an OOM
// 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
// furthest we can go without triggering CapacityOverflow
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();
@ -1273,36 +1267,46 @@ fn test_try_reserve_exact() {
}
if guards_against_isize {
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 {
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) {
} 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();
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!");
}
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!");
}
if guards_against_isize {
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
} else { panic!("isize::MAX + 1 should trigger an overflow!"); }
if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
} else {
panic!("isize::MAX + 1 should trigger an overflow!");
}
} else {
if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
} else { panic!("isize::MAX + 1 should trigger an OOM!") }
if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
} else {
panic!("isize::MAX + 1 should trigger an OOM!")
}
}
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]
@ -1404,9 +1408,8 @@ fn test_rotate_right_parts() {
#[test]
fn test_rotate_left_random() {
let shifts = [
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, 12, 9, 11, 1, 7, 9, 7, 2,
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,
12, 9, 11, 1, 7, 9, 7, 2,
];
let n = 12;
let mut v: VecDeque<_> = (0..n).collect();
@ -1423,9 +1426,8 @@ fn test_rotate_left_random() {
#[test]
fn test_rotate_right_random() {
let shifts = [
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, 12, 9, 11, 1, 7, 9, 7, 2,
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,
12, 9, 11, 1, 7, 9, 7, 2,
];
let n = 12;
let mut v: VecDeque<_> = (0..n).collect();
@ -1447,8 +1449,7 @@ fn test_try_fold_empty() {
#[test]
fn test_try_fold_none() {
let v: VecDeque<u32> = (0..12).collect();
assert_eq!(None, v.into_iter().try_fold(0, |a, b|
if b < 11 { Some(a + b) } else { None }));
assert_eq!(None, v.into_iter().try_fold(0, |a, b| if b < 11 { Some(a + b) } else { None }));
}
#[test]
@ -1463,7 +1464,6 @@ fn test_try_fold_unit() {
assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(())));
}
#[test]
fn test_try_fold_unit_none() {
let v: std::collections::VecDeque<()> = [(); 10].iter().cloned().collect();
@ -1534,7 +1534,7 @@ fn test_try_rfold_rotated() {
#[test]
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();
assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None);
assert_eq!(iter.next_back(), Some(&70));

View File

@ -44,14 +44,14 @@ CloneTypeFoldableImpls! {
pub type ConstEvalRawResult<'tcx> = Result<RawConst<'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 span: Span,
pub error: crate::mir::interpret::InterpError<'tcx>,
pub stacktrace: Vec<FrameInfo<'tcx>>,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug)]
pub struct FrameInfo<'tcx> {
/// This span is in the caller.
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
/// 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.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, HashStable)]
pub enum InvalidProgramInfo<'tcx> {
/// Resolution can fail if we are in a too generic context.
TooGeneric,
@ -361,7 +361,7 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> {
}
/// Error information for when the program caused Undefined Behavior.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, HashStable)]
pub enum UndefinedBehaviorInfo {
/// Free-form case. Only for errors that are never caught!
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
/// categorized yet.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, HashStable)]
pub enum UnsupportedOpInfo<'tcx> {
/// Free-form case. Only for errors that are never caught!
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 --
FunctionAbiMismatch(Abi, Abi),
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
@ -559,13 +563,15 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
not a power of two"),
Unsupported(ref 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
/// by the interpreter.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, HashStable)]
pub enum ResourceExhaustionInfo {
/// The stack grew too big.
StackFrameLimitReached,
@ -586,7 +592,7 @@ impl fmt::Debug for ResourceExhaustionInfo {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, HashStable)]
pub enum InterpError<'tcx> {
/// The program panicked.
Panic(PanicInfo<u64>),

View File

@ -94,9 +94,6 @@ pub struct Session {
/// The maximum length of types during monomorphization.
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
/// the localized span for the macro body) to the
/// macro name and definition span in the source crate.
@ -1158,7 +1155,6 @@ fn build_session_(
features: Once::new(),
recursion_limit: Once::new(),
type_length_limit: Once::new(),
const_eval_stack_frame_limit: 100,
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
cgu_reuse_tracker,

View File

@ -69,7 +69,7 @@ pub enum BoundRegion {
impl BoundRegion {
pub fn is_named(&self) -> bool {
match *self {
BoundRegion::BrNamed(..) => true,
BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
_ => false,
}
}

View File

@ -41,7 +41,7 @@ use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorRe
use rustc_metadata::locator;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use errors::{PResult, registry::Registry};
use rustc_interface::interface;
use rustc_interface::{interface, Queries};
use rustc_interface::util::get_codegen_sysroot;
use rustc_data_structures::sync::SeqCst;
use rustc_feature::{find_gated_cfg, UnstableFeatures};
@ -98,17 +98,29 @@ pub trait Callbacks {
fn config(&mut self, _config: &mut interface::Config) {}
/// Called after parsing. Return value instructs the compiler whether to
/// 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
}
/// Called after expansion. Return value instructs the compiler whether to
/// 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
}
/// Called after analysis. Return value instructs the compiler whether to
/// 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
}
}
@ -312,7 +324,7 @@ pub fn run_compiler(
return early_exit();
}
if callbacks.after_parsing(compiler) == Compilation::Stop {
if callbacks.after_parsing(compiler, queries) == Compilation::Stop {
return early_exit();
}
@ -333,7 +345,7 @@ pub fn run_compiler(
}
queries.expansion()?;
if callbacks.after_expansion(compiler) == Compilation::Stop {
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
return early_exit();
}
@ -382,7 +394,7 @@ pub fn run_compiler(
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();
}

View File

@ -107,6 +107,7 @@ E0199: include_str!("./error_codes/E0199.md"),
E0200: include_str!("./error_codes/E0200.md"),
E0201: include_str!("./error_codes/E0201.md"),
E0202: include_str!("./error_codes/E0202.md"),
E0203: include_str!("./error_codes/E0203.md"),
E0204: include_str!("./error_codes/E0204.md"),
E0205: include_str!("./error_codes/E0205.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
// E0194, // merged into E0403
// E0196, // cannot determine a type for this closure
E0203, // type parameter has more than one relaxed default bound,
// and only one is supported
E0208,
// E0209, // builtin traits can only be implemented on structs or enums
E0212, // cannot extract an associated type from a higher-ranked trait bound

View File

@ -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
}
```

View File

@ -18,6 +18,7 @@ pub mod util;
mod proc_macro_decls;
pub use interface::{run_compiler, Config};
pub use queries::Queries;
#[cfg(test)]
mod tests;

View File

@ -78,17 +78,7 @@ impl OutlivesSuggestionBuilder<'a> {
match name.source {
RegionNameSource::NamedEarlyBoundRegion(..)
| RegionNameSource::NamedFreeRegion(..)
| RegionNameSource::Static => {
// 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
}
}
| RegionNameSource::Static => true,
// Don't give suggestions for upvars, closure return types, or other unnamable
// regions.
@ -98,7 +88,8 @@ impl OutlivesSuggestionBuilder<'a> {
| RegionNameSource::MatchedAdtAndSegment(..)
| RegionNameSource::AnonRegionFromUpvar(..)
| RegionNameSource::AnonRegionFromOutput(..)
| RegionNameSource::AnonRegionFromYieldTy(..) => {
| RegionNameSource::AnonRegionFromYieldTy(..)
| RegionNameSource::AnonRegionFromAsyncFn(..) => {
debug!("Region {:?} is NOT suggestable", name);
false
}

View File

@ -13,13 +13,13 @@ use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::{Local, Body};
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_index::vec::IndexVec;
use rustc_errors::DiagnosticBuilder;
use syntax::symbol::kw;
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
/// 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),
/// The region corresponding to the return type of a closure.
AnonRegionFromOutput(Span, String, String),
/// The region from a type yielded by a generator.
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
@ -113,14 +116,11 @@ impl RegionName {
RegionNameSource::MatchedAdtAndSegment(..) |
RegionNameSource::AnonRegionFromUpvar(..) |
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<'_>) {
match &self.source {
RegionNameSource::NamedFreeRegion(span)
@ -137,7 +137,8 @@ impl RegionName {
RegionNameSource::CannotMatchHirTy(span, type_name) => {
diag.span_label(*span, format!("has type `{}`", type_name));
}
RegionNameSource::MatchedHirTy(span) => {
RegionNameSource::MatchedHirTy(span) |
RegionNameSource::AnonRegionFromAsyncFn(span) => {
diag.span_label(
*span,
format!("let's call the lifetime of this reference `{}`", self),
@ -270,7 +271,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
match error_region {
ty::ReEarlyBound(ebr) => {
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 {
name: ebr.name,
source: RegionNameSource::NamedEarlyBoundRegion(span),
@ -286,12 +287,30 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}),
ty::ReFree(free_region) => match free_region.bound_region {
ty::BoundRegion::BrNamed(_, name) => {
let span = self.get_named_span(tcx, error_region, name);
Some(RegionName {
name,
source: RegionNameSource::NamedFreeRegion(span),
})
ty::BoundRegion::BrNamed(region_def_id, name) => {
// Get the span to point to, even if we don't use the name.
let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP);
debug!("bound region named: {:?}, is_named: {:?}",
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 => {
@ -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
/// elaborated type, returning something like `'1`. Result looks
/// like:

View File

@ -548,7 +548,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
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)
} else {
Ok(())

View File

@ -560,7 +560,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
trace!("visit_statement: statement={:?} location={:?}", statement, location);
match statement.kind {
StatementKind::Assign(..) => {
StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } => {
self.super_statement(statement, location);
}
StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => {
@ -568,7 +568,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
}
// FIXME(eddyb) should these really do nothing?
StatementKind::FakeRead(..) |
StatementKind::SetDiscriminant { .. } |
StatementKind::StorageLive(_) |
StatementKind::StorageDead(_) |
StatementKind::InlineAsm {..} |

View File

@ -168,14 +168,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
_unwind: Option<BasicBlock>
) -> 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(
_mem: &Memory<'mir, 'tcx, Self>,
_ptr: Pointer,
) -> 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(
@ -185,7 +185,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
_right: ImmTy<'tcx>,
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
// 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(
@ -218,7 +219,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_dest: PlaceTy<'tcx>,
) -> InterpResult<'tcx> {
throw_unsup_format!("can't const prop `box` keyword");
throw_unsup!(ConstPropUnsupported("can't const prop `box` keyword"));
}
fn access_local(
@ -229,7 +230,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
let l = &frame.locals[local];
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()
@ -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
// the memory behind that in the future), then we can't const prop it
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(())
@ -389,9 +390,26 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let r = match f(self) {
Ok(val) => Some(val),
Err(error) => {
use rustc::mir::interpret::InterpError::*;
use rustc::mir::interpret::{
UnsupportedOpInfo,
UndefinedBehaviorInfo,
InterpError::*
};
match error.kind {
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(_)
| UndefinedBehavior(_)
| InvalidProgram(_)

View File

@ -225,7 +225,7 @@ fn check_statement(
StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
// just an assignment
StatementKind::SetDiscriminant { .. } => Ok(()),
StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body),
| StatementKind::InlineAsm { .. } => {
Err((span, "cannot use inline assembly in const fn".into()))

View File

@ -37,22 +37,30 @@ pub fn calc_result<'a>(
let result = match (&desc.should_panic, task_result) {
(&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
(&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
if err
let maybe_panic_str = err
.downcast_ref::<String>()
.map(|e| &**e)
.or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
.map(|e| e.contains(msg))
.unwrap_or(false)
{
.or_else(|| err.downcast_ref::<&'static str>().map(|e| *e));
if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
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 {
if desc.allow_fail {
TestResult::TrAllowedFail
} else {
TestResult::TrFailedMsg(
format!("panic did not include expected string '{}'", msg)
)
}
TestResult::TrFailedMsg(format!(
r#"expected panic with string value,
found non-string value: `{:?}`
expected substring: `{:?}`"#,
(**err).type_id(),
msg
))
}
}
(&ShouldPanic::Yes, Ok(())) => {

View File

@ -15,6 +15,7 @@ use crate::{
// TestType, TrFailedMsg, TrIgnored, TrOk,
},
};
use std::any::TypeId;
use std::sync::mpsc::channel;
use std::time::Duration;
@ -84,7 +85,7 @@ pub fn do_not_run_ignored_tests() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
let result = rx.recv().unwrap().result;
assert!(result != TrOk);
assert_ne!(result, TrOk);
}
#[test]
@ -103,7 +104,7 @@ pub fn ignored_tests_result_in_ignored() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
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)
@ -126,7 +127,7 @@ fn test_should_panic() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
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)
@ -149,7 +150,7 @@ fn test_should_panic_good_message() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
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)
@ -161,7 +162,9 @@ fn test_should_panic_bad_message() {
panic!("an error message");
}
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 {
desc: TestDesc {
name: StaticTestName("whatever"),
@ -175,7 +178,35 @@ fn test_should_panic_bad_message() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
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)
@ -196,7 +227,7 @@ fn test_should_panic_but_succeeds() {
let (tx, rx) = channel();
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
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> {
@ -570,7 +601,7 @@ pub fn sort_tests() {
];
for (a, b) in expected.iter().zip(filtered) {
assert!(*a == b.desc.name.to_string());
assert_eq!(*a, b.desc.name.to_string());
}
}

View File

@ -12,12 +12,12 @@ error: lifetime may not live long enough
LL | async fn do_sth<'a>(
| -- lifetime `'a` defined here
LL | &'a self, foo: &dyn Foo
| - lifetime `'_` defined here
| - let's call the lifetime of this reference `'1`
LL | ) -> &dyn Foo
LL | / {
LL | | foo
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

View File

@ -42,3 +42,4 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0203`.

View File

@ -2,11 +2,11 @@ error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
|
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 }
| ^^^^^^^^^^^^^^^

View File

@ -10,19 +10,19 @@ error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
|
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 `'_`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
| | |
| | let's call the lifetime of this reference `'1`
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
--> $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) }
| - ^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
| | |
| | let's call the lifetime of this reference `'1`
| let's call the lifetime of this reference `'2`
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
@ -36,8 +36,9 @@ error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
|
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
error: aborting due to 5 previous errors

View File

@ -10,12 +10,11 @@ error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:13:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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

View File

@ -10,12 +10,11 @@ error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:13:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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

View File

@ -10,12 +10,11 @@ error: lifetime may not live long enough
--> $DIR/ref-mut-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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

View File

@ -10,12 +10,11 @@ error: lifetime may not live long enough
--> $DIR/ref-struct-async.rs:13:9
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| -
| - - let's call the lifetime of this reference `'1`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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
--> $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
|
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
| lifetime `'_` defined here
| let's call the lifetime of this reference `'2`
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