Auto merge of #94350 - matthiaskrgr:rollup-eesfiyr, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #92714 (Provide ignore message in the result of test) - #93273 (Always check cg_llvm with ./x.py check) - #94068 (Consider mutations as borrows in generator drop tracking) - #94184 (BTree: simplify test code) - #94297 (update const_generics_defaults release notes) - #94341 (Remove a duplicate space) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
03c8ffaacb
18 changed files with 354 additions and 148 deletions
19
RELEASES.md
19
RELEASES.md
|
@ -4,7 +4,7 @@ Version 1.59.0 (2022-02-24)
|
|||
Language
|
||||
--------
|
||||
|
||||
- [Stabilize default arguments for const generics][90207]
|
||||
- [Stabilize default arguments for const parameters and remove the ordering restriction for type and const parameters][90207]
|
||||
- [Stabilize destructuring assignment][90521]
|
||||
- [Relax private in public lint on generic bounds and where clauses of trait impls][90586]
|
||||
- [Stabilize asm! and global_asm! for x86, x86_64, ARM, Aarch64, and RISC-V][91728]
|
||||
|
@ -18,6 +18,21 @@ Compiler
|
|||
- [Warn when a `#[test]`-like built-in attribute macro is present multiple times.][91172]
|
||||
- [Add support for riscv64gc-unknown-freebsd][91284]
|
||||
- [Stabilize `-Z emit-future-incompat` as `--json future-incompat`][91535]
|
||||
- [Soft disable incremental compilation][94124]
|
||||
|
||||
This release disables incremental compilation, unless the user has explicitly
|
||||
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.
|
||||
This is due to a known and relatively frequently occurring bug in incremental
|
||||
compilation, which causes builds to issue internal compiler errors. This
|
||||
particular bug is already fixed on nightly, but that fix has not yet rolled out
|
||||
to stable and is deemed too risky for a direct stable backport.
|
||||
|
||||
As always, we encourage users to test with nightly and report bugs so that we
|
||||
can track failures and fix issues earlier.
|
||||
|
||||
See [94124] for more details.
|
||||
|
||||
[94124]: https://github.com/rust-lang/rust/issues/94124
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
@ -86,6 +101,7 @@ Compatibility Notes
|
|||
- [Weaken guarantee around advancing underlying iterators in zip][83791]
|
||||
- [Make split_inclusive() on an empty slice yield an empty output][89825]
|
||||
- [Update std::env::temp_dir to use GetTempPath2 on Windows when available.][89999]
|
||||
- [unreachable! was updated to match other formatting macro behavior on Rust 2021][92137]
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
@ -127,6 +143,7 @@ and related tools.
|
|||
[91984]: https://github.com/rust-lang/rust/pull/91984/
|
||||
[92020]: https://github.com/rust-lang/rust/pull/92020/
|
||||
[92034]: https://github.com/rust-lang/rust/pull/92034/
|
||||
[92137]: https://github.com/rust-lang/rust/pull/92137/
|
||||
[92483]: https://github.com/rust-lang/rust/pull/92483/
|
||||
[cargo/10088]: https://github.com/rust-lang/cargo/pull/10088/
|
||||
[cargo/10133]: https://github.com/rust-lang/cargo/pull/10133/
|
||||
|
|
|
@ -262,6 +262,15 @@ pub fn expand_test_or_bench(
|
|||
"ignore",
|
||||
cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
|
||||
),
|
||||
// ignore_message: Some("...") | None
|
||||
field(
|
||||
"ignore_message",
|
||||
if let Some(msg) = should_ignore_message(cx, &item) {
|
||||
cx.expr_some(sp, cx.expr_str(sp, msg))
|
||||
} else {
|
||||
cx.expr_none(sp)
|
||||
},
|
||||
),
|
||||
// compile_fail: true | false
|
||||
field("compile_fail", cx.expr_bool(sp, false)),
|
||||
// no_run: true | false
|
||||
|
@ -364,6 +373,20 @@ fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
|
|||
sess.contains_name(&i.attrs, sym::ignore)
|
||||
}
|
||||
|
||||
fn should_ignore_message(cx: &ExtCtxt<'_>, i: &ast::Item) -> Option<Symbol> {
|
||||
match cx.sess.find_by_name(&i.attrs, sym::ignore) {
|
||||
Some(attr) => {
|
||||
match attr.meta_item_list() {
|
||||
// Handle #[ignore(bar = "foo")]
|
||||
Some(_) => None,
|
||||
// Handle #[ignore] and #[ignore = "message"]
|
||||
None => attr.value_str(),
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
|
||||
match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
|
||||
Some(attr) => {
|
||||
|
|
|
@ -329,6 +329,10 @@ impl<'a> ExtCtxt<'a> {
|
|||
self.expr_call_global(sp, some, vec![expr])
|
||||
}
|
||||
|
||||
pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
|
||||
let none = self.std_path(&[sym::option, sym::Option, sym::None]);
|
||||
self.expr_path(self.path_global(sp, none))
|
||||
}
|
||||
pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
|
||||
self.expr(sp, ast::ExprKind::Tup(exprs))
|
||||
}
|
||||
|
|
|
@ -633,7 +633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
})
|
||||
.collect::<Result<Vec<_>, _>>();
|
||||
|
||||
let Ok(where_predicates) = where_predicates else { return };
|
||||
let Ok(where_predicates) = where_predicates else { return };
|
||||
|
||||
// now get all predicates in the same types as the where bounds, so we can chain them
|
||||
let predicates_from_where =
|
||||
|
|
|
@ -93,9 +93,10 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
|||
fn borrow(
|
||||
&mut self,
|
||||
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
_diag_expr_id: HirId,
|
||||
diag_expr_id: HirId,
|
||||
_bk: rustc_middle::ty::BorrowKind,
|
||||
) {
|
||||
debug!("borrow {:?}; diag_expr_id={:?}", place_with_id, diag_expr_id);
|
||||
self.places
|
||||
.borrowed
|
||||
.insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
|
||||
|
@ -103,9 +104,14 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
|
|||
|
||||
fn mutate(
|
||||
&mut self,
|
||||
_assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
_diag_expr_id: HirId,
|
||||
assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
diag_expr_id: HirId,
|
||||
) {
|
||||
debug!("mutate {:?}; diag_expr_id={:?}", assignee_place, diag_expr_id);
|
||||
// Count mutations as a borrow.
|
||||
self.places
|
||||
.borrowed
|
||||
.insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
|
||||
}
|
||||
|
||||
fn fake_read(
|
||||
|
|
|
@ -17,14 +17,10 @@ use std::ops::RangeBounds;
|
|||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
|
||||
// Capacity of a tree with a single level,
|
||||
// i.e., a tree who's root is a leaf node at height 0.
|
||||
const NODE_CAPACITY: usize = node::CAPACITY;
|
||||
|
||||
// Minimum number of elements to insert, to guarantee a tree with 2 levels,
|
||||
// i.e., a tree who's root is an internal node at height 1, with edges to leaf nodes.
|
||||
// It's not the minimum size: removing an element from such a tree does not always reduce height.
|
||||
const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1;
|
||||
const MIN_INSERTS_HEIGHT_1: usize = node::CAPACITY + 1;
|
||||
|
||||
// Minimum number of elements to insert in ascending order, to guarantee a tree with 3 levels,
|
||||
// i.e., a tree who's root is an internal node at height 2, with edges to more internal nodes.
|
||||
|
@ -180,7 +176,7 @@ fn test_levels() {
|
|||
#[should_panic]
|
||||
fn test_check_ord_chaos() {
|
||||
let gov = Governor::new();
|
||||
let map: BTreeMap<_, _> = (0..2).map(|i| (Governed(i, &gov), ())).collect();
|
||||
let map = BTreeMap::from([(Governed(1, &gov), ()), (Governed(2, &gov), ())]);
|
||||
gov.flip();
|
||||
map.check();
|
||||
}
|
||||
|
@ -189,7 +185,7 @@ fn test_check_ord_chaos() {
|
|||
#[test]
|
||||
fn test_check_invariants_ord_chaos() {
|
||||
let gov = Governor::new();
|
||||
let map: BTreeMap<_, _> = (0..2).map(|i| (Governed(i, &gov), ())).collect();
|
||||
let map = BTreeMap::from([(Governed(1, &gov), ()), (Governed(2, &gov), ())]);
|
||||
gov.flip();
|
||||
map.check_invariants();
|
||||
}
|
||||
|
@ -337,8 +333,7 @@ fn test_basic_small() {
|
|||
fn test_iter() {
|
||||
// Miri is too slow
|
||||
let size = if cfg!(miri) { 200 } else { 10000 };
|
||||
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
fn test<T>(size: usize, mut iter: T)
|
||||
where
|
||||
|
@ -360,8 +355,7 @@ fn test_iter() {
|
|||
fn test_iter_rev() {
|
||||
// Miri is too slow
|
||||
let size = if cfg!(miri) { 200 } else { 10000 };
|
||||
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
fn test<T>(size: usize, mut iter: T)
|
||||
where
|
||||
|
@ -386,7 +380,7 @@ where
|
|||
<T as TryFrom<usize>>::Error: Debug,
|
||||
{
|
||||
let zero = T::try_from(0).unwrap();
|
||||
let mut map: BTreeMap<T, T> = (0..size).map(|i| (T::try_from(i).unwrap(), zero)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (T::try_from(i).unwrap(), zero)));
|
||||
|
||||
// Forward and backward iteration sees enough pairs (also tested elsewhere)
|
||||
assert_eq!(map.iter_mut().count(), size);
|
||||
|
@ -452,7 +446,7 @@ fn test_iter_mut_mutation() {
|
|||
|
||||
#[test]
|
||||
fn test_values_mut() {
|
||||
let mut a: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect();
|
||||
let mut a = BTreeMap::from_iter((0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)));
|
||||
test_all_refs(&mut 13, a.values_mut());
|
||||
a.check();
|
||||
}
|
||||
|
@ -467,14 +461,14 @@ fn test_values_mut_mutation() {
|
|||
value.push_str("!");
|
||||
}
|
||||
|
||||
let values: Vec<String> = a.values().cloned().collect();
|
||||
let values = Vec::from_iter(a.values().cloned());
|
||||
assert_eq!(values, [String::from("hello!"), String::from("goodbye!")]);
|
||||
a.check();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter_entering_root_twice() {
|
||||
let mut map: BTreeMap<_, _> = (0..2).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from([(0, 0), (1, 1)]);
|
||||
let mut it = map.iter_mut();
|
||||
let front = it.next().unwrap();
|
||||
let back = it.next_back().unwrap();
|
||||
|
@ -491,7 +485,7 @@ fn test_iter_entering_root_twice() {
|
|||
|
||||
#[test]
|
||||
fn test_iter_descending_to_same_node_twice() {
|
||||
let mut map: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)));
|
||||
let mut it = map.iter_mut();
|
||||
// Descend into first child.
|
||||
let front = it.next().unwrap();
|
||||
|
@ -509,7 +503,7 @@ fn test_iter_mixed() {
|
|||
// Miri is too slow
|
||||
let size = if cfg!(miri) { 200 } else { 10000 };
|
||||
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
fn test<T>(size: usize, mut iter: T)
|
||||
where
|
||||
|
@ -569,21 +563,19 @@ fn test_iter_min_max() {
|
|||
}
|
||||
|
||||
fn range_keys(map: &BTreeMap<i32, i32>, range: impl RangeBounds<i32>) -> Vec<i32> {
|
||||
map.range(range)
|
||||
.map(|(&k, &v)| {
|
||||
assert_eq!(k, v);
|
||||
k
|
||||
})
|
||||
.collect()
|
||||
Vec::from_iter(map.range(range).map(|(&k, &v)| {
|
||||
assert_eq!(k, v);
|
||||
k
|
||||
}))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_small() {
|
||||
let size = 4;
|
||||
|
||||
let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect();
|
||||
let all: Vec<_> = (1..=size).collect();
|
||||
let all = Vec::from_iter(1..=size);
|
||||
let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]);
|
||||
let map = BTreeMap::from_iter(all.iter().copied().map(|i| (i, i)));
|
||||
|
||||
assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all);
|
||||
assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all);
|
||||
|
@ -638,10 +630,9 @@ fn test_range_small() {
|
|||
|
||||
#[test]
|
||||
fn test_range_height_1() {
|
||||
// Tests tree with a root and 2 leaves. The single key in the root node is
|
||||
// close to the middle among the keys.
|
||||
|
||||
let map: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_1 as i32).map(|i| (i, i)).collect();
|
||||
// Tests tree with a root and 2 leaves. We test around the middle of the
|
||||
// keys because one of those is the single key in the root node.
|
||||
let map = BTreeMap::from_iter((0..MIN_INSERTS_HEIGHT_1 as i32).map(|i| (i, i)));
|
||||
let middle = MIN_INSERTS_HEIGHT_1 as i32 / 2;
|
||||
for root in middle - 2..=middle + 2 {
|
||||
assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]);
|
||||
|
@ -660,9 +651,9 @@ fn test_range_height_1() {
|
|||
fn test_range_large() {
|
||||
let size = 200;
|
||||
|
||||
let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect();
|
||||
let all: Vec<_> = (1..=size).collect();
|
||||
let all = Vec::from_iter(1..=size);
|
||||
let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]);
|
||||
let map = BTreeMap::from_iter(all.iter().copied().map(|i| (i, i)));
|
||||
|
||||
assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all);
|
||||
assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all);
|
||||
|
@ -715,9 +706,7 @@ fn test_range_large() {
|
|||
L: IntoIterator<Item = (&'a i32, &'a i32)>,
|
||||
R: IntoIterator<Item = (&'a i32, &'a i32)>,
|
||||
{
|
||||
let lhs: Vec<_> = lhs.into_iter().collect();
|
||||
let rhs: Vec<_> = rhs.into_iter().collect();
|
||||
assert_eq!(lhs, rhs);
|
||||
assert_eq!(Vec::from_iter(lhs), Vec::from_iter(rhs));
|
||||
}
|
||||
|
||||
check(map.range(..=100), map.range(..101));
|
||||
|
@ -728,14 +717,13 @@ fn test_range_large() {
|
|||
#[test]
|
||||
fn test_range_inclusive_max_value() {
|
||||
let max = usize::MAX;
|
||||
let map: BTreeMap<_, _> = [(max, 0)].into_iter().collect();
|
||||
|
||||
assert_eq!(map.range(max..=max).collect::<Vec<_>>(), &[(&max, &0)]);
|
||||
let map = BTreeMap::from([(max, 0)]);
|
||||
assert_eq!(Vec::from_iter(map.range(max..=max)), &[(&max, &0)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_equal_empty_cases() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
assert_eq!(map.range((Included(2), Excluded(2))).next(), None);
|
||||
assert_eq!(map.range((Excluded(2), Included(2))).next(), None);
|
||||
}
|
||||
|
@ -743,35 +731,35 @@ fn test_range_equal_empty_cases() {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
fn test_range_equal_excluded() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
let _ = map.range((Excluded(2), Excluded(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_range_backwards_1() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
let _ = map.range((Included(3), Included(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_range_backwards_2() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
let _ = map.range((Included(3), Excluded(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_range_backwards_3() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
let _ = map.range((Excluded(3), Included(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_range_backwards_4() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..5).map(|i| (i, i)));
|
||||
let _ = map.range((Excluded(3), Excluded(2)));
|
||||
}
|
||||
|
||||
|
@ -823,7 +811,7 @@ fn test_range_finding_ill_order_in_range_ord() {
|
|||
}
|
||||
}
|
||||
|
||||
let map = (0..12).map(|i| (CompositeKey(i, EvilTwin(i)), ())).collect::<BTreeMap<_, _>>();
|
||||
let map = BTreeMap::from_iter((0..12).map(|i| (CompositeKey(i, EvilTwin(i)), ())));
|
||||
let _ = map.range(EvilTwin(5)..=EvilTwin(7));
|
||||
}
|
||||
|
||||
|
@ -831,7 +819,7 @@ fn test_range_finding_ill_order_in_range_ord() {
|
|||
fn test_range_1000() {
|
||||
// Miri is too slow
|
||||
let size = if cfg!(miri) { MIN_INSERTS_HEIGHT_2 as u32 } else { 1000 };
|
||||
let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
|
||||
let mut kvs = map.range((min, max)).map(|(&k, &v)| (k, v));
|
||||
|
@ -870,7 +858,7 @@ fn test_range() {
|
|||
let size = 200;
|
||||
// Miri is too slow
|
||||
let step = if cfg!(miri) { 66 } else { 1 };
|
||||
let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
for i in (0..size).step_by(step) {
|
||||
for j in (i..size).step_by(step) {
|
||||
|
@ -891,7 +879,7 @@ fn test_range_mut() {
|
|||
let size = 200;
|
||||
// Miri is too slow
|
||||
let step = if cfg!(miri) { 66 } else { 1 };
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i, i)));
|
||||
|
||||
for i in (0..size).step_by(step) {
|
||||
for j in (i..size).step_by(step) {
|
||||
|
@ -910,7 +898,7 @@ fn test_range_mut() {
|
|||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
let mut map: BTreeMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..100).map(|x| (x, x * 10)));
|
||||
|
||||
map.retain(|&k, _| k % 2 == 0);
|
||||
assert_eq!(map.len(), 50);
|
||||
|
@ -934,7 +922,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn consumed_keeping_all() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
assert!(map.drain_filter(|_, _| false).eq(iter::empty()));
|
||||
map.check();
|
||||
}
|
||||
|
@ -943,7 +931,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn consumed_removing_all() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
assert!(map.drain_filter(|_, _| true).eq(pairs));
|
||||
assert!(map.is_empty());
|
||||
map.check();
|
||||
|
@ -953,7 +941,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn mutating_and_keeping() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
assert!(
|
||||
map.drain_filter(|_, v| {
|
||||
*v += 6;
|
||||
|
@ -970,7 +958,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn mutating_and_removing() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
assert!(
|
||||
map.drain_filter(|_, v| {
|
||||
*v += 6;
|
||||
|
@ -985,7 +973,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn underfull_keeping_all() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| false);
|
||||
assert!(map.keys().copied().eq(0..3));
|
||||
map.check();
|
||||
|
@ -995,7 +983,7 @@ mod test_drain_filter {
|
|||
fn underfull_removing_one() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
for doomed in 0..3 {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i == doomed);
|
||||
assert_eq!(map.len(), 2);
|
||||
map.check();
|
||||
|
@ -1006,7 +994,7 @@ mod test_drain_filter {
|
|||
fn underfull_keeping_one() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
for sacred in 0..3 {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i != sacred);
|
||||
assert!(map.keys().copied().eq(sacred..=sacred));
|
||||
map.check();
|
||||
|
@ -1016,7 +1004,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn underfull_removing_all() {
|
||||
let pairs = (0..3).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| true);
|
||||
assert!(map.is_empty());
|
||||
map.check();
|
||||
|
@ -1024,29 +1012,29 @@ mod test_drain_filter {
|
|||
|
||||
#[test]
|
||||
fn height_0_keeping_all() {
|
||||
let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let pairs = (0..node::CAPACITY).map(|i| (i, i));
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| false);
|
||||
assert!(map.keys().copied().eq(0..NODE_CAPACITY));
|
||||
assert!(map.keys().copied().eq(0..node::CAPACITY));
|
||||
map.check();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn height_0_removing_one() {
|
||||
let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
|
||||
for doomed in 0..NODE_CAPACITY {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let pairs = (0..node::CAPACITY).map(|i| (i, i));
|
||||
for doomed in 0..node::CAPACITY {
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i == doomed);
|
||||
assert_eq!(map.len(), NODE_CAPACITY - 1);
|
||||
assert_eq!(map.len(), node::CAPACITY - 1);
|
||||
map.check();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn height_0_keeping_one() {
|
||||
let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
|
||||
for sacred in 0..NODE_CAPACITY {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let pairs = (0..node::CAPACITY).map(|i| (i, i));
|
||||
for sacred in 0..node::CAPACITY {
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i != sacred);
|
||||
assert!(map.keys().copied().eq(sacred..=sacred));
|
||||
map.check();
|
||||
|
@ -1055,8 +1043,8 @@ mod test_drain_filter {
|
|||
|
||||
#[test]
|
||||
fn height_0_removing_all() {
|
||||
let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let pairs = (0..node::CAPACITY).map(|i| (i, i));
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| true);
|
||||
assert!(map.is_empty());
|
||||
map.check();
|
||||
|
@ -1064,7 +1052,7 @@ mod test_drain_filter {
|
|||
|
||||
#[test]
|
||||
fn height_0_keeping_half() {
|
||||
let mut map: BTreeMap<_, _> = (0..16).map(|i| (i, i)).collect();
|
||||
let mut map = BTreeMap::from_iter((0..16).map(|i| (i, i)));
|
||||
assert_eq!(map.drain_filter(|i, _| *i % 2 == 0).count(), 8);
|
||||
assert_eq!(map.len(), 8);
|
||||
map.check();
|
||||
|
@ -1073,7 +1061,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn height_1_removing_all() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| true);
|
||||
assert!(map.is_empty());
|
||||
map.check();
|
||||
|
@ -1083,7 +1071,7 @@ mod test_drain_filter {
|
|||
fn height_1_removing_one() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
|
||||
for doomed in 0..MIN_INSERTS_HEIGHT_1 {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i == doomed);
|
||||
assert_eq!(map.len(), MIN_INSERTS_HEIGHT_1 - 1);
|
||||
map.check();
|
||||
|
@ -1094,7 +1082,7 @@ mod test_drain_filter {
|
|||
fn height_1_keeping_one() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
|
||||
for sacred in 0..MIN_INSERTS_HEIGHT_1 {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i != sacred);
|
||||
assert!(map.keys().copied().eq(sacred..=sacred));
|
||||
map.check();
|
||||
|
@ -1105,7 +1093,7 @@ mod test_drain_filter {
|
|||
fn height_2_removing_one() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
|
||||
for doomed in (0..MIN_INSERTS_HEIGHT_2).step_by(12) {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i == doomed);
|
||||
assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1);
|
||||
map.check();
|
||||
|
@ -1116,7 +1104,7 @@ mod test_drain_filter {
|
|||
fn height_2_keeping_one() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
|
||||
for sacred in (0..MIN_INSERTS_HEIGHT_2).step_by(12) {
|
||||
let mut map: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut map = BTreeMap::from_iter(pairs.clone());
|
||||
map.drain_filter(|i, _| *i != sacred);
|
||||
assert!(map.keys().copied().eq(sacred..=sacred));
|
||||
map.check();
|
||||
|
@ -1126,7 +1114,7 @@ mod test_drain_filter {
|
|||
#[test]
|
||||
fn height_2_removing_all() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
|
||||
let mut map: BTreeMap<_, _> = pairs.collect();
|
||||
let mut map = BTreeMap::from_iter(pairs);
|
||||
map.drain_filter(|_, _| true);
|
||||
assert!(map.is_empty());
|
||||
map.check();
|
||||
|
@ -1287,7 +1275,7 @@ fn test_borrow() {
|
|||
fn test_entry() {
|
||||
let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
|
||||
|
||||
let mut map: BTreeMap<_, _> = xs.iter().cloned().collect();
|
||||
let mut map = BTreeMap::from(xs);
|
||||
|
||||
// Existing key (insert)
|
||||
match map.entry(1) {
|
||||
|
@ -1415,7 +1403,7 @@ fn test_bad_zst() {
|
|||
#[test]
|
||||
fn test_clear() {
|
||||
let mut map = BTreeMap::new();
|
||||
for &len in &[MIN_INSERTS_HEIGHT_1, MIN_INSERTS_HEIGHT_2, 0, NODE_CAPACITY] {
|
||||
for &len in &[MIN_INSERTS_HEIGHT_1, MIN_INSERTS_HEIGHT_2, 0, node::CAPACITY] {
|
||||
for i in 0..len {
|
||||
map.insert(i, ());
|
||||
}
|
||||
|
@ -1485,7 +1473,7 @@ fn test_clone() {
|
|||
}
|
||||
|
||||
// Test a tree with 2 semi-full levels and a tree with 3 levels.
|
||||
map = (1..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect();
|
||||
map = BTreeMap::from_iter((1..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)));
|
||||
assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1);
|
||||
assert_eq!(map, map.clone());
|
||||
map.insert(0, 0);
|
||||
|
@ -1496,14 +1484,11 @@ fn test_clone() {
|
|||
|
||||
fn test_clone_panic_leak(size: usize) {
|
||||
for i in 0..size {
|
||||
let dummies: Vec<CrashTestDummy> = (0..size).map(|id| CrashTestDummy::new(id)).collect();
|
||||
let map: BTreeMap<_, ()> = dummies
|
||||
.iter()
|
||||
.map(|dummy| {
|
||||
let panic = if dummy.id == i { Panic::InClone } else { Panic::Never };
|
||||
(dummy.spawn(panic), ())
|
||||
})
|
||||
.collect();
|
||||
let dummies = Vec::from_iter((0..size).map(|id| CrashTestDummy::new(id)));
|
||||
let map = BTreeMap::from_iter(dummies.iter().map(|dummy| {
|
||||
let panic = if dummy.id == i { Panic::InClone } else { Panic::Never };
|
||||
(dummy.spawn(panic), ())
|
||||
}));
|
||||
|
||||
catch_unwind(|| map.clone()).unwrap_err();
|
||||
for d in &dummies {
|
||||
|
@ -1864,9 +1849,9 @@ fn test_first_last_entry() {
|
|||
|
||||
#[test]
|
||||
fn test_insert_into_full_height_0() {
|
||||
let size = NODE_CAPACITY;
|
||||
let size = node::CAPACITY;
|
||||
for pos in 0..=size {
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i * 2 + 1, ())).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i * 2 + 1, ())));
|
||||
assert!(map.insert(pos * 2, ()).is_none());
|
||||
map.check();
|
||||
}
|
||||
|
@ -1874,14 +1859,14 @@ fn test_insert_into_full_height_0() {
|
|||
|
||||
#[test]
|
||||
fn test_insert_into_full_height_1() {
|
||||
let size = NODE_CAPACITY + 1 + NODE_CAPACITY;
|
||||
let size = node::CAPACITY + 1 + node::CAPACITY;
|
||||
for pos in 0..=size {
|
||||
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i * 2 + 1, ())).collect();
|
||||
let mut map = BTreeMap::from_iter((0..size).map(|i| (i * 2 + 1, ())));
|
||||
map.compact();
|
||||
let root_node = map.root.as_ref().unwrap().reborrow();
|
||||
assert_eq!(root_node.len(), 1);
|
||||
assert_eq!(root_node.first_leaf_edge().into_node().len(), NODE_CAPACITY);
|
||||
assert_eq!(root_node.last_leaf_edge().into_node().len(), NODE_CAPACITY);
|
||||
assert_eq!(root_node.first_leaf_edge().into_node().len(), node::CAPACITY);
|
||||
assert_eq!(root_node.last_leaf_edge().into_node().len(), node::CAPACITY);
|
||||
|
||||
assert!(map.insert(pos * 2, ()).is_none());
|
||||
map.check();
|
||||
|
@ -2022,7 +2007,7 @@ fn test_split_off_empty_left() {
|
|||
#[test]
|
||||
fn test_split_off_tiny_left_height_2() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
|
||||
let mut left: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut left = BTreeMap::from_iter(pairs.clone());
|
||||
let right = left.split_off(&1);
|
||||
left.check();
|
||||
right.check();
|
||||
|
@ -2038,7 +2023,7 @@ fn test_split_off_tiny_left_height_2() {
|
|||
fn test_split_off_tiny_right_height_2() {
|
||||
let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
|
||||
let last = MIN_INSERTS_HEIGHT_2 - 1;
|
||||
let mut left: BTreeMap<_, _> = pairs.clone().collect();
|
||||
let mut left = BTreeMap::from_iter(pairs.clone());
|
||||
assert_eq!(*left.last_key_value().unwrap().0, last);
|
||||
let right = left.split_off(&last);
|
||||
left.check();
|
||||
|
@ -2052,7 +2037,7 @@ fn test_split_off_tiny_right_height_2() {
|
|||
#[test]
|
||||
fn test_split_off_halfway() {
|
||||
let mut rng = DeterministicRng::new();
|
||||
for &len in &[NODE_CAPACITY, 25, 50, 75, 100] {
|
||||
for &len in &[node::CAPACITY, 25, 50, 75, 100] {
|
||||
let mut data = Vec::from_iter((0..len).map(|_| (rng.next(), ())));
|
||||
// Insertion in non-ascending order creates some variation in node length.
|
||||
let mut map = BTreeMap::from_iter(data.iter().copied());
|
||||
|
@ -2112,13 +2097,11 @@ fn test_into_iter_drop_leak_height_0() {
|
|||
fn test_into_iter_drop_leak_height_1() {
|
||||
let size = MIN_INSERTS_HEIGHT_1;
|
||||
for panic_point in vec![0, 1, size - 2, size - 1] {
|
||||
let dummies: Vec<_> = (0..size).map(|i| CrashTestDummy::new(i)).collect();
|
||||
let map: BTreeMap<_, _> = (0..size)
|
||||
.map(|i| {
|
||||
let panic = if i == panic_point { Panic::InDrop } else { Panic::Never };
|
||||
(dummies[i].spawn(Panic::Never), dummies[i].spawn(panic))
|
||||
})
|
||||
.collect();
|
||||
let dummies = Vec::from_iter((0..size).map(|i| CrashTestDummy::new(i)));
|
||||
let map = BTreeMap::from_iter((0..size).map(|i| {
|
||||
let panic = if i == panic_point { Panic::InDrop } else { Panic::Never };
|
||||
(dummies[i].spawn(Panic::Never), dummies[i].spawn(panic))
|
||||
}));
|
||||
catch_unwind(move || drop(map.into_iter())).unwrap_err();
|
||||
for i in 0..size {
|
||||
assert_eq!(dummies[i].dropped(), 2);
|
||||
|
@ -2128,9 +2111,8 @@ fn test_into_iter_drop_leak_height_1() {
|
|||
|
||||
#[test]
|
||||
fn test_into_keys() {
|
||||
let vec = [(1, 'a'), (2, 'b'), (3, 'c')];
|
||||
let map: BTreeMap<_, _> = vec.into_iter().collect();
|
||||
let keys: Vec<_> = map.into_keys().collect();
|
||||
let map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]);
|
||||
let keys = Vec::from_iter(map.into_keys());
|
||||
|
||||
assert_eq!(keys.len(), 3);
|
||||
assert!(keys.contains(&1));
|
||||
|
@ -2140,9 +2122,8 @@ fn test_into_keys() {
|
|||
|
||||
#[test]
|
||||
fn test_into_values() {
|
||||
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
|
||||
let map: BTreeMap<_, _> = vec.into_iter().collect();
|
||||
let values: Vec<_> = map.into_values().collect();
|
||||
let map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]);
|
||||
let values = Vec::from_iter(map.into_values());
|
||||
|
||||
assert_eq!(values.len(), 3);
|
||||
assert!(values.contains(&'a'));
|
||||
|
|
|
@ -1539,7 +1539,7 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
|
|||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let (a_len, b_len) = self.0.lens();
|
||||
// No checked_add, because even if a and b refer to the same set,
|
||||
// and T is an empty type, the storage overhead of sets limits
|
||||
// and T is a zero-sized type, the storage overhead of sets limits
|
||||
// the number of elements to less than half the range of usize.
|
||||
(0, Some(a_len + b_len))
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ fn test_intersection() {
|
|||
return;
|
||||
}
|
||||
|
||||
let large = (0..100).collect::<Vec<_>>();
|
||||
let large = Vec::from_iter(0..100);
|
||||
check_intersection(&[], &large, &[]);
|
||||
check_intersection(&large, &[], &[]);
|
||||
check_intersection(&[-1], &large, &[]);
|
||||
|
@ -107,8 +107,8 @@ fn test_intersection() {
|
|||
|
||||
#[test]
|
||||
fn test_intersection_size_hint() {
|
||||
let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
|
||||
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
|
||||
let x = BTreeSet::from([3, 4]);
|
||||
let y = BTreeSet::from([1, 2, 3]);
|
||||
let mut iter = x.intersection(&y);
|
||||
assert_eq!(iter.size_hint(), (1, Some(1)));
|
||||
assert_eq!(iter.next(), Some(&3));
|
||||
|
@ -145,7 +145,7 @@ fn test_difference() {
|
|||
return;
|
||||
}
|
||||
|
||||
let large = (0..100).collect::<Vec<_>>();
|
||||
let large = Vec::from_iter(0..100);
|
||||
check_difference(&[], &large, &[]);
|
||||
check_difference(&[-1], &large, &[-1]);
|
||||
check_difference(&[0], &large, &[]);
|
||||
|
@ -159,43 +159,43 @@ fn test_difference() {
|
|||
|
||||
#[test]
|
||||
fn test_difference_size_hint() {
|
||||
let s246: BTreeSet<i32> = [2, 4, 6].iter().copied().collect();
|
||||
let s23456: BTreeSet<i32> = (2..=6).collect();
|
||||
let s246 = BTreeSet::from([2, 4, 6]);
|
||||
let s23456 = BTreeSet::from_iter(2..=6);
|
||||
let mut iter = s246.difference(&s23456);
|
||||
assert_eq!(iter.size_hint(), (0, Some(3)));
|
||||
assert_eq!(iter.next(), None);
|
||||
|
||||
let s12345: BTreeSet<i32> = (1..=5).collect();
|
||||
let s12345 = BTreeSet::from_iter(1..=5);
|
||||
iter = s246.difference(&s12345);
|
||||
assert_eq!(iter.size_hint(), (0, Some(3)));
|
||||
assert_eq!(iter.next(), Some(&6));
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
|
||||
let s34567: BTreeSet<i32> = (3..=7).collect();
|
||||
let s34567 = BTreeSet::from_iter(3..=7);
|
||||
iter = s246.difference(&s34567);
|
||||
assert_eq!(iter.size_hint(), (0, Some(3)));
|
||||
assert_eq!(iter.next(), Some(&2));
|
||||
assert_eq!(iter.size_hint(), (0, Some(2)));
|
||||
assert_eq!(iter.next(), None);
|
||||
|
||||
let s1: BTreeSet<i32> = (-9..=1).collect();
|
||||
let s1 = BTreeSet::from_iter(-9..=1);
|
||||
iter = s246.difference(&s1);
|
||||
assert_eq!(iter.size_hint(), (3, Some(3)));
|
||||
|
||||
let s2: BTreeSet<i32> = (-9..=2).collect();
|
||||
let s2 = BTreeSet::from_iter(-9..=2);
|
||||
iter = s246.difference(&s2);
|
||||
assert_eq!(iter.size_hint(), (2, Some(2)));
|
||||
assert_eq!(iter.next(), Some(&4));
|
||||
assert_eq!(iter.size_hint(), (1, Some(1)));
|
||||
|
||||
let s23: BTreeSet<i32> = (2..=3).collect();
|
||||
let s23 = BTreeSet::from([2, 3]);
|
||||
iter = s246.difference(&s23);
|
||||
assert_eq!(iter.size_hint(), (1, Some(3)));
|
||||
assert_eq!(iter.next(), Some(&4));
|
||||
assert_eq!(iter.size_hint(), (1, Some(1)));
|
||||
|
||||
let s4: BTreeSet<i32> = (4..=4).collect();
|
||||
let s4 = BTreeSet::from([4]);
|
||||
iter = s246.difference(&s4);
|
||||
assert_eq!(iter.size_hint(), (2, Some(3)));
|
||||
assert_eq!(iter.next(), Some(&2));
|
||||
|
@ -204,19 +204,19 @@ fn test_difference_size_hint() {
|
|||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
|
||||
let s56: BTreeSet<i32> = (5..=6).collect();
|
||||
let s56 = BTreeSet::from([5, 6]);
|
||||
iter = s246.difference(&s56);
|
||||
assert_eq!(iter.size_hint(), (1, Some(3)));
|
||||
assert_eq!(iter.next(), Some(&2));
|
||||
assert_eq!(iter.size_hint(), (0, Some(2)));
|
||||
|
||||
let s6: BTreeSet<i32> = (6..=19).collect();
|
||||
let s6 = BTreeSet::from_iter(6..=19);
|
||||
iter = s246.difference(&s6);
|
||||
assert_eq!(iter.size_hint(), (2, Some(2)));
|
||||
assert_eq!(iter.next(), Some(&2));
|
||||
assert_eq!(iter.size_hint(), (1, Some(1)));
|
||||
|
||||
let s7: BTreeSet<i32> = (7..=19).collect();
|
||||
let s7 = BTreeSet::from_iter(7..=19);
|
||||
iter = s246.difference(&s7);
|
||||
assert_eq!(iter.size_hint(), (3, Some(3)));
|
||||
}
|
||||
|
@ -235,8 +235,8 @@ fn test_symmetric_difference() {
|
|||
|
||||
#[test]
|
||||
fn test_symmetric_difference_size_hint() {
|
||||
let x: BTreeSet<i32> = [2, 4].iter().copied().collect();
|
||||
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
|
||||
let x = BTreeSet::from([2, 4]);
|
||||
let y = BTreeSet::from([1, 2, 3]);
|
||||
let mut iter = x.symmetric_difference(&y);
|
||||
assert_eq!(iter.size_hint(), (0, Some(5)));
|
||||
assert_eq!(iter.next(), Some(&1));
|
||||
|
@ -263,8 +263,8 @@ fn test_union() {
|
|||
|
||||
#[test]
|
||||
fn test_union_size_hint() {
|
||||
let x: BTreeSet<i32> = [2, 4].iter().copied().collect();
|
||||
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
|
||||
let x = BTreeSet::from([2, 4]);
|
||||
let y = BTreeSet::from([1, 2, 3]);
|
||||
let mut iter = x.union(&y);
|
||||
assert_eq!(iter.size_hint(), (3, Some(5)));
|
||||
assert_eq!(iter.next(), Some(&1));
|
||||
|
@ -276,8 +276,8 @@ fn test_union_size_hint() {
|
|||
#[test]
|
||||
// Only tests the simple function definition with respect to intersection
|
||||
fn test_is_disjoint() {
|
||||
let one = [1].iter().collect::<BTreeSet<_>>();
|
||||
let two = [2].iter().collect::<BTreeSet<_>>();
|
||||
let one = BTreeSet::from([1]);
|
||||
let two = BTreeSet::from([2]);
|
||||
assert!(one.is_disjoint(&two));
|
||||
}
|
||||
|
||||
|
@ -285,8 +285,8 @@ fn test_is_disjoint() {
|
|||
// Also implicitly tests the trivial function definition of is_superset
|
||||
fn test_is_subset() {
|
||||
fn is_subset(a: &[i32], b: &[i32]) -> bool {
|
||||
let set_a = a.iter().collect::<BTreeSet<_>>();
|
||||
let set_b = b.iter().collect::<BTreeSet<_>>();
|
||||
let set_a = BTreeSet::from_iter(a.iter());
|
||||
let set_b = BTreeSet::from_iter(b.iter());
|
||||
set_a.is_subset(&set_b)
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ fn test_is_subset() {
|
|||
return;
|
||||
}
|
||||
|
||||
let large = (0..100).collect::<Vec<_>>();
|
||||
let large = Vec::from_iter(0..100);
|
||||
assert_eq!(is_subset(&[], &large), true);
|
||||
assert_eq!(is_subset(&large, &[]), false);
|
||||
assert_eq!(is_subset(&[-1], &large), false);
|
||||
|
@ -321,8 +321,7 @@ fn test_is_subset() {
|
|||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
|
||||
let mut set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
|
||||
set.retain(|&k| k % 2 == 0);
|
||||
assert_eq!(set.len(), 3);
|
||||
assert!(set.contains(&2));
|
||||
|
@ -332,8 +331,8 @@ fn test_retain() {
|
|||
|
||||
#[test]
|
||||
fn test_drain_filter() {
|
||||
let mut x: BTreeSet<_> = [1].iter().copied().collect();
|
||||
let mut y: BTreeSet<_> = [1].iter().copied().collect();
|
||||
let mut x = BTreeSet::from([1]);
|
||||
let mut y = BTreeSet::from([1]);
|
||||
|
||||
x.drain_filter(|_| true);
|
||||
y.drain_filter(|_| false);
|
||||
|
@ -417,7 +416,7 @@ fn test_zip() {
|
|||
fn test_from_iter() {
|
||||
let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
let set: BTreeSet<_> = xs.iter().cloned().collect();
|
||||
let set = BTreeSet::from_iter(xs.iter());
|
||||
|
||||
for x in &xs {
|
||||
assert!(set.contains(x));
|
||||
|
|
|
@ -103,17 +103,32 @@ impl ConsoleTestState {
|
|||
exec_time: Option<&TestExecTime>,
|
||||
) -> io::Result<()> {
|
||||
self.write_log(|| {
|
||||
let TestDesc {
|
||||
name,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message,
|
||||
..
|
||||
} = test;
|
||||
format!(
|
||||
"{} {}",
|
||||
match *result {
|
||||
TestResult::TrOk => "ok".to_owned(),
|
||||
TestResult::TrFailed => "failed".to_owned(),
|
||||
TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
|
||||
TestResult::TrIgnored => "ignored".to_owned(),
|
||||
TestResult::TrIgnored => {
|
||||
#[cfg(not(bootstrap))]
|
||||
if let Some(msg) = ignore_message {
|
||||
format!("ignored, {}", msg)
|
||||
} else {
|
||||
"ignored".to_owned()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
"ignored".to_owned()
|
||||
}
|
||||
TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
|
||||
TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
|
||||
},
|
||||
test.name,
|
||||
name,
|
||||
)
|
||||
})?;
|
||||
if let Some(exec_time) = exec_time {
|
||||
|
|
|
@ -61,6 +61,8 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("1"),
|
||||
ignore: true,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -74,6 +76,8 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("2"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -95,6 +99,8 @@ pub fn do_not_run_ignored_tests() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: true,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -117,6 +123,8 @@ pub fn ignored_tests_result_in_ignored() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: true,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -143,6 +151,8 @@ fn test_should_panic() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::Yes,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -169,6 +179,8 @@ fn test_should_panic_good_message() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::YesWithMessage("error message"),
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -200,6 +212,8 @@ fn test_should_panic_bad_message() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::YesWithMessage(expected),
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -235,6 +249,8 @@ fn test_should_panic_non_string_message_type() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::YesWithMessage(expected),
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -262,6 +278,8 @@ fn test_should_panic_but_succeeds() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -297,6 +315,8 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -333,6 +353,8 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -373,6 +395,8 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
|
|||
TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -486,6 +510,8 @@ pub fn exclude_should_panic_option() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName("3"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::Yes,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -511,6 +537,8 @@ pub fn exact_filter_match() {
|
|||
desc: TestDesc {
|
||||
name: StaticTestName(name),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -601,6 +629,8 @@ fn sample_tests() -> Vec<TestDescAndFn> {
|
|||
desc: TestDesc {
|
||||
name: DynTestName((*name).clone()),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -753,6 +783,8 @@ pub fn test_bench_no_iter() {
|
|||
let desc = TestDesc {
|
||||
name: StaticTestName("f"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -776,6 +808,8 @@ pub fn test_bench_iter() {
|
|||
let desc = TestDesc {
|
||||
name: StaticTestName("f"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -793,6 +827,8 @@ fn should_sort_failures_before_printing_them() {
|
|||
let test_a = TestDesc {
|
||||
name: StaticTestName("a"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
@ -804,6 +840,8 @@ fn should_sort_failures_before_printing_them() {
|
|||
let test_b = TestDesc {
|
||||
name: StaticTestName("b"),
|
||||
ignore: false,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
should_panic: ShouldPanic::No,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
|
|
@ -117,6 +117,8 @@ pub struct TestId(pub usize);
|
|||
pub struct TestDesc {
|
||||
pub name: TestName,
|
||||
pub ignore: bool,
|
||||
#[cfg(not(bootstrap))]
|
||||
pub ignore_message: Option<&'static str>,
|
||||
pub should_panic: options::ShouldPanic,
|
||||
pub compile_fail: bool,
|
||||
pub no_run: bool,
|
||||
|
|
|
@ -648,7 +648,7 @@ impl Step for Rustc {
|
|||
pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
|
||||
cargo
|
||||
.arg("--features")
|
||||
.arg(builder.rustc_features())
|
||||
.arg(builder.rustc_features(builder.kind))
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join("compiler/rustc/Cargo.toml"));
|
||||
rustc_cargo_env(builder, cargo, target);
|
||||
|
|
|
@ -119,6 +119,7 @@ use std::os::windows::fs::symlink_file;
|
|||
use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed};
|
||||
use filetime::FileTime;
|
||||
|
||||
use crate::builder::Kind;
|
||||
use crate::config::{LlvmLibunwind, TargetSelection};
|
||||
use crate::util::{exe, libdir, CiEnv};
|
||||
|
||||
|
@ -669,12 +670,12 @@ impl Build {
|
|||
}
|
||||
|
||||
/// Gets the space-separated set of activated features for the compiler.
|
||||
fn rustc_features(&self) -> String {
|
||||
fn rustc_features(&self, kind: Kind) -> String {
|
||||
let mut features = String::new();
|
||||
if self.config.jemalloc {
|
||||
features.push_str("jemalloc");
|
||||
}
|
||||
if self.config.llvm_enabled() {
|
||||
if self.config.llvm_enabled() || kind == Kind::Check {
|
||||
features.push_str(" llvm");
|
||||
}
|
||||
|
||||
|
|
|
@ -946,6 +946,8 @@ impl Tester for Collector {
|
|||
Ignore::None => false,
|
||||
Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
|
||||
},
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message: None,
|
||||
// compiler failures are test failures
|
||||
should_panic: test::ShouldPanic::No,
|
||||
compile_fail: config.compile_fail,
|
||||
|
|
45
src/test/ui/async-await/drop-track-field-assign-nonsend.rs
Normal file
45
src/test/ui/async-await/drop-track-field-assign-nonsend.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Derived from an ICE found in tokio-xmpp during a crater run.
|
||||
// edition:2021
|
||||
// compile-flags: -Zdrop-tracking
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Clone)]
|
||||
struct InfoResult {
|
||||
node: Option<std::rc::Rc<String>>
|
||||
}
|
||||
|
||||
struct Agent {
|
||||
info_result: InfoResult
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
async fn handle(&mut self) {
|
||||
let mut info = self.info_result.clone();
|
||||
info.node = None;
|
||||
let element = parse_info(info);
|
||||
let _ = send_element(element).await;
|
||||
}
|
||||
}
|
||||
|
||||
struct Element {
|
||||
}
|
||||
|
||||
async fn send_element(_: Element) {}
|
||||
|
||||
fn parse(_: &[u8]) -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_info(_: InfoResult) -> Element {
|
||||
Element { }
|
||||
}
|
||||
|
||||
fn assert_send<T: Send>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
let agent = Agent { info_result: InfoResult { node: None } };
|
||||
// FIXME: It would be nice for this to work. See #94067.
|
||||
assert_send(agent.handle());
|
||||
//~^ cannot be sent between threads safely
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
error: future cannot be sent between threads safely
|
||||
--> $DIR/drop-track-field-assign-nonsend.rs:43:17
|
||||
|
|
||||
LL | assert_send(agent.handle());
|
||||
| ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
|
||||
|
|
||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> $DIR/drop-track-field-assign-nonsend.rs:21:38
|
||||
|
|
||||
LL | let mut info = self.info_result.clone();
|
||||
| -------- has type `InfoResult` which is not `Send`
|
||||
...
|
||||
LL | let _ = send_element(element).await;
|
||||
| ^^^^^^ await occurs here, with `mut info` maybe used later
|
||||
LL | }
|
||||
| - `mut info` is later dropped here
|
||||
note: required by a bound in `assert_send`
|
||||
--> $DIR/drop-track-field-assign-nonsend.rs:38:19
|
||||
|
|
||||
LL | fn assert_send<T: Send>(_: T) {}
|
||||
| ^^^^ required by this bound in `assert_send`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
44
src/test/ui/async-await/drop-track-field-assign.rs
Normal file
44
src/test/ui/async-await/drop-track-field-assign.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Derived from an ICE found in tokio-xmpp during a crater run.
|
||||
// edition:2021
|
||||
// compile-flags: -Zdrop-tracking
|
||||
// build-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Clone)]
|
||||
struct InfoResult {
|
||||
node: Option<String>
|
||||
}
|
||||
|
||||
struct Agent {
|
||||
info_result: InfoResult
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
async fn handle(&mut self) {
|
||||
let mut info = self.info_result.clone();
|
||||
info.node = Some("bar".into());
|
||||
let element = parse_info(info);
|
||||
let _ = send_element(element).await;
|
||||
}
|
||||
}
|
||||
|
||||
struct Element {
|
||||
}
|
||||
|
||||
async fn send_element(_: Element) {}
|
||||
|
||||
fn parse(_: &[u8]) -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_info(_: InfoResult) -> Element {
|
||||
Element { }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut agent = Agent {
|
||||
info_result: InfoResult { node: None }
|
||||
};
|
||||
let _ = agent.handle();
|
||||
}
|
|
@ -806,6 +806,8 @@ pub fn make_test_description<R: Read>(
|
|||
cfg: Option<&str>,
|
||||
) -> test::TestDesc {
|
||||
let mut ignore = false;
|
||||
#[cfg(not(bootstrap))]
|
||||
let ignore_message: Option<String> = None;
|
||||
let mut should_fail = false;
|
||||
|
||||
let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
|
||||
|
@ -877,6 +879,8 @@ pub fn make_test_description<R: Read>(
|
|||
test::TestDesc {
|
||||
name,
|
||||
ignore,
|
||||
#[cfg(not(bootstrap))]
|
||||
ignore_message,
|
||||
should_panic,
|
||||
compile_fail: false,
|
||||
no_run: false,
|
||||
|
|
Loading…
Add table
Reference in a new issue