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 #82352

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6d2247e
BTreeMap/BTreeSet: separate off code supporting tests
ssomers Jan 23, 2021
3e1d602
BTreeMap: share panicky test code & test panic during clear, clone
ssomers Jan 23, 2021
4bf910b
Avoid `cfg_if` in `std::os`
jonas-schievink Feb 10, 2021
c5b43aa
Update RELEASES.md 1.50 to include methods stabilized in #79342
CDirkx Feb 15, 2021
f52caa7
Do not delete bootstrap.exe on Windows during clean
rylev Feb 16, 2021
e18c79a
Work around various issues cleaning up bootstrap on Windows
rylev Feb 16, 2021
5b0ed02
Delete symlinked directories
rylev Feb 16, 2021
fcf6e6e
Add check for ES5 in CI
GuillaumeGomez Feb 15, 2021
8ae05df
try-back-block-type test: Use TryFromSliceError for From test
ijackson Feb 17, 2021
2380090
Remove unsafe impl Send for CompletedTest & TestResult
tmiasko Feb 19, 2021
1d02358
Fix typo in generics.rs
eltociear Feb 20, 2021
9b4e612
Document BinaryHeap unsafe functions
SkiFire13 Feb 3, 2021
3ec1a28
Add FIXME for safety comments that are invalid when T is a ZST
SkiFire13 Feb 12, 2021
211d49c
parallelize x.py test tidy
the8472 Feb 6, 2021
6dc948e
limit rustfmt parallelism by taking -j into account
the8472 Feb 20, 2021
c071970
remove redundant box wrapper
the8472 Feb 12, 2021
8ead8f5
Add A-diagnostics bug report template
estebank Feb 17, 2021
88753ce
test: Print test name only once on timeout
tmiasko Feb 21, 2021
c853094
Rollup merge of #81300 - ssomers:btree_cleanup_leak_tests, r=Mark-Sim…
JohnTitor Feb 21, 2021
1b8cac8
Rollup merge of #81706 - SkiFire13:document-binaryheap-unsafe, r=Mark…
JohnTitor Feb 21, 2021
db0a6a6
Rollup merge of #81833 - the8472:parallel-bootstrap-rustfmt, r=Mark-S…
JohnTitor Feb 21, 2021
16f2980
Rollup merge of #81969 - jonas-schievink:no-cfg-if, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
7ddcb11
Rollup merge of #82154 - CDirkx:ip-changelog, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
1a6c48a
Rollup merge of #82177 - rylev:no-delete-bootstrap-windows, r=Mark-Si…
JohnTitor Feb 21, 2021
2dda490
Rollup merge of #82181 - GuillaumeGomez:es5-checks-ci, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
20d99b2
Rollup merge of #82229 - estebank:issue-templace, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
9685a5e
Rollup merge of #82233 - ijackson:try-block-type-test, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
5d6fc24
Rollup merge of #82302 - tmiasko:test-unsafe-send, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
01b822b
Rollup merge of #82324 - eltociear:patch-9, r=Dylan-DPC
JohnTitor Feb 21, 2021
73747ec
Rollup merge of #82349 - tmiasko:pretty-test-timeout, r=Mark-Simulacrum
JohnTitor Feb 21, 2021
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
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/diagnostics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: Diagnostic issue
about: Create a bug report or feature request for a change to `rustc`'s error output
labels: A-diagnostics, T-compiler
---
<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

```rust
<code>
```

The current output is:

```
<rustc output>
```

<!-- The following is not always necessary. -->
Ideally the output should look like:

```
<proposed output>
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

<!--
If dramatically different output is caused by small changes, consider also
adding them here.

If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->
34 changes: 34 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ The following previously stable methods are now `const`.

- [`IpAddr::is_ipv4`]
- [`IpAddr::is_ipv6`]
- [`IpAddr::is_unspecified`]
- [`IpAddr::is_loopback`]
- [`IpAddr::is_multicast`]
- [`Ipv4Addr::octets`]
- [`Ipv4Addr::is_loopback`]
- [`Ipv4Addr::is_private`]
- [`Ipv4Addr::is_link_local`]
- [`Ipv4Addr::is_multicast`]
- [`Ipv4Addr::is_broadcast`]
- [`Ipv4Addr::is_documentation`]
- [`Ipv4Addr::to_ipv6_compatible`]
- [`Ipv4Addr::to_ipv6_mapped`]
- [`Ipv6Addr::segments`]
- [`Ipv6Addr::is_unspecified`]
- [`Ipv6Addr::is_loopback`]
- [`Ipv6Addr::is_multicast`]
- [`Ipv6Addr::to_ipv4`]
- [`Layout::size`]
- [`Layout::align`]
- [`Layout::from_size_align`]
Expand Down Expand Up @@ -104,6 +121,23 @@ Compatibility Notes
[cargo/8725]: https://github.com/rust-lang/cargo/pull/8725
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv6
[`IpAddr::is_unspecified`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_unspecified
[`IpAddr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_loopback
[`IpAddr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_multicast
[`Ipv4Addr::octets`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.octets
[`Ipv4Addr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_loopback
[`Ipv4Addr::is_private`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_private
[`Ipv4Addr::is_link_local`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_link_local
[`Ipv4Addr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_multicast
[`Ipv4Addr::is_broadcast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_broadcast
[`Ipv4Addr::is_documentation`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_documentation
[`Ipv4Addr::to_ipv6_compatible`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.to_ipv6_compatible
[`Ipv4Addr::to_ipv6_mapped`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.to_ipv6_mapped
[`Ipv6Addr::segments`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.segments
[`Ipv6Addr::is_unspecified`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_unspecified
[`Ipv6Addr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_loopback
[`Ipv6Addr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_multicast
[`Ipv6Addr::to_ipv4`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.to_ipv4
[`Layout::align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align
[`Layout::from_size_align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.from_size_align
[`Layout::size`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.size
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if param_type.is_suggestable() {
err.span_suggestion(
tcx.def_span(src_def_id),
"consider changing this type paramater to a `const`-generic",
"consider changing this type parameter to a `const`-generic",
format!("const {}: {}", param_name, param_type),
Applicability::MaybeIncorrect,
);
Expand Down
166 changes: 117 additions & 49 deletions library/alloc/src/collections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ impl<T: Ord + fmt::Debug> fmt::Debug for PeekMut<'_, T> {
impl<T: Ord> Drop for PeekMut<'_, T> {
fn drop(&mut self) {
if self.sift {
self.heap.sift_down(0);
// SAFETY: PeekMut is only instantiated for non-empty heaps.
unsafe { self.heap.sift_down(0) };
}
}
}
Expand Down Expand Up @@ -431,7 +432,8 @@ impl<T: Ord> BinaryHeap<T> {
self.data.pop().map(|mut item| {
if !self.is_empty() {
swap(&mut item, &mut self.data[0]);
self.sift_down_to_bottom(0);
// SAFETY: !self.is_empty() means that self.len() > 0
unsafe { self.sift_down_to_bottom(0) };
}
item
})
Expand Down Expand Up @@ -473,7 +475,9 @@ impl<T: Ord> BinaryHeap<T> {
pub fn push(&mut self, item: T) {
let old_len = self.len();
self.data.push(item);
self.sift_up(0, old_len);
// SAFETY: Since we pushed a new item it means that
// old_len = self.len() - 1 < self.len()
unsafe { self.sift_up(0, old_len) };
}

/// Consumes the `BinaryHeap` and returns a vector in sorted
Expand Down Expand Up @@ -506,7 +510,10 @@ impl<T: Ord> BinaryHeap<T> {
let ptr = self.data.as_mut_ptr();
ptr::swap(ptr, ptr.add(end));
}
self.sift_down_range(0, end);
// SAFETY: `end` goes from `self.len() - 1` to 1 (both included) so:
// 0 < 1 <= end <= self.len() - 1 < self.len()
// Which means 0 < end and end < self.len().
unsafe { self.sift_down_range(0, end) };
}
self.into_vec()
}
Expand All @@ -519,78 +526,139 @@ impl<T: Ord> BinaryHeap<T> {
// the hole is filled back at the end of its scope, even on panic.
// Using a hole reduces the constant factor compared to using swaps,
// which involves twice as many moves.
fn sift_up(&mut self, start: usize, pos: usize) -> usize {
unsafe {
// Take out the value at `pos` and create a hole.
let mut hole = Hole::new(&mut self.data, pos);

while hole.pos() > start {
let parent = (hole.pos() - 1) / 2;
if hole.element() <= hole.get(parent) {
break;
}
hole.move_to(parent);

/// # Safety
///
/// The caller must guarantee that `pos < self.len()`.
unsafe fn sift_up(&mut self, start: usize, pos: usize) -> usize {
// Take out the value at `pos` and create a hole.
// SAFETY: The caller guarantees that pos < self.len()
let mut hole = unsafe { Hole::new(&mut self.data, pos) };

while hole.pos() > start {
let parent = (hole.pos() - 1) / 2;

// SAFETY: hole.pos() > start >= 0, which means hole.pos() > 0
// and so hole.pos() - 1 can't underflow.
// This guarantees that parent < hole.pos() so
// it's a valid index and also != hole.pos().
if hole.element() <= unsafe { hole.get(parent) } {
break;
}
hole.pos()

// SAFETY: Same as above
unsafe { hole.move_to(parent) };
}

hole.pos()
}

/// Take an element at `pos` and move it down the heap,
/// while its children are larger.
fn sift_down_range(&mut self, pos: usize, end: usize) {
unsafe {
let mut hole = Hole::new(&mut self.data, pos);
let mut child = 2 * pos + 1;
while child < end - 1 {
// compare with the greater of the two children
child += (hole.get(child) <= hole.get(child + 1)) as usize;
// if we are already in order, stop.
if hole.element() >= hole.get(child) {
return;
}
hole.move_to(child);
child = 2 * hole.pos() + 1;
}
if child == end - 1 && hole.element() < hole.get(child) {
hole.move_to(child);
///
/// # Safety
///
/// The caller must guarantee that `pos < end <= self.len()`.
unsafe fn sift_down_range(&mut self, pos: usize, end: usize) {
// SAFETY: The caller guarantees that pos < end <= self.len().
let mut hole = unsafe { Hole::new(&mut self.data, pos) };
let mut child = 2 * hole.pos() + 1;

// Loop invariant: child == 2 * hole.pos() + 1.
while child < end - 1 {
// compare with the greater of the two children
// SAFETY: child < end - 1 < self.len() and
// child + 1 < end <= self.len(), so they're valid indexes.
// child == 2 * hole.pos() + 1 != hole.pos() and
// child + 1 == 2 * hole.pos() + 2 != hole.pos().
// FIXME: 2 * hole.pos() + 1 or 2 * hole.pos() + 2 could overflow
// if T is a ZST
child += unsafe { hole.get(child) <= hole.get(child + 1) } as usize;

// if we are already in order, stop.
// SAFETY: child is now either the old child or the old child+1
// We already proven that both are < self.len() and != hole.pos()
if hole.element() >= unsafe { hole.get(child) } {
return;
}

// SAFETY: same as above.
unsafe { hole.move_to(child) };
child = 2 * hole.pos() + 1;
}

// SAFETY: && short circuit, which means that in the
// second condition it's already true that child == end - 1 < self.len().
if child == end - 1 && hole.element() < unsafe { hole.get(child) } {
// SAFETY: child is already proven to be a valid index and
// child == 2 * hole.pos() + 1 != hole.pos().
unsafe { hole.move_to(child) };
}
}

fn sift_down(&mut self, pos: usize) {
/// # Safety
///
/// The caller must guarantee that `pos < self.len()`.
unsafe fn sift_down(&mut self, pos: usize) {
let len = self.len();
self.sift_down_range(pos, len);
// SAFETY: pos < len is guaranteed by the caller and
// obviously len = self.len() <= self.len().
unsafe { self.sift_down_range(pos, len) };
}

/// Take an element at `pos` and move it all the way down the heap,
/// then sift it up to its position.
///
/// Note: This is faster when the element is known to be large / should
/// be closer to the bottom.
fn sift_down_to_bottom(&mut self, mut pos: usize) {
///
/// # Safety
///
/// The caller must guarantee that `pos < self.len()`.
unsafe fn sift_down_to_bottom(&mut self, mut pos: usize) {
let end = self.len();
let start = pos;
unsafe {
let mut hole = Hole::new(&mut self.data, pos);
let mut child = 2 * pos + 1;
while child < end - 1 {
child += (hole.get(child) <= hole.get(child + 1)) as usize;
hole.move_to(child);
child = 2 * hole.pos() + 1;
}
if child == end - 1 {
hole.move_to(child);
}
pos = hole.pos;

// SAFETY: The caller guarantees that pos < self.len().
let mut hole = unsafe { Hole::new(&mut self.data, pos) };
let mut child = 2 * hole.pos() + 1;

// Loop invariant: child == 2 * hole.pos() + 1.
while child < end - 1 {
// SAFETY: child < end - 1 < self.len() and
// child + 1 < end <= self.len(), so they're valid indexes.
// child == 2 * hole.pos() + 1 != hole.pos() and
// child + 1 == 2 * hole.pos() + 2 != hole.pos().
// FIXME: 2 * hole.pos() + 1 or 2 * hole.pos() + 2 could overflow
// if T is a ZST
child += unsafe { hole.get(child) <= hole.get(child + 1) } as usize;

// SAFETY: Same as above
unsafe { hole.move_to(child) };
child = 2 * hole.pos() + 1;
}
self.sift_up(start, pos);

if child == end - 1 {
// SAFETY: child == end - 1 < self.len(), so it's a valid index
// and child == 2 * hole.pos() + 1 != hole.pos().
unsafe { hole.move_to(child) };
}
pos = hole.pos();
drop(hole);

// SAFETY: pos is the position in the hole and was already proven
// to be a valid index.
unsafe { self.sift_up(start, pos) };
}

fn rebuild(&mut self) {
let mut n = self.len() / 2;
while n > 0 {
n -= 1;
self.sift_down(n);
// SAFETY: n starts from self.len() / 2 and goes down to 0.
// The only case when !(n < self.len()) is if
// self.len() == 0, but it's ruled out by the loop condition.
unsafe { self.sift_down(n) };
}
}

Expand Down
Loading