Add support for pre-unix-epoch file dates on Apple platforms (#108277)
Please note that even though the assertion being hit is the same on MacOS and thus similar to what's described in #108277, on MacOS it's possible to convert the numbers such that they are valid, don't hit the assertion and are round-trippable.
Doing so effectively fixes the issue on Apple platforms.
This PR does not attempt to harden other platforms against negative nanoseconds, which can happen for many reasons including mild filesystem corruption.
----
Time in UNIX system calls counts from the epoch, 1970-01-01. The timespec
struct used in various system calls represents this as a number of seconds and
a number of nanoseconds. Nanoseconds are required to be between 0 and
999_999_999, because the portion outside that range should be represented in
the seconds field; if nanoseconds were larger than 999_999_999, the seconds
field should go up instead.
Suppose you ask for the time 1969-12-31, what time is that? On UNIX systems
that support times before the epoch, that's seconds=-86400, one day before the
epoch. But now, suppose you ask for the time 1969-12-31 23:59:00.1. In other
words, a tenth of a second after one minute before the epoch. On most UNIX
systems, that's represented as seconds=-60, nanoseconds=100_000_000. The macOS
bug is that it returns seconds=-59, nanoseconds=-900_000_000.
While that's in some sense an accurate description of the time (59.9 seconds
before the epoch), that violates the invariant of the timespec data structure:
nanoseconds must be between 0 and 999999999. This causes this assertion in the
Rust standard library.
So, on macOS, if we get a Timespec value with seconds less than or equal to
zero, and nanoseconds between -999_999_999 and -1 (inclusive), we can add
1_000_000_000 to the nanoseconds and subtract 1 from the seconds, and then
convert. The resulting timespec value is still accepted by macOS, and when fed
back into the OS, produces the same results. (If you set a file's mtime with
that timestamp, then read it back, you get back the one with negative
nanoseconds again.)
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
prepopulate opaque ty storage before using it
doesn't have any significant impact rn afaict, as we freely define new opaque types during MIR typeck.
It will be relevant with #117278 and once we stop allowing the definition of new opaques in MIR typeck
r? `@compiler-errors`
rustdoc: Document lack of object safety on affected traits
Closes#85138
I saw the issue didn't have any recent activity, if there is another MR for it I missed it.
I want the issue to move forward so here is my proposition.
It takes some space just before the "Implementors" section and only if the trait is **not** object
safe since it is the only case where special care must be taken in some cases and this has the
benefit of avoiding generation of HTML in (I hope) the common case.
Accept less invalid Rust in rustdoc
pulled out of https://github.com/rust-lang/rust/pull/117213 where this change was already approved
This only affects rustdoc, and has up to [20% perf regressions in rustdoc](https://github.com/rust-lang/rust/pull/117213#issuecomment-1785776288). These are unavoidable, as we are simply doing more checks now, but it's part of the longer term plan of making rustdoc more resistant to ICEs by only accepting valid Rust code.
Time in UNIX system calls counts from the epoch, 1970-01-01. The timespec
struct used in various system calls represents this as a number of seconds and
a number of nanoseconds. Nanoseconds are required to be between 0 and
999_999_999, because the portion outside that range should be represented in
the seconds field; if nanoseconds were larger than 999_999_999, the seconds
field should go up instead.
Suppose you ask for the time 1969-12-31, what time is that? On UNIX systems
that support times before the epoch, that's seconds=-86400, one day before the
epoch. But now, suppose you ask for the time 1969-12-31 23:59:00.1. In other
words, a tenth of a second after one minute before the epoch. On most UNIX
systems, that's represented as seconds=-60, nanoseconds=100_000_000. The macOS
bug is that it returns seconds=-59, nanoseconds=-900_000_000.
While that's in some sense an accurate description of the time (59.9 seconds
before the epoch), that violates the invariant of the timespec data structure:
nanoseconds must be between 0 and 999999999. This causes this assertion in the
Rust standard library.
So, on macOS, if we get a Timespec value with seconds less than or equal to
zero, and nanoseconds between -999_999_999 and -1 (inclusive), we can add
1_000_000_000 to the nanoseconds and subtract 1 from the seconds, and then
convert. The resulting timespec value is still accepted by macOS, and when fed
back into the OS, produces the same results. (If you set a file's mtime with
that timestamp, then read it back, you get back the one with negative
nanoseconds again.)
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
Use derivative for `Clone`/`PartialOrd`/`Ord`/`Hash` in `rustc_type_ir`
This uses `derivative` to derive `Clone`/`PartialOrd`/`Ord`/`Hash` for types in `rustc_type_ir`. This doesn't derive `PartialEq`/`Eq` yet, because I have no idea why those are generating slower implementations from derivative.
Rollup of 5 pull requests
Successful merges:
- #116267 (Some codegen cleanups around SIMD checks)
- #116712 (When encountering unclosed delimiters during lexing, check for diff markers)
- #117416 (Also consider TAIT to be uncomputable if the MIR body is tainted)
- #117421 (coverage: Replace impossible `coverage::Error` with assertions)
- #117438 (Do not ICE on constant evaluation failure in GVN.)
r? `@ghost`
`@rustbot` modify labels: rollup
coverage: Replace impossible `coverage::Error` with assertions
Historically, these errors existed so that the coverage debug code could dump additional information before reporting a compiler bug. That debug code was removed by #115962, so we can now simplify these methods by making them panic immediately when they detect a bug.
Also consider TAIT to be uncomputable if the MIR body is tainted
Not totally sure if this is the best solution. We could, alternatively, look at the hir typeck results and try to take a type from there instead of just falling back to type error, inferring `u8` instead of `{type error}`. Not certain it really matters, though.
Happy to iterate on this.
Fixes#117413
r? ``@oli-obk`` cc ``@Nadrieril``
Historically, these errors existed so that the coverage debug code could dump
additional information before reporting a compiler bug. That debug code was
removed by #115962, so we can now simplify these methods by making them panic
when they detect a bug.
Store #[deprecated] attribute's `since` value in parsed form
This PR implements the first followup bullet listed in https://github.com/rust-lang/rust/pull/117148#issue-1960240108.
We centralize error handling to the attribute parsing code in `compiler/rustc_attr/src/builtin.rs`, and thereby remove some awkward error codepaths from later phases of compilation that had to make sense of these #\[deprecated\] attributes, namely `compiler/rustc_passes/src/stability.rs` and `compiler/rustc_middle/src/middle/stability.rs`.
The switch_stdout_to test was broken on Windows7, as the test
infrastructure would refuse to delete the temporary test folder because
the switch-stdout-output file we redirected the stdout to was still
opened.
To fix this issue, we make switch_stdout_to return the previous handle,
and add a new switch_stdout_to call at the end of the test to return the
stdio handles to their original state. The handle the second
switch_stdout_to returns will be automatically closed, which should
allow the temporary test folder to be deleted properly.
new lint: `unnecessary_fallible_conversions`
Closes#11577
A new lint that looks for calls such as `i64::try_from(1i32)` and suggests `i64::from(1i32)`. See lint description (and linked issue) for more details for why.
There's a tiny bit of overlap with the `useless_conversion` lint, in that the other one warns `T::try_from(T)` (i.e., fallibly converting to the same type), so this lint ignores cases like `i32::try_from(1i32)` to avoid emitting two warnings for the same expression.
Also, funnily enough, with this one exception, this lint would warn on exactly every case in the `useless_conversion_try` ui test that `useless_conversion` didn't cover (but never two warnings at the same time), which is neat. I did add an `#![allow]` though since we don't want interleaved warnings from multiple lints in the same uitest.
changelog: new lint: `unnecessary_fallible_conversions`
fix enum_variant_names depending lint depending on order
changelog: [`enum_variant_names`]: fix single word variants preventing lint of later variant pre/postfixed with the enum name
fixes#11494
Single word variants prevented checking the `check_enum_start` and `check_enum_end` for being run on later variants
Enable cross-crate-inlining when MIR inlining is enabled
This would make https://github.com/rust-lang/rust/issues/117355 generally less obscure, and also seems like a good idea, even if for some reason someone wants MIR opts but no codegen opts.