Rollup of 5 pull requests
Successful merges:
- #113241 (rustdoc: Document lack of object safety on affected traits)
- #117388 (Turn const_caller_location from a query to a hook)
- #117417 (Add a stable MIR visitor)
- #117439 (prepopulate opaque ty storage before using it)
- #117451 (Add support for pre-unix-epoch file dates on Apple platforms (#108277))
r? `@ghost`
`@rustbot` modify labels: rollup
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>
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.
Allows `#[diagnostic::on_unimplemented]` attributes to have multiple
notes
This commit extends the `#[diagnostic::on_unimplemented]` (and `#[rustc_on_unimplemented]`) attributes to allow multiple `note` options. This enables emitting multiple notes for custom error messages. For now I've opted to not change any of the existing usages of `#[rustc_on_unimplemented]` and just updated the relevant compile tests.
r? `@compiler-errors`
I'm happy to adjust any of the existing changed location to emit the old error message if that's desired.
Increase the reach of panic_immediate_abort
I wanted to use/abuse this recently as part of another project, and I was surprised how many panic-related things were left in my binaries if I built a large crate with the feature enabled along with LTO. These changes get all the panic-related symbols that I could find out of my set of locally installed Rust utilities.
memcpy assumptions: link to source showing that GCC makes the same assumption
I finally stumbled upon a source showing that GCC also generates overlapping `memcpy`. So if we're linking major C compilers making such assumptions here, let's have both clang and GCC.
Don't use LFS64 symbols on musl
Supersedes #106246
~~Note to packagers: If your distro's musl package has already been updated, then you won't be able to build a newer version of rust until a new rust release is made with these changes merged (which can be used to bootstrap). I'm using a super hacky method to bypass this by creating a stub library with LFS64 symbols and building a patched rust, so the symbols satisfy the build requirements while the final compiler build has no references to LFS64 symbols, example: https://codeberg.org/kiss-community/repo/pulls/160/files~~ Doesn't seem to be necessary with new rustup nightly builds, likely due to updates to vendored crates
cc ```@alyssais```
Bump stdarch submodule and remove special handling for LLVM intrinsics that are no longer needed
Bumps stdarch to pull https://github.com/rust-lang/stdarch/pull/1477, which reimplemented some functions with portable SIMD intrinsics instead of arch specific LLVM intrinsics.
Handling of those LLVM intrinsics is removed from cranelift codegen and miri.
cc `@RalfJung` `@bjorn3`
Create `windows/api.rs` for safer FFI
FFI is inherently unsafe. For memory safety we need to assert that some contract is being upheld on both sides of the FFI, though of course we can only ever check our side. In Rust, `unsafe` blocks are used to assert safety and `// SAFETY` comments describing why it is safe. Currently in sys/windows we have a lot of this unsafety spread all over the place, with variations on the same unsafe patterns repeated. And because of the repitition and frequency, we're a bit lax with the safety comments.
This PR aims to fix this and to make FFI safety more auditable by creating an `api` module with the goal of centralising and consolidating this unsafety. It contains thin wrappers around the Windows API that make most functions safe to call or, if that's not possible, then at least safer. Note that its goal is *only* to address safety. It does not stray far from the Windows API and intentionally does not attempt to make higher lever wrappers around, for example, file handles. This is better left to the existing modules. The windows/api.rs file has a top level comment to help future contributors understand the intent of the module and the design decisions made.
I chose two functions as a first tentative step towards the above goal:
- [`GetLastError`](https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) is trivially safe. There's no reason to wrap it in an `unsafe` block every time. So I simply created a safe `get_last_error` wrapper.
- [`SetFileInformationByHandle`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileinformationbyhandle) is more complex. It essentially takes a generic type but over a C API which necessitates some amount of ceremony. Rather than implementing similar unsafe patterns in multiple places, I provide a safe `set_file_information_by_handle` that takes a Rusty generic type and handles converting that to the form required by the C FFI.
r? libs
Hide internal methods from documentation
The two methods here are perma-unstable and only made public for technical reasons. There is no reason to show them in documentation.
`@rustbot` label +A-docs
notes
This commit extends the `#[diagnostic::on_unimplemented]` (and
`#[rustc_on_unimplemented]`) attributes to allow multiple `note`
options. This enables emitting multiple notes for custom error messages.
For now I've opted to not change any of the existing usages of
`#[rustc_on_unimplemented]` and just updated the relevant compile tests.
Rollup of 6 pull requests
Successful merges:
- #114998 (feat(docs): add cargo-pgo to PGO documentation 📝)
- #116868 (Tweak suggestion span for outer attr and point at item following invalid inner attr)
- #117240 (Fix documentation typo in std::iter::Iterator::collect_into)
- #117241 (Stash and cancel cycle errors for auto trait leakage in opaques)
- #117262 (Create a new ConstantKind variant (ZeroSized) for StableMIR)
- #117266 (replace transmute by raw pointer cast)
r? `@ghost`
`@rustbot` modify labels: rollup
Refactor some `char`, `u8` ASCII functions to be branchless
Extract conditions in singular `matches!` with or-patterns to individual `matches!` statements which enables branchless code output. The following functions were changed:
- `is_ascii_alphanumeric`
- `is_ascii_hexdigit`
- `is_ascii_punctuation`
Added codegen tests
---
Continued from https://github.com/rust-lang/rust/pull/103024.
Based on the comment from `@scottmcm` https://github.com/rust-lang/rust/pull/103024#pullrequestreview-1248697206.
The unmodified `is_ascii_*` functions didn't seem to benefit from extracting the conditions.
I've never written a codegen test before, but I tried to check that no branches were emitted.
Decompose singular `matches!` with or-patterns to individual `matches!`
statements to enable branchless code output. The following functions
were changed:
- `is_ascii_alphanumeric`
- `is_ascii_hexdigit`
- `is_ascii_punctuation`
Add codegen tests
Co-authored-by: George Bateman <george.bateman16@gmail.com>
Co-authored-by: scottmcm <scottmcm@users.noreply.github.com>
Explain implementation of mem::replace
This adds a comment to explain why `mem::replace` is not implemented in terms of `mem::swap` to prevent [naïfs like me](https://github.com/rust-lang/rust/pull/117189) from trying to "fix" it.
Rework negative coherence to properly consider impls that only partly overlap
This PR implements a modified negative coherence that handles impls that only have partial overlap.
It does this by:
1. taking both impl trait refs, instantiating them with infer vars
2. equating both trait refs
3. taking the equated trait ref (which represents the two impls' intersection), and resolving any vars
4. plugging all remaining infer vars with placeholder types
these placeholder-plugged trait refs can then be used normally with the new trait solver, since we no longer have to worry about the issue with infer vars in param-envs.
We use the **new trait solver** to reason correctly about unnormalized trait refs (due to deferred projection equality), since this avoid having to normalize anything under param-envs with infer vars in them.
This PR then additionally:
* removes the `FnPtr` knowable hack by implementing proper negative `FnPtr` trait bounds for rigid types.
---
An example:
Consider these two partially overlapping impls:
```
impl<T, U> PartialEq<&U> for &T where T: PartialEq<U> {}
impl<F> PartialEq<F> for F where F: FnPtr {}
```
Under the old algorithm, we would take one of these impls and replace it with infer vars, then try unifying it with the other impl under identity substitutions. This is not possible in either direction, since it either sets `T = U`, or tries to equate `F = &?0`.
Under the new algorithm, we try to unify `?0: PartialEq<?0>` with `&?1: PartialEq<&?2>`. This gives us `?0 = &?1 = &?2` and thus `?1 = ?2`. The intersection of these two trait refs therefore looks like: `&?1: PartialEq<&?1>`. After plugging this with placeholders, we get a trait ref that looks like `&!0: PartialEq<&!0>`, with the first impl having substs `?T = ?U = !0` and the second having substs `?F = &!0`[^1].
Then we can take the param-env from the first impl, and try to prove the negated where clause of the second.
We know that `&!0: !FnPtr` never holds, since it's a rigid type that is also not a fn ptr, we successfully detect that these impls may never overlap.
[^1]: For the purposes of this example, I just ignored lifetimes, since it doesn't really matter.
Rollup of 7 pull requests
Successful merges:
- #117111 (Remove support for alias `-Z instrument-coverage`)
- #117141 (Require target features to match exactly during inlining)
- #117152 (Fix unwrap suggestion for async fn)
- #117154 (implement C ABI lowering for CSKY)
- #117159 (Work around the fact that `check_mod_type_wf` may spuriously return `ErrorGuaranteed`)
- #117163 (compiletest: Display compilation errors in mir-opt tests)
- #117173 (Make `Iterator` a lang item)
r? `@ghost`
`@rustbot` modify labels: rollup
The branchy Hoare partition `partition_equal` as part of `slice::sort_unstable`
has a bug that makes it perform a comparison of the last element twice.
Measuring inputs with a Zipfian distribution with characterizing exponent s ==
1.0, yields a ~0.05% reduction in the total number of comparisons performed.