Skip to content

Rollup of 7 pull requests #56581

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

Merged
merged 27 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
47b5e23
Introduce ptr::hash for references
dwijnand Nov 26, 2018
86d20f9
FIXME is the new TODO
dwijnand Nov 26, 2018
5558c07
Fix ptr::hex doc example
dwijnand Nov 26, 2018
7b429b0
Fix stability attribute for ptr::hash
dwijnand Nov 27, 2018
8125149
Pick a better variable name for ptr::hash
dwijnand Nov 27, 2018
afb4fbd
Add an assert_eq in ptr::hash's doc example
dwijnand Nov 27, 2018
4a7ffe2
Fix issue number
dwijnand Nov 27, 2018
9755410
Try to fix ptr::hash's doc example
dwijnand Nov 27, 2018
097b5db
Move feature enable in ptr::hash doc example
dwijnand Nov 27, 2018
6fab3f9
Make ptr::hash take a raw painter like ptr::eq
dwijnand Dec 4, 2018
ad76569
Fix ptr::hash, just hash the raw pointer
dwijnand Dec 4, 2018
0f47c2a
Add Armv8-M Mainline targets
hug-dev Nov 13, 2018
c025d61
Replace usages of `..i + 1` ranges with `..=i`.
frewsxcv Dec 4, 2018
84443a3
Send textual profile data to stderr, not stdout
Mark-Simulacrum Dec 6, 2018
7df4b81
Fix bug in from_key_hashed_nocheck
Zoxc Dec 6, 2018
b6d3668
Fix a stutter in the docs for slice::exact_chunks
cbarrick Dec 6, 2018
ecd5efa
Show usages of query cycles and correctly shift queries in a cycle
Zoxc Dec 2, 2018
4fac739
Fix a race condition
Zoxc Dec 2, 2018
93294ea
Fix
Zoxc Dec 3, 2018
813b484
Fix printing of spans with no TyCtxt
Zoxc Dec 3, 2018
92638ef
Rollup merge of #56000 - hug-dev:armv8m.main, r=alexcrichton
kennytm Dec 7, 2018
6d3501e
Rollup merge of #56250 - dwijnand:ptr-hash, r=alexcrichton
kennytm Dec 7, 2018
6a07f23
Rollup merge of #56434 - Zoxc:par-tests, r=michaelwoerister
kennytm Dec 7, 2018
0e41ef1
Rollup merge of #56516 - frewsxcv:frewsxcv-eq, r=Mark-Simulacrum
kennytm Dec 7, 2018
aa5ba83
Rollup merge of #56555 - Mark-Simulacrum:stderr-profile, r=wesleywiser
kennytm Dec 7, 2018
06f3b57
Rollup merge of #56561 - Zoxc:too-raw, r=Gankro
kennytm Dec 7, 2018
a40aa45
Rollup merge of #56574 - cbarrick:master, r=varkor
kennytm Dec 7, 2018
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
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