Fix issue #50811 (`NaN > NaN` was true).
Fix#50811
Make sure the float comparison output is consistent with the expected behavior when NaN is involved.
----
Note: This PR is a **BREAKING CHANGE**. If you have used `>` or `>=` to compare floats, and make the result as the length of a fixed array type, like:
```rust
use std::f64::NAN;
let x: [u8; (NAN > NAN) as usize] = [1];
```
then the code will no longer compile. Previously, all float comparison involving NaN will just return "Greater", i.e. `NAN > NAN` would wrongly return `true` during const evaluation. If you need to retain the old behavior (why), you may replace `a > b` with `a != a || b != b || a > b`.
rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants".
Previously, constants in array lengths and enum variant discriminants were "merely an expression", and had no separate ID for, e.g. type-checking or const-eval, instead reusing the expression's.
That complicated code working with bodies, because such constants were the only special case where the "owner" of the body wasn't the HIR parent, but rather the same node as the body itself.
Also, if the body happened to be a closure, we had no way to allocate a `DefId` for both the constant *and* the closure, leading to *several* bugs (mostly ICEs where type errors were expected).
This PR rectifies the situation by adding another (`{ast,hir}::AnonConst`) node around every such constant. Also, const generics are expected to rely on the new `AnonConst` nodes, as well (cc @varkor).
* fixes#48838
* fixes#50600
* fixes#50688
* fixes#50689
* obsoletes #50623
r? @nikomatsakis
Implement [T]::align_to
Note that this PR deviates from what is accepted by RFC slightly by making `align_offset` to return an offset in elements, rather than bytes. This is necessary to sanely support `[T]::align_to` and also simply makes more sense™. The caveat is that trying to align a pointer of ZST is now an equivalent to `is_aligned` check, rather than anything else (as no number of ZST elements will align a misaligned ZST pointer).
It also implements the `align_to` slightly differently than proposed in the RFC to properly handle cases where size of T and U aren’t co-prime.
Furthermore, a promise is made that the slice containing `U`s will be as large as possible (contrary to the RFC) – otherwise the function is quite useless.
The implementation uses quite a few underhanded tricks and takes advantage of the fact that alignment is a power-of-two quite heavily to optimise the machine code down to something that results in as few known-expensive instructions as possible. Currently calling `ptr.align_offset` with an unknown-at-compile-time `align` results in code that has just a single "expensive" modulo operation; the rest is "cheap" arithmetic and bitwise ops.
cc https://github.com/rust-lang/rust/issues/44488 @oli-obk
As mentioned in the commit message for align_offset, many thanks go to Chris McDonald.
Implement edition hygiene for keywords
Determine "keywordness" of an identifier in its hygienic context.
cc https://github.com/rust-lang/rust/pull/49611
I've resurrected `proc` as an Edition-2015-only keyword for testing purposes, but it should probably be buried again. EDIT: `proc` is removed again.
stop considering location when computing outlives relationships
This doesn't (yet?) use SEME regions, but it does ignore the location for outlives constraints. This makes (I believe) NLL significantly faster -- but we should do some benchmarks. It regresses the "get-default" family of use cases for NLL, which is a shame, but keeps the other benefits, and thus represents a decent step forward.
r? @pnkfelix
This is necessary if we want to implement `[T]::align_to` and is more
useful in general.
This implementation effort has begun during the All Hands and represents
a month of my futile efforts to do any sort of maths. Luckily, I
found the very very nice Chris McDonald (cjm) on IRC who figured out the
core formulas for me! All the thanks for existence of this PR go to
them!
Anyway… Those formulas were mangled by yours truly into the arcane forms
you see here to squeeze out the best assembly possible on most of the
modern architectures (x86 and ARM were evaluated in practice). I mean,
just look at it: *one actual* modulo operation and everything else is
just the cheap single cycle ops! Admitedly, the naive solution might be
faster in some common scenarios, but this code absolutely butchers the
naive solution on the worst case scenario.
Alas, the result of this arcane magic also means that the code pretty
heavily relies on the preconditions holding true and breaking those
preconditions will unleash the UB-est of all UBs! So don’t.
Rollup of 17 pull requests
Successful merges:
- #50170 (Implement From for more types on Cow)
- #50638 (Don't unconditionally set CLOEXEC twice on every fd we open on Linux)
- #50656 (Fix `fn main() -> impl Trait` for non-`Termination` trait)
- #50669 (rustdoc: deprecate `#![doc(passes, plugins, no_default_passes)]`)
- #50726 (read2: Use inner function instead of closure)
- #50728 (Fix rustdoc panic with `impl Trait` in type parameters)
- #50736 (env: remove unwrap in examples in favor of try op)
- #50740 (Remove LazyBTreeMap.)
- #50752 (Add missing error codes in libsyntax-ext asm)
- #50779 (Make mutable_noalias and arg_align_attributes be tracked)
- #50787 (Fix run-make wasm tests)
- #50788 (Fix an ICE when casting a nonexistent const)
- #50789 (Ensure libraries built in stage0 have unique metadata)
- #50793 (tidy: Add a check for empty UI test files)
- #50797 (fix a typo in signed-integer::from_str_radix())
- #50808 (Stabilize num::NonZeroU*)
- #50809 (GitHub: Stop treating Cargo.lock as a generated file.)
Failed merges:
tidy: Add a check for empty UI test files
Check for empty `.stderr` and `.stdout` files in UI test directories.
Empty files could still pass testing for `compile-pass` tests with no output
so they can get into the repo accidentally, but they are not necessary and can
be removed.
This is very much an in progress pull request. I'm having an issue with rustfmt. It wanted to reformat the entire file for almost every file by default. And when I run tidy it just errors out because it catches the empty files that are already in the repo.
My next step is goin got be to remove those empty file and see if running tidy again will actually reformat things outside of the context of `cargo fmt`
Fixes https://github.com/rust-lang/rust/issues/50785
Fix `fn main() -> impl Trait` for non-`Termination` trait
Fixes#50595.
This bug currently affects stable. Why I think we can go for hard error:
- It will in stable for at most one cycle and there is no legitimate reason to abuse it, nor any known uses in the wild.
- It only affects `bin` crates (which have a `main`), so there is little practical difference between a hard error or a deny lint, both are a one line fix.
The fix was to just unshadow a variable. Thanks @nikomatsakis for the mentoring!
r? @nikomatsakis
Fix self referential impl Trait substitutions
A high impact bug because a lot of common traits use a `Self` substitution by default. Should be backported to beta.
There was a check for this which wasn't catching all cases, it was made more robust.
Fixes#49376Fixes#50626
r? @petrochenkov
rustc: leave space for fields of uninhabited types to allow partial initialization.
Fixes#49298 by only collapsing uninhabited enum variants, and only if they only have ZST fields.
Fixes#50442 incidentally (@nox's optimization didn't take into account uninhabited variants).
A high impact bug because a lot of common traits use a `Self`
substitution by default. Should be backported to beta.
There was a check for this which wasn't catching all cases, it was made
more robust.
Fixes#49376Fixes#50626
r? @petrochenkov
Fixes#50595.
This bug currently affects stable. Why I think we can go for hard error:
- It will in stable for at most one cycle and there is no legitimate
reason to abuse it, nor any known uses in the wild.
- It only affects `bin` crates (which have a `main`), so there is
little practical difference between a hard error or a deny lint, both
are a one line fix.
The fix was to just unshadow a variable. Thanks @nikomatsakis for the
mentoring!
r? @nikomatsakis