Rollup of 9 pull requests
Successful merges:
- #71662 (Implement FromStr for OsString)
- #71677 (Add explicit references to the BuildHasher trait)
- #71724 (Doc alias improvements)
- #71948 (Suggest to await future before ? operator)
- #72090 (rustc_driver: factor out computing the exit code)
- #72206 (Cleanup stale 'FIXME(#64197)')
- #72218 (make sure even unleashed miri does not do pointer stuff)
- #72220 ([const-prop] Don't replace Rvalues that are already constants)
- #72224 (doc: add links to rotate_(left|right))
Failed merges:
r? @ghost
[const-prop] Don't replace Rvalues that are already constants
This cleans up a few mir-opt tests which have slight changes to spans for `consts` as a result of replacing them with new Rvalues.
Cleanup stale 'FIXME(#64197)'
(My first PR in rust-lang, any feedback is welcome. Please don't hesitate to let me know if I'm trying to do something pointless!)
Trivial cleanup of a stale `FIXME`, `StringReader.pos` is no longer exposed. For testing added `pos()` method that returns cloned value of `pos`.
rustc_driver: factor out computing the exit code
In a recent Miri PR I [added a convenience wrapper](https://github.com/rust-lang/miri/pull/1405/files#diff-c3d602c5c8035a16699ce9c015bfeceaR125) around `catch_fatal_errors` and `run_compiler` that @oli-obk suggested I could upstream. However, after seeing what could be shared between `rustc_driver::main`, clippy and Miri, really the only thing I found is computing the exit code -- so that's what this PR does.
What prevents using the Miri convenience function in `rustc_driver::main` and clippy is that they do extra work inside `catch_fatal_errors`, and while I could abstract that away, clippy actually *computes the callbacks* inside there, and I fond no good way to abstract that and thus gave up. Maybe the clippy thing could be moved out, I am not sure if it ever can actually raise a `FatalErrorMarker` -- someone more knowledgeable in clippy would have to do that.
Doc alias improvements
After [this message](https://github.com/rust-lang/rust/issues/50146#issuecomment-496601755), I realized that the **doc alias**. So this PR does the followings:
* Align the alias discovery on items added into the search-index. It brings a few nice advantages:
* Instead of cloning the data between the two (in rustdoc source code), we now have the search-index one and aliases which reference to the first one. So we go from one big map containing a lot of duplicated data to just integers...
* In the front-end (main.js), I improved the code around aliases to allow them to go through the same transformation as other items when we show the search results.
* Improve the search tester in order to perform multiple requests into one file (I think it's better in this case than having a file for each case considering how many there are...)
* I also had to add the new function inside the tester (`handleAliases`)
Once this PR is merged, I intend to finally stabilize this feature.
r? @ollie27
cc @rust-lang/rustdoc
Rework the std::iter::Step trait
Previous attempts: #43127#62886#68807
Tracking issue: #42168
This PR reworks the `Step` trait to be phrased in terms of the *successor* and *predecessor* operations. With this, `Step` hopefully has a consistent identity that can have a path towards stabilization. The proposed trait:
```rust
/// Objects that have a notion of *successor* and *predecessor* operations.
///
/// The *successor* operation moves towards values that compare greater.
/// The *predecessor* operation moves towards values that compare lesser.
///
/// # Safety
///
/// This trait is `unsafe` because its implementation must be correct for
/// the safety of `unsafe trait TrustedLen` implementations, and the results
/// of using this trait can otherwise be trusted by `unsafe` code to be correct
/// and fulful the listed obligations.
pub unsafe trait Step: Clone + PartialOrd + Sized {
/// Returns the number of *successor* steps required to get from `start` to `end`.
///
/// Returns `None` if the number of steps would overflow `usize`
/// (or is infinite, or if `end` would never be reached).
///
/// # Invariants
///
/// For any `a`, `b`, and `n`:
///
/// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward(&a, n) == Some(b)`
/// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward(&a, n) == Some(a)`
/// * `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`
/// * `steps_between(&a, &b) == None` if `a > b`
fn steps_between(start: &Self, end: &Self) -> Option<usize>;
/// Returns the value that would be obtained by taking the *successor*
/// of `self` `count` times.
///
/// If this would overflow the range of values supported by `Self`, returns `None`.
///
/// # Invariants
///
/// For any `a`, `n`, and `m`:
///
/// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, m).and_then(|x| Step::forward_checked(x, n))`
///
/// For any `a`, `n`, and `m` where `n + m` does not overflow:
///
/// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, n + m)`
///
/// For any `a` and `n`:
///
/// * `Step::forward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::forward_checked(&x, 1))`
/// * Corollary: `Step::forward_checked(&a, 0) == Some(a)`
fn forward_checked(start: Self, count: usize) -> Option<Self>;
/// Returns the value that would be obtained by taking the *successor*
/// of `self` `count` times.
///
/// If this would overflow the range of values supported by `Self`,
/// this function is allowed to panic, wrap, or saturate.
/// The suggested behavior is to panic when debug assertions are enabled,
/// and to wrap or saturate otherwise.
///
/// Unsafe code should not rely on the correctness of behavior after overflow.
///
/// # Invariants
///
/// For any `a`, `n`, and `m`, where no overflow occurs:
///
/// * `Step::forward(Step::forward(a, n), m) == Step::forward(a, n + m)`
///
/// For any `a` and `n`, where no overflow occurs:
///
/// * `Step::forward_checked(a, n) == Some(Step::forward(a, n))`
/// * `Step::forward(a, n) == (0..n).fold(a, |x, _| Step::forward(x, 1))`
/// * Corollary: `Step::forward(a, 0) == a`
/// * `Step::forward(a, n) >= a`
/// * `Step::backward(Step::forward(a, n), n) == a`
fn forward(start: Self, count: usize) -> Self {
Step::forward_checked(start, count).expect("overflow in `Step::forward`")
}
/// Returns the value that would be obtained by taking the *successor*
/// of `self` `count` times.
///
/// # Safety
///
/// It is undefined behavior for this operation to overflow the
/// range of values supported by `Self`. If you cannot guarantee that this
/// will not overflow, use `forward` or `forward_checked` instead.
///
/// # Invariants
///
/// For any `a`:
///
/// * if there exists `b` such that `b > a`, it is safe to call `Step::forward_unchecked(a, 1)`
/// * if there exists `b`, `n` such that `steps_between(&a, &b) == Some(n)`,
/// it is safe to call `Step::forward_unchecked(a, m)` for any `m <= n`.
///
/// For any `a` and `n`, where no overflow occurs:
///
/// * `Step::forward_unchecked(a, n)` is equivalent to `Step::forward(a, n)`
#[unstable(feature = "unchecked_math", reason = "niche optimization path", issue = "none")]
unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
Step::forward(start, count)
}
/// Returns the value that would be obtained by taking the *successor*
/// of `self` `count` times.
///
/// If this would overflow the range of values supported by `Self`, returns `None`.
///
/// # Invariants
///
/// For any `a`, `n`, and `m`:
///
/// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == n.checked_add(m).and_then(|x| Step::backward_checked(a, x))`
/// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == try { Step::backward_checked(a, n.checked_add(m)?) }`
///
/// For any `a` and `n`:
///
/// * `Step::backward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::backward_checked(&x, 1))`
/// * Corollary: `Step::backward_checked(&a, 0) == Some(a)`
fn backward_checked(start: Self, count: usize) -> Option<Self>;
/// Returns the value that would be obtained by taking the *predecessor*
/// of `self` `count` times.
///
/// If this would overflow the range of values supported by `Self`,
/// this function is allowed to panic, wrap, or saturate.
/// The suggested behavior is to panic when debug assertions are enabled,
/// and to wrap or saturate otherwise.
///
/// Unsafe code should not rely on the correctness of behavior after overflow.
///
/// # Invariants
///
/// For any `a`, `n`, and `m`, where no overflow occurs:
///
/// * `Step::backward(Step::backward(a, n), m) == Step::backward(a, n + m)`
///
/// For any `a` and `n`, where no overflow occurs:
///
/// * `Step::backward_checked(a, n) == Some(Step::backward(a, n))`
/// * `Step::backward(a, n) == (0..n).fold(a, |x, _| Step::backward(x, 1))`
/// * Corollary: `Step::backward(a, 0) == a`
/// * `Step::backward(a, n) <= a`
/// * `Step::forward(Step::backward(a, n), n) == a`
fn backward(start: Self, count: usize) -> Self {
Step::backward_checked(start, count).expect("overflow in `Step::backward`")
}
/// Returns the value that would be obtained by taking the *predecessor*
/// of `self` `count` times.
///
/// # Safety
///
/// It is undefined behavior for this operation to overflow the
/// range of values supported by `Self`. If you cannot guarantee that this
/// will not overflow, use `backward` or `backward_checked` instead.
///
/// # Invariants
///
/// For any `a`:
///
/// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)`
/// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`,
/// it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`.
///
/// For any `a` and `n`, where no overflow occurs:
///
/// * `Step::backward_unchecked(a, n)` is equivalent to `Step::backward(a, n)`
#[unstable(feature = "unchecked_math", reason = "niche optimization path", issue = "none")]
unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
Step::backward(start, count)
}
}
```
Note that all of these are associated functions and not callable via method syntax; the calling syntax is always `Step::forward(start, n)`. This version of the trait additionally changes the stepping functions to talk their arguments by value.
As opposed to previous attempts which provided a "step by one" method directly, this version of the trait only exposes "step by n". There are a few reasons for this:
- `Range*`, the primary consumer of `Step`, assumes that the "step by n" operation is cheap. If a single step function is provided, it will be a lot more enticing to implement "step by n" as n repeated calls to "step by one". While this is not strictly incorrect, this behavior would be surprising for anyone used to using `Range<{primitive integer}>`.
- With a trivial default impl, this can be easily added backwards-compatibly later.
- The debug-wrapping "step by n" needs to exist for `RangeFrom` to be consistent between "step by n" and "step by one" operation. (Note: the behavior is not changed by this PR, but making the behavior consistent is made tenable by this PR.)
Three "kinds" of step are provided: `_checked`, which returns an `Option` indicating attempted overflow; (unsuffixed), which provides "safe overflow" behavior (is allowed to panic, wrap, or saturate, depending on what is most convenient for a given type); and `_unchecked`, which is a version which assumes overflow does not happen.
Review is appreciated to check that:
- The invariants as described on the `Step` functions are enough to specify the "common sense" consistency for successor/predecessor.
- Implementation of `Step` functions is correct in the face of overflow and the edges of representable integers.
- Added tests of `Step` functions are asserting the correct behavior (and not just the implemented behavior).
Minor fixes to comments
* In 'src/librustc_ast_passes/node_count.rs'
* typo fix ('rought' -> 'rough')
* In 'src/librustc_middle/middle/region.rs',
* fixed broken link to 'rustc-dev-guide'
* typo fix ('aluded' -> 'alluded')
Thank you for reviewing this PR :)
Forbid stage arguments to check
Users generally expect that check builds are fast, and that's only true in stage
0 (stages beyond that need us to build a compiler, which is slow).
Closes#69337
r? @alexcrichton
Provide separate option for std debug asserts
On local one-off benchmarking of libcore metadata-only, debug asserts in std are a significant hit (15s to 20s). Provide an option for compiler developers to disable them. A build with a nightly compiler is around 10s, for reference.
Add built in PSP target
This adds a new target, `mipsel-sony-psp`, corresponding to the Sony PSP. The linker script is necessary to handle special sections, which are required by the target. This has been tested with my [rust-psp] crate and I can confirm it works as intended.
The linker script is taken from [here]. It has been slightly adapted to work with rust and LLD.
The `stdarch` submodule was also updated in order for `libcore` to build successfully.
[rust-psp]: https://github.com/overdrivenpotato/rust-psp
[here]: https://github.com/pspdev/pspsdk/blob/master/src/base/linkfile.prx.in
Use min_specialization in liballoc
- Remove a type parameter from `[A]RcFromIter`.
- Remove an implementation of `[A]RcFromIter` that didn't actually
specialize anything.
- Remove unused implementation of `IsZero` for `Option<&mut T>`.
- Change specializations of `[A]RcEqIdent` to use a marker trait version
of `Eq`.
- Remove `BTreeClone`. I couldn't find a way to make this work with
`min_specialization`.
- Add `rustc_unsafe_specialization_marker` to `Copy` and `TrustedLen`.
After this only libcore is the only standard library crate using `feature(specialization)`.
cc #31844
* In 'src/librustc_ast_passes/node_count.rs'
* typo fix ('rought' -> 'rough')
* In 'src/librustc_middle/middle/region.rs',
* fixed broken link to 'rustc-dev-guide'
* typo fix ('aluded' -> 'alluded')
Thank you for reviewing this PR :)
Rollup of 8 pull requests
Successful merges:
- #71910 (Fix unused_parens false positive when using binary operations)
- #72087 (Fix hang in lexical_region_resolve)
- #72126 (Change `WorkProduct::saved_files` to an `Option`.)
- #72127 (add long error explanation for E0228)
- #72141 (Warn against thread::sleep in async fn)
- #72170 (use `require_lang_item` over `unwrap`.)
- #72191 (Clean up E0589 explanation)
- #72194 (Don't ICE on missing `Unsize` impl)
Failed merges:
r? @ghost
Don't ICE on missing `Unsize` impl
Previously code of the form
```rust
#![feature(unsize, dispatch_from_dyn)]
use std::marker::Unsize;
use std::ops::DispatchFromDyn;
pub struct Foo<'a, T: ?Sized> {
_inner: &'a &'a T,
}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {}
```
would generate an ICE due to the missing `Unsize` impl being run through the `suggest_change_mut` suggestion. This PR adds an early exit and a pointer to the appropriate docs regarding `Unsize` instead:
```
error[E0277]: the trait bound `&'a T: std::marker::Unsize<&'a U>` is not satisfied
--> src/test/ui/issues/issue-71036.rs:11:1
|
11 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unsize<&'a U>` is not implemented for `&'a T`
|
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
= note: required because of the requirements on the impl of `std::ops::DispatchFromDyn<&'a &'a U>` for `&'a &'a T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
```
r? @estebank
Resolves#71036
use `require_lang_item` over `unwrap`.
Does not yet replace all uses of `lang_items\(\)\.*\.unwrap\(\)`, as there are more
than I expected 😅Fixes#72099
r? @RalfJung
*edit: The goal of this this PR is to change ICE from missing lang items to a fatal error.*
Warn against thread::sleep in async fn
I've seen `thread::sleep` wrecking havoc in async servers. There's already an [issue for clippy](https://github.com/rust-lang/rust-clippy/issues/4377), but the std docs could warn against it too.
add long error explanation for E0228
Add long explanation for the E0228 error code
Part of #61137
Let me know if this is wrong at all (or can be written more clearly), I'm still learning Rust.
* Update Javascript to take this change into account
* Update CrateData::aliases field to take a reference instead (it allowed to remove a conversion loop)
Update books
## book
2 commits in e37c0e84e2ef73d3a4ebffda8011db6814a3b02d..6247be15a7f7509559f7981ee2209b9e0cc121df
2020-04-26 09:31:36 -0500 to 2020-05-03 10:55:09 -0500
- Fix guessing game listing explanation (rust-lang/book#2321)
- Update ch01-01-installation.md (rust-lang/book#2325)
## edition-guide
1 commits in 8204c1d123472cd17f0c1c5c77300ae802eb0271..49270740c7a4bff2763e6bc730b191d45b7d5167
2020-04-09 18:55:50 -0700 to 2020-05-11 08:50:29 -0500
- Use rust-lang/rust linkchecker on CI. (rust-lang/edition-guide#197)
## embedded-book
1 commits in 40beccdf1bb8eb9184a2e3b42db8b8c6e394247f..366c50a03bed928589771eba8a6f18e0c0c01d23
2020-04-26 17:44:14 +0000 to 2020-05-07 09:04:42 +0000
- Add HAL patterns/guidelines/recommendations (rust-embedded/book#235)
## nomicon
3 commits in 4d2d275997746d35eabfc4d992dfbdcce2f626ed..d1517d4e3f29264c5c67bce2658516bb5202c800
2020-04-27 10:24:52 -0400 to 2020-05-12 13:47:00 -0400
- Rename Unique::empty to Unique::dangling
- Use simpler link syntax
- Replace catch_panic by catch_unwind
## reference
3 commits in ed22e6fbfcb6ce436e9ea3b4bb4a55b2fb50a57e..892b928b565e35d25b6f9c47faee03b94bc41489
2020-04-24 12:46:22 -0700 to 2020-05-11 11:13:51 -0700
- clarify that str data must still be initialized
- remove language-level UB for non-UTF-8 str
- Replace incorrect term "parent modules" with "ancestor modules". (rust-lang/reference#806)
## rust-by-example
2 commits in ffc99581689fe2455908aaef5f5cf50dd03bb8f5..ab072b14393cbd9e8a1d1d75879bf51e27217bbb
2020-04-24 15:05:04 -0300 to 2020-05-09 08:46:39 -0300
- Fix link of formatting traits (rust-lang/rust-by-example#1346)
- Remove stale footnote (rust-lang/rust-by-example#1345)