Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 12 pull requests #74710

Merged
merged 29 commits into from
Jul 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
839216a
Improve logo image display in different themes
GuillaumeGomez Jul 15, 2020
c5cc29b
Parse rustc_deprecated as deprecated attribute
Mark-Simulacrum Jul 20, 2020
21a3d29
rustc_depr no longer needs to be connected to stability
Mark-Simulacrum Jul 20, 2020
8454ee8
Migrate rustc_depr uses to use deprecation attribute
Mark-Simulacrum Jul 20, 2020
6a9c5fb
polymorphize GlobalAlloc::Function
lcnr Jul 22, 2020
40b6bcc
no need to polymorphize
lcnr Jul 22, 2020
2152d18
More BTreeMap test cases, some exposing undefined behaviour
ssomers Jul 14, 2020
dc7d115
Don't ICE on unconstrained anonymous lifetimes inside associated types.
smmalis37 Jul 23, 2020
bbaab63
Include the note in the test.
smmalis37 Jul 23, 2020
37f6f7f
Fix typo
Homarechan Jul 23, 2020
3f4f313
Add missing backticks in diagnostics note
JohnTitor Jul 23, 2020
facc46f
BTreeMap::drain_filter: replace needless unsafety and test
ssomers Jul 22, 2020
9be9d72
Clean up E0727 explanation
GuillaumeGomez Jul 23, 2020
d6b50d8
Clean up E0724 explanation
GuillaumeGomez Jul 21, 2020
62e75a1
Fix ICE while building MIR with type errors
tmandry Jul 24, 2020
ccbb024
ayu: Change to less luminous color
tesuji Jul 23, 2020
7005ddb
Add right border bar to Dark and Light theme
tesuji Jul 22, 2020
38b2956
Rollup merge of #74361 - GuillaumeGomez:theme-logo, r=Manishearth
JohnTitor Jul 24, 2020
52476f5
Rollup merge of #74504 - lzutao:ayu-border-selected-fn, r=GuillaumeGomez
JohnTitor Jul 24, 2020
0651dd4
Rollup merge of #74572 - Mark-Simulacrum:unify-rustc-depr, r=petroche…
JohnTitor Jul 24, 2020
a816345
Rollup merge of #74601 - GuillaumeGomez:cleanup-e0724, r=jyn514
JohnTitor Jul 24, 2020
a02aecb
Rollup merge of #74623 - lcnr:polymorphize-functions, r=eddyb
JohnTitor Jul 24, 2020
1f6d5ce
Rollup merge of #74665 - smmalis37:issue-62200, r=davidtwco
JohnTitor Jul 24, 2020
cff5953
Rollup merge of #74666 - ssomers:btree_cleanup_1, r=Mark-Simulacrum
JohnTitor Jul 24, 2020
7f2bb29
Rollup merge of #74669 - Homarechan:fix_typo, r=lcnr
JohnTitor Jul 24, 2020
fab9b1d
Rollup merge of #74677 - ssomers:btree_cleanup_2, r=Amanieu
JohnTitor Jul 24, 2020
90f2816
Rollup merge of #74680 - JohnTitor:missing-backticks, r=lcnr
JohnTitor Jul 24, 2020
2406c93
Rollup merge of #74694 - GuillaumeGomez:cleanup-e0727, r=Dylan-DPC
JohnTitor Jul 24, 2020
01b069d
Rollup merge of #74703 - tmandry:issue-74047, r=oli-obk
JohnTitor Jul 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1672,19 +1672,12 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
edge.reborrow().next_kv().ok().map(|kv| kv.into_kv())
}

unsafe fn next_kv(
&mut self,
) -> Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>> {
let edge = self.cur_leaf_edge.as_ref()?;
unsafe { ptr::read(edge).next_kv().ok() }
}

/// Implementation of a typical `DrainFilter::next` method, given the predicate.
pub(super) fn next<F>(&mut self, pred: &mut F) -> Option<(K, V)>
where
F: FnMut(&K, &mut V) -> bool,
{
while let Some(mut kv) = unsafe { self.next_kv() } {
while let Ok(mut kv) = self.cur_leaf_edge.take()?.next_kv() {
let (k, v) = kv.kv_mut();
if pred(k, v) {
*self.length -= 1;
Expand Down
138 changes: 126 additions & 12 deletions src/liballoc/tests/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fmt::Debug;
use std::iter::FromIterator;
use std::mem;
use std::ops::Bound::{self, Excluded, Included, Unbounded};
use std::ops::RangeBounds;
use std::panic::{catch_unwind, AssertUnwindSafe};
Expand All @@ -25,6 +26,20 @@ const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1;
// It's not the minimum size: removing an element from such a tree does not always reduce height.
const MIN_INSERTS_HEIGHT_2: usize = NODE_CAPACITY + (NODE_CAPACITY + 1) * NODE_CAPACITY + 1;

// Gather all references from a mutable iterator and make sure Miri notices if
// using them is dangerous.
fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
// Gather all those references.
let mut refs: Vec<&mut T> = iter.collect();
// Use them all. Twice, to be sure we got all interleavings.
for r in refs.iter_mut() {
mem::swap(dummy, r);
}
for r in refs {
mem::swap(dummy, r);
}
}

#[test]
fn test_basic_large() {
let mut map = BTreeMap::new();
Expand Down Expand Up @@ -268,7 +283,14 @@ fn test_iter_mut_mutation() {
}

#[test]
#[cfg_attr(miri, ignore)] // FIXME: fails in Miri <https://github.com/rust-lang/rust/issues/73915>
fn test_values_mut() {
let mut a: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect();
test_all_refs(&mut 13, a.values_mut());
}

#[test]
fn test_values_mut_mutation() {
let mut a = BTreeMap::new();
a.insert(1, String::from("hello"));
a.insert(2, String::from("goodbye"));
Expand All @@ -281,6 +303,36 @@ fn test_values_mut() {
assert_eq!(values, [String::from("hello!"), String::from("goodbye!")]);
}

#[test]
#[cfg_attr(miri, ignore)] // FIXME: fails in Miri <https://github.com/rust-lang/rust/issues/73915>
fn test_iter_entering_root_twice() {
let mut map: BTreeMap<_, _> = (0..2).map(|i| (i, i)).collect();
let mut it = map.iter_mut();
let front = it.next().unwrap();
let back = it.next_back().unwrap();
assert_eq!(front, (&0, &mut 0));
assert_eq!(back, (&1, &mut 1));
*front.1 = 24;
*back.1 = 42;
assert_eq!(front, (&0, &mut 24));
assert_eq!(back, (&1, &mut 42));
}

#[test]
#[cfg_attr(miri, ignore)] // FIXME: fails in Miri <https://github.com/rust-lang/rust/issues/73915>
fn test_iter_descending_to_same_node_twice() {
let mut map: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i)).collect();
let mut it = map.iter_mut();
// Descend into first child.
let front = it.next().unwrap();
// Descend into first child again, after running through second child.
while it.next_back().is_some() {}
// Check immutable access.
assert_eq!(front, (&0, &mut 0));
// Perform mutable access.
*front.1 = 42;
}

#[test]
fn test_iter_mixed() {
// Miri is too slow
Expand Down Expand Up @@ -835,18 +887,16 @@ mod test_drain_filter {
}
}

let mut map = BTreeMap::new();
map.insert(0, D);
map.insert(4, D);
map.insert(8, D);
// Keys are multiples of 4, so that each key is counted by a hexadecimal digit.
let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>();

catch_unwind(move || {
drop(map.drain_filter(|i, _| {
PREDS.fetch_add(1usize << i, Ordering::SeqCst);
true
}))
})
.ok();
.unwrap_err();

assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
Expand All @@ -864,10 +914,8 @@ mod test_drain_filter {
}
}

let mut map = BTreeMap::new();
map.insert(0, D);
map.insert(4, D);
map.insert(8, D);
// Keys are multiples of 4, so that each key is counted by a hexadecimal digit.
let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>();

catch_unwind(AssertUnwindSafe(|| {
drop(map.drain_filter(|i, _| {
Expand All @@ -878,7 +926,45 @@ mod test_drain_filter {
}
}))
}))
.ok();
.unwrap_err();

assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 1);
assert_eq!(map.len(), 2);
assert_eq!(map.first_entry().unwrap().key(), &4);
assert_eq!(map.last_entry().unwrap().key(), &8);
}

// Same as above, but attempt to use the iterator again after the panic in the predicate
#[test]
fn pred_panic_reuse() {
static PREDS: AtomicUsize = AtomicUsize::new(0);
static DROPS: AtomicUsize = AtomicUsize::new(0);

struct D;
impl Drop for D {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
}
}

// Keys are multiples of 4, so that each key is counted by a hexadecimal digit.
let mut map = (0..3).map(|i| (i * 4, D)).collect::<BTreeMap<_, _>>();

{
let mut it = map.drain_filter(|i, _| {
PREDS.fetch_add(1usize << i, Ordering::SeqCst);
match i {
0 => true,
_ => panic!(),
}
});
catch_unwind(AssertUnwindSafe(|| while it.next().is_some() {})).unwrap_err();
// Iterator behaviour after a panic is explicitly unspecified,
// so this is just the current implementation:
let result = catch_unwind(AssertUnwindSafe(|| it.next()));
assert!(matches!(result, Ok(None)));
}

assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 1);
Expand Down Expand Up @@ -1283,6 +1369,34 @@ fn test_split_off_empty_left() {
assert!(right.into_iter().eq(data));
}

// In a tree with 3 levels, if all but a part of the first leaf node is split off,
// make sure fix_top eliminates both top levels.
#[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 right = left.split_off(&1);
assert_eq!(left.len(), 1);
assert_eq!(right.len(), MIN_INSERTS_HEIGHT_2 - 1);
assert_eq!(*left.first_key_value().unwrap().0, 0);
assert_eq!(*right.first_key_value().unwrap().0, 1);
}

// In a tree with 3 levels, if only part of the last leaf node is split off,
// make sure fix_top eliminates both top levels.
#[test]
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();
assert_eq!(*left.last_key_value().unwrap().0, last);
let right = left.split_off(&last);
assert_eq!(left.len(), MIN_INSERTS_HEIGHT_2 - 1);
assert_eq!(right.len(), 1);
assert_eq!(*left.last_key_value().unwrap().0, last - 1);
assert_eq!(*right.last_key_value().unwrap().0, last);
}

#[test]
fn test_split_off_large_random_sorted() {
// Miri is too slow
Expand Down Expand Up @@ -1319,7 +1433,7 @@ fn test_into_iter_drop_leak_height_0() {
map.insert("d", D);
map.insert("e", D);

catch_unwind(move || drop(map.into_iter())).ok();
catch_unwind(move || drop(map.into_iter())).unwrap_err();

assert_eq!(DROPS.load(Ordering::SeqCst), 5);
}
Expand All @@ -1343,7 +1457,7 @@ fn test_into_iter_drop_leak_height_1() {
DROPS.store(0, Ordering::SeqCst);
PANIC_POINT.store(panic_point, Ordering::SeqCst);
let map: BTreeMap<_, _> = (0..size).map(|i| (i, D)).collect();
catch_unwind(move || drop(map.into_iter())).ok();
catch_unwind(move || drop(map.into_iter())).unwrap_err();
assert_eq!(DROPS.load(Ordering::SeqCst), size);
}
}
2 changes: 1 addition & 1 deletion src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub unsafe trait Step: Clone + PartialOrd + Sized {
/// * `steps_between(&a, &b) == Some(n)` only if `a <= b`
/// * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b`
/// * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
/// this is the case wheen it would require more than `usize::MAX` steps to get to `b`
/// this is the case when it would require more than `usize::MAX` steps to get to `b`
/// * `steps_between(&a, &b) == None` if `a > b`
fn steps_between(start: &Self, end: &Self) -> Option<usize>;

Expand Down
6 changes: 3 additions & 3 deletions src/libcore/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
#[rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
Expand Down Expand Up @@ -141,7 +141,7 @@ pub trait Fn<Args>: FnMut<Args> {
#[rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
Expand Down Expand Up @@ -215,7 +215,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
#[rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
Expand Down
Loading