Skip to content

Commit

Permalink
Auto merge of #56581 - kennytm:rollup, r=kennytm
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #56000 (Add Armv8-M Mainline targets)
 - #56250 (Introduce ptr::hash for references)
 - #56434 (Improve query cycle errors for parallel queries)
 - #56516 (Replace usages of `..i + 1` ranges with `..=i`.)
 - #56555 (Send textual profile data to stderr, not stdout)
 - #56561 (Fix bug in from_key_hashed_nocheck)
 - #56574 (Fix a stutter in the docs for slice::exact_chunks)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Dec 7, 2018
2 parents 15a2607 + a40aa45 commit fc84f5f
Show file tree
Hide file tree
Showing 30 changed files with 225 additions and 77 deletions.
18 changes: 9 additions & 9 deletions src/liballoc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2795,7 +2795,7 @@ mod tests {
// 0, 1, 2, .., len - 1
let expected = (0..).take(len).collect::<VecDeque<_>>();
for tail_pos in 0..cap {
for to_remove in 0..len + 1 {
for to_remove in 0..=len {
tester.tail = tail_pos;
tester.head = tail_pos;
for i in 0..len {
Expand All @@ -2821,10 +2821,10 @@ mod tests {
let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);

let cap = tester.capacity();
for len in 0..cap + 1 {
for tail in 0..cap + 1 {
for drain_start in 0..len + 1 {
for drain_end in drain_start..len + 1 {
for len in 0..=cap {
for tail in 0..=cap {
for drain_start in 0..=len {
for drain_end in drain_start..=len {
tester.tail = tail;
tester.head = tail;
for i in 0..len {
Expand Down Expand Up @@ -2866,10 +2866,10 @@ mod tests {
tester.reserve(63);
let max_cap = tester.capacity();

for len in 0..cap + 1 {
for len in 0..=cap {
// 0, 1, 2, .., len - 1
let expected = (0..).take(len).collect::<VecDeque<_>>();
for tail_pos in 0..max_cap + 1 {
for tail_pos in 0..=max_cap {
tester.tail = tail_pos;
tester.head = tail_pos;
tester.reserve(63);
Expand Down Expand Up @@ -2899,7 +2899,7 @@ mod tests {
// len is the length *before* splitting
for len in 0..cap {
// index to split at
for at in 0..len + 1 {
for at in 0..=len {
// 0, 1, 2, .., at - 1 (may be empty)
let expected_self = (0..).take(at).collect::<VecDeque<_>>();
// at, at + 1, .., len - 1 (may be empty)
Expand Down Expand Up @@ -2927,7 +2927,7 @@ mod tests {
fn test_from_vec() {
use vec::Vec;
for cap in 0..35 {
for len in 0..cap + 1 {
for len in 0..=cap {
let mut vec = Vec::with_capacity(cap);
vec.extend(0..len);

Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/tests/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,11 @@ fn panic_safe() {
const NTEST: usize = 10;

// don't use 0 in the data -- we want to catch the zeroed-out case.
let data = (1..DATASZ + 1).collect::<Vec<_>>();
let data = (1..=DATASZ).collect::<Vec<_>>();

// since it's a fuzzy test, run several tries.
for _ in 0..NTEST {
for i in 1..DATASZ + 1 {
for i in 1..=DATASZ {
DROP_COUNTER.store(0, Ordering::SeqCst);

let mut panic_ords: Vec<_> = data.iter()
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/tests/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ fn test_range() {
for i in 0..size {
for j in i..size {
let mut kvs = map.range((Included(&i), Included(&j))).map(|(&k, &v)| (k, v));
let mut pairs = (i..j + 1).map(|i| (i, i));
let mut pairs = (i..=j).map(|i| (i, i));

for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
assert_eq!(kv, pair);
Expand All @@ -321,7 +321,7 @@ fn test_range_mut() {
for i in 0..size {
for j in i..size {
let mut kvs = map.range_mut((Included(&i), Included(&j))).map(|(&k, &mut v)| (k, v));
let mut pairs = (i..j + 1).map(|i| (i, i));
let mut pairs = (i..=j).map(|i| (i, i));

for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
assert_eq!(kv, pair);
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,7 @@ fn test_bool_from_str() {
fn check_contains_all_substrings(s: &str) {
assert!(s.contains(""));
for i in 0..s.len() {
for j in i+1..s.len() + 1 {
for j in i+1..=s.len() {
assert!(s.contains(&s[i..j]));
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/liballoc/tests/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,15 +861,15 @@ fn test_as_slices() {
ring.push_back(i);

let (left, right) = ring.as_slices();
let expected: Vec<_> = (0..i + 1).collect();
let expected: Vec<_> = (0..=i).collect();
assert_eq!(left, &expected[..]);
assert_eq!(right, []);
}

for j in -last..0 {
ring.push_front(j);
let (left, right) = ring.as_slices();
let expected_left: Vec<_> = (-last..j + 1).rev().collect();
let expected_left: Vec<_> = (-last..=j).rev().collect();
let expected_right: Vec<_> = (0..first).collect();
assert_eq!(left, &expected_left[..]);
assert_eq!(right, &expected_right[..]);
Expand All @@ -889,15 +889,15 @@ fn test_as_mut_slices() {
ring.push_back(i);

let (left, right) = ring.as_mut_slices();
let expected: Vec<_> = (0..i + 1).collect();
let expected: Vec<_> = (0..=i).collect();
assert_eq!(left, &expected[..]);
assert_eq!(right, []);
}

for j in -last..0 {
ring.push_front(j);
let (left, right) = ring.as_mut_slices();
let expected_left: Vec<_> = (-last..j + 1).rev().collect();
let expected_left: Vec<_> = (-last..=j).rev().collect();
let expected_right: Vec<_> = (0..first).collect();
assert_eq!(left, &expected_left[..]);
assert_eq!(right, &expected_right[..]);
Expand Down
30 changes: 30 additions & 0 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2516,6 +2516,36 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
a == b
}

/// Hash the raw pointer address behind a reference, rather than the value
/// it points to.
///
/// # Examples
///
/// ```
/// #![feature(ptr_hash)]
/// use std::collections::hash_map::DefaultHasher;
/// use std::hash::{Hash, Hasher};
/// use std::ptr;
///
/// let five = 5;
/// let five_ref = &five;
///
/// let mut hasher = DefaultHasher::new();
/// ptr::hash(five_ref, &mut hasher);
/// let actual = hasher.finish();
///
/// let mut hasher = DefaultHasher::new();
/// (five_ref as *const i32).hash(&mut hasher);
/// let expected = hasher.finish();
///
/// assert_eq!(actual, expected);
/// ```
#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
use hash::Hash;
hashee.hash(into);
}

// Impls for function pointers
macro_rules! fnptr_impls_safety_abi {
($FnTy: ty, $($Arg: ident),*) => {
Expand Down
3 changes: 1 addition & 2 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,7 @@ impl<T> [T] {
/// resulting code better than in the case of [`chunks`].
///
/// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
/// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice of
/// the slice.
/// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
///
/// # Panics
///
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/hir_id_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {

if max != self.hir_ids_seen.len() - 1 {
// Collect the missing ItemLocalIds
let missing: Vec<_> = (0 .. max as u32 + 1)
let missing: Vec<_> = (0 ..= max as u32)
.filter(|&i| !self.hir_ids_seen.contains_key(&ItemLocalId::from_u32(i)))
.collect();

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ impl<'tcx> Mir<'tcx> {
#[inline]
pub fn args_iter(&self) -> impl Iterator<Item = Local> {
let arg_count = self.arg_count;
(1..arg_count + 1).map(Local::new)
(1..=arg_count).map(Local::new)
}

/// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
Expand Down
8 changes: 6 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1942,8 +1942,12 @@ pub mod tls {
/// This is a callback from libsyntax as it cannot access the implicit state
/// in librustc otherwise
fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
with(|tcx| {
write!(f, "{}", tcx.sess.source_map().span_to_string(span))
with_opt(|tcx| {
if let Some(tcx) = tcx {
write!(f, "{}", tcx.sess.source_map().span_to_string(span))
} else {
syntax_pos::default_span_debug(span, f)
}
})
}

Expand Down
98 changes: 66 additions & 32 deletions src/librustc/ty/query/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ impl<'tcx> QueryJob<'tcx> {
condvar: Condvar::new(),
});
self.latch.await(&waiter);

match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
// FIXME: Get rid of this lock. We have ownership of the QueryWaiter
// although another thread may still have a Lrc reference so we cannot
// use Lrc::get_mut
let mut cycle = waiter.cycle.lock();
match cycle.take() {
None => Ok(()),
Some(cycle) => Err(cycle)
}
Expand Down Expand Up @@ -326,19 +329,17 @@ fn connected_to_root<'tcx>(
query: Lrc<QueryJob<'tcx>>,
visited: &mut FxHashSet<*const QueryJob<'tcx>>
) -> bool {
// This query is connected to the root (it has no query parent), return true
if query.parent.is_none() {
return true;
}

// We already visited this or we're deliberately ignoring it
if visited.contains(&query.as_ptr()) {
return false;
}

visited.insert(query.as_ptr());
// This query is connected to the root (it has no query parent), return true
if query.parent.is_none() {
return true;
}

let mut connected = false;
visited.insert(query.as_ptr());

visit_waiters(query, |_, successor| {
if connected_to_root(successor, visited) {
Expand All @@ -349,6 +350,28 @@ fn connected_to_root<'tcx>(
}).is_some()
}

// Deterministically pick an query from a list
#[cfg(parallel_queries)]
fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc<QueryJob<'tcx>>)>(
tcx: TyCtxt<'_, 'tcx, '_>,
queries: &'a [T],
f: F
) -> &'a T {
// Deterministically pick an entry point
// FIXME: Sort this instead
let mut hcx = tcx.create_stable_hashing_context();
queries.iter().min_by_key(|v| {
let (span, query) = f(v);
let mut stable_hasher = StableHasher::<u64>::new();
query.info.query.hash_stable(&mut hcx, &mut stable_hasher);
// Prefer entry points which have valid spans for nicer error messages
// We add an integer to the tuple ensuring that entry points
// with valid spans are picked first
let span_cmp = if span == DUMMY_SP { 1 } else { 0 };
(span_cmp, stable_hasher.finish())
}).unwrap()
}

/// Looks for query cycles starting from the last query in `jobs`.
/// If a cycle is found, all queries in the cycle is removed from `jobs` and
/// the function return true.
Expand Down Expand Up @@ -388,41 +411,52 @@ fn remove_cycle<'tcx>(

// Find the queries in the cycle which are
// connected to queries outside the cycle
let entry_points = stack.iter().filter_map(|query| {
// Mark all the other queries in the cycle as already visited
let mut visited = FxHashSet::from_iter(stack.iter().filter_map(|q| {
if q.1.as_ptr() != query.1.as_ptr() {
Some(q.1.as_ptr())
} else {
let entry_points: Vec<_> = stack.iter().filter_map(|(span, query)| {
if query.parent.is_none() {
// This query is connected to the root (it has no query parent)
Some((*span, query.clone(), None))
} else {
let mut waiters = Vec::new();
// Find all the direct waiters who lead to the root
visit_waiters(query.clone(), |span, waiter| {
// Mark all the other queries in the cycle as already visited
let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1.as_ptr()));

if connected_to_root(waiter.clone(), &mut visited) {
waiters.push((span, waiter));
}

None
});
if waiters.is_empty() {
None
} else {
// Deterministically pick one of the waiters to show to the user
let waiter = pick_query(tcx, &waiters, |s| s.clone()).clone();
Some((*span, query.clone(), Some(waiter)))
}
}));

if connected_to_root(query.1.clone(), &mut visited) {
Some(query.1.clone())
} else {
None
}
});
}).collect();

let entry_points: Vec<(Span, Lrc<QueryJob<'tcx>>, Option<(Span, Lrc<QueryJob<'tcx>>)>)>
= entry_points;

// Deterministically pick an entry point
// FIXME: Sort this instead
let mut hcx = tcx.create_stable_hashing_context();
let entry_point = entry_points.min_by_key(|q| {
let mut stable_hasher = StableHasher::<u64>::new();
q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
stable_hasher.finish()
}).unwrap().as_ptr();
let (_, entry_point, usage) = pick_query(tcx, &entry_points, |e| (e.0, e.1.clone()));

// Shift the stack so that our entry point is first
let entry_point_pos = stack.iter().position(|(_, query)| query.as_ptr() == entry_point);
let entry_point_pos = stack.iter().position(|(_, query)| {
query.as_ptr() == entry_point.as_ptr()
});
if let Some(pos) = entry_point_pos {
stack.rotate_right(pos);
stack.rotate_left(pos);
}

let usage = usage.as_ref().map(|(span, query)| (*span, query.info.query.clone()));

// Create the cycle error
let mut error = CycleError {
usage: None,
usage,
cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
span: s,
query: q.info.query.clone(),
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/util/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use session::config::Options;

use std::fs;
use std::io::{self, StdoutLock, Write};
use std::io::{self, StderrLock, Write};
use std::time::{Duration, Instant};

macro_rules! define_categories {
Expand Down Expand Up @@ -61,7 +61,7 @@ macro_rules! define_categories {
}
}

fn print(&self, lock: &mut StdoutLock<'_>) {
fn print(&self, lock: &mut StderrLock<'_>) {
writeln!(lock, "| Phase | Time (ms) | Queries | Hits (%) |")
.unwrap();
writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |")
Expand Down Expand Up @@ -235,7 +235,7 @@ impl SelfProfiler {
self.timer_stack.is_empty(),
"there were timers running when print_results() was called");

let out = io::stdout();
let out = io::stderr();
let mut lock = out.lock();

let crate_name =
Expand Down
Loading

0 comments on commit fc84f5f

Please sign in to comment.