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:
bors 2022-02-25 08:40:34 +00:00
commit 03c8ffaacb
18 changed files with 354 additions and 148 deletions

View file

@ -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/

View file

@ -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) => {

View file

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

View file

@ -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 =

View file

@ -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(

View file

@ -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'));

View file

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

View file

@ -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));

View file

@ -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 {

View file

@ -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,

View file

@ -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,

View file

@ -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);

View file

@ -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");
}

View file

@ -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,

View 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
}

View file

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

View 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();
}

View file

@ -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,