Rollup of 9 pull requests
Successful merges:
- #138336 (Improve `-Z crate-attr` diagnostics)
- #139636 (Encode dep node edge count as u32 instead of usize)
- #139666 (cleanup `mir_borrowck`)
- #139695 (compiletest: consistently use `camino::{Utf8Path,Utf8PathBuf}` throughout)
- #139699 (Proactively update coroutine drop shim's phase to account for later passes applied during shim query)
- #139718 (enforce unsafe attributes in pre-2024 editions by default)
- #139722 (Move some things to rustc_type_ir)
- #139760 (UI tests: migrate remaining compile time `error-pattern`s to line annotations when possible)
- #139776 (Switch attrs to `diagnostic::on_unimplemented`)
r? `@ghost`
`@rustbot` modify labels: rollup
UI tests: migrate remaining compile time `error-pattern`s to line annotations when possible
There's a number of cases in which `error-pattern` is still necessary even for compile time checking.
- It checks something that compiler writes directly into stderr as text, and not to the structured json output. This includes some stuff reported during compiler panics, and also diagnostics that happen very early, for example when parsing the command line.
- It checks something that exists only in the full rendered diagnostic test, but not in its structured components, for example code fragments or output of `-Ztrack-diagnostics`. (The latter can probably be converted to structured form though.)
This is continuation of https://github.com/rust-lang/rust/pull/139137.
r? `@jieyouxu`
enforce unsafe attributes in pre-2024 editions by default
New unsafe attributes should emit an error when used without the `unsafe(...)` in all editions.
The `no_mangle`, `link_section` and `export_name` attributes are exceptions, and can still be used without an unsafe in earlier editions. The only attributes for which this change is relevant right now are `#[ffi_const]` and `#[ffi_pure]`.
This change is required for making `#[unsafe(naked)]` sound in pre-2024 editions.
Improve `-Z crate-attr` diagnostics
- Show the `#![ ... ]` in the span (to make it clear that it should not
be included in the CLI argument)
- Show more detailed errors when the crate has valid token trees but
invalid syntax.
Previously, `crate-attr=feature(foo),feature(bar)` would just say
"invalid crate attribute" and point at the comma. Now, it explicitly
says that the comma was unexpected, which is useful when using
`--error-format=short`. It also fixes the column to show the correct
span.
- Recover from parse errors. Previously we would abort immediately on
syntax errors; now we go on to try and type-check the rest of the
crate.
The new diagnostic code also happens to be slightly shorter.
r? diagnostics
fix smir's run! doc and import
This PR
* adds missing `extern crate rustc_middle` in `rustc_smir::run!` docstring
* adds missing `use rustc_smir::rustc_internal` in `run_driver!` scope
* also adjust some tests that don't need to import rustc_internalany more
Convert `tests/ui/lint/dead-code/self-assign.rs` to a known-bug test
I did a survey pass over `tests/`, and this test seems like the only candidate suitable for conversion into a known-bug test. (Other tests had varying degrees of other issues that known-bug would not be suitable.)
r? compiler
Use delayed bug for normalization errors in drop elaboration
Normalization can fail due to a lot of different earlier errors, so just use span_delayed_bug if normalization failed.
Closes#137287Closes#135668
r? compiler-errors
add `naked_functions_rustic_abi` feature gate
tracking issue: https://github.com/rust-lang/rust/issues/138997
Because the details of the rust abi are unstable, and a naked function must match its stated ABI, this feature gate keeps naked functions with a rustic abi ("Rust", "rust-cold", "rust-call" and "rust-intrinsic") unstable.
r? ````@traviscross````
Initial `UnsafePinned` implementation [Part 1: Libs]
Initial libs changes necessary to unblock further work on [RFC 3467](https://rust-lang.github.io/rfcs/3467-unsafe-pinned.html).
Tracking issue: #125735
This PR is split off from #136964, and includes just the libs changes:
- `UnsafePinned` struct
- private `UnsafeUnpin` structural auto trait
- Lang items for both
- Compiler changes necessary to block niches on `UnsafePinned`
This PR does not change codegen, miri, the existing `!Unpin` hack, or anything else. That work is to be split into later PRs.
---
cc ``@RalfJung`` ``@Noratrieb``
``@rustbot`` label F-unsafe_pinned T-libs-api
- Show the `#![ ... ]` in the span (to make it clear that it should not
be included in the CLI argument)
- Show more detailed errors when the crate has valid token trees but
invalid syntax.
Previously, `crate-attr=feature(foo),feature(bar)` would just say
"invalid crate attribute" and point at the comma. Now, it explicitly
says that the comma was unexpected, which is useful when using
`--error-format=short`. It also fixes the column to show the correct
span.
- Recover from parse errors. Previously we would abort immediately on
syntax errors; now we go on to try and type-check the rest of the
crate.
The new diagnostic code also happens to be slightly shorter.
Move `select_unpredictable` to the `hint` module
There has been considerable discussion in both the ACP (rust-lang/libs-team#468) and tracking issue (#133962) about whether the `bool::select_unpredictable` method should be in `core::hint` instead.
I believe this is the right move for the following reasons:
- The documentation explicitly says that it is a hint, not a codegen guarantee.
- `bool` doesn't have a corresponding `select` method, and I don't think we should be adding one.
- This shouldn't be something that people reach for with auto-completion unless they specifically understand the interactions with branch prediction. Using conditional moves can easily make code *slower* by preventing the CPU from speculating past the condition due to the data dependency.
- Although currently `core::hint` only contains no-ops, this isn't a hard rule (for example `unreachable_unchecked` is a bit of a gray area). The documentation only status that the module contains "hints to compiler that affects how code should be emitted or optimized". This is consistent with what `select_unpredictable` does.
compiletest: Make `SUGGESTION` annotations viral
If one of them is expected in a test file, then others should be annotated as well, in the same way as with `HELP`s and `NOTE`s.
This doesn't require much of an additional annotation burden, but simplifies the rules.
r? ```@jieyouxu```
Use the chaining methods on PartialOrd for slices too
#138135 added these doc-hidden trait methods to improve the tuple codegen. This PR adds more implementations and callers so that the codegen for slice (and array) comparisons also improves.
Rollup of 6 pull requests
Successful merges:
- #139107 (std: make `cmath` functions safe)
- #139607 (Add regression test for #127424)
- #139691 (Document that `opt-dist` requires metrics to be enabled)
- #139707 (Fix comment in bootstrap)
- #139708 (Fix name of field in doc comment)
- #139709 (bootstrap: fix typo in doc string)
r? `@ghost`
`@rustbot` modify labels: rollup
Add regression test for #127424
Fixes: https://github.com/rust-lang/rust/issues/127424
This ICE no longer reproduces, so it appears to have already been fixed.
This PR adds a regression test to ensure the issue doesn’t come back in the future.
Please let me know if there's anything I should improve or revise!
Removed outdated ui test suite README, give reasons for disabled tests
### Changes
- `tests/ui/README.md` is very outdated, test suite docs should consistently live in rustc-dev-guide.
- Add reasons for `//@ ignore-test` tests that don't have one.[^query]
This is a precursor change to make follow-up changes easier (possibly more specialized directives or converting some auxiliaries into the canonical `auxiliary/` form).
[^query]: searched via `rg --no-ignore -F -e "ignore-test" tests/`.
run-make-support: Calculate artifact names for target platform, not host platform
This was implemented incorrectly during the porting process, where we relied on std consts. However, `run-make-support` is a host-only library, which meant that these artifact names were for the *host* and not the *target*.
Helps with #138066.
r? `@Kobzol`
try-job: armhf-gnu
try-job: test-various
try-job: x86_64-msvc-1
try-job: i686-msvc-1
try-job: x86_64-mingw-1
try-job: aarch64-apple
try-job: x86_64-apple-1
Some tests fail on cross-compiled targets due to various linker problems
on cross-compiled target, and having test coverage for these against
cross-compiled targets is nice but not necessary.
Post merge analysis / analysis (push) Has been cancelled
Polymorphize `array::IntoIter`'s iterator impl
Today we emit all the iterator methods for every different array width. That's wasteful since the actual array length never even comes into it -- the indices used are from the separate `alive: IndexRange` field, not even the `N` const param.
This PR switches things so that an `array::IntoIter<T, N>` stores a `PolymorphicIter<[MaybeUninit<T>; N]>`, which we *unsize* to `PolymorphicIter<[MaybeUninit<T>]>` and call methods on that non-`Sized` type for all the iterator methods.
That also necessarily makes the layout consistent between the different lengths of arrays, because of the unsizing. Compare that to today <https://rust.godbolt.org/z/Prb4xMPrb>, where different widths can't even be deduped because the offset to the indices is different for different array widths.
Prepend temp files with per-invocation random string to avoid temp filename conflicts
https://github.com/rust-lang/rust/issues/139407 uncovered a very subtle unsoundness with incremental codegen, failing compilation sessions (due to assembler errors), and the "prefer hard linking over copying files" strategy we use in the compiler for file management.
Specifically, imagine we're building a single file 3 times, all with `-Csave-temps -Cincremental=...`. Let's call the object file we're building for the codegen unit for `main` "`XXX.o`" just for clarity since it's probably some gigantic hash name:
```
#[inline(never)]
#[cfg(any(rpass1, rpass3))]
fn a() -> i32 {
0
}
#[cfg(any(cfail2))]
fn a() -> i32 {
1
}
fn main() {
evil::evil();
assert_eq!(a(), 0);
}
mod evil {
#[cfg(any(rpass1, rpass3))]
pub fn evil() {
unsafe {
std::arch::asm!("/* */");
}
}
#[cfg(any(cfail2))]
pub fn evil() {
unsafe {
std::arch::asm!("missing");
}
}
}
```
Session 1 (`rpass1`):
* Type-check, borrow-check, etc.
* Serialize the dep graph to the incremental working directory `.../s-...-working/`.
* Codegen object file to a temp file `XXX.rcgu.o` which is spit out in the cwd.
* Hard-link[^1] `XXX.rcgu.o` to the incremental working directory `.../s-...-working/XXX.o`.
* Save-temps option means we don't delete `XXX.rgcu.o`.
* Link the binary and stuff.
* Finalize[^2] the working incremental session by renaming `.../s-...-working` to ` s-...-asjkdhsjakd` (some other finalized incr comp session dir name).
Session 2 (`cfail2`):
* Load artifacts from the previous *finalized* incremental session, namely the dep graph.
* Type-check, borrow-check, etc. since the file has changed, so most dep graph nodes are red.
* Serialize the dep graph to the incremental working directory `.../s-...-working/`.
* Codegen object file to a temp file `XXX.rcgu.o`. **HERE IS THE PROBLEM**: The hard-link is still set up to point to the inode from `XXX.o` from the first session, so this also modifies the `XXX.o` in the previous finalized session directory.
* Codegen emits an error b/c `missing` is not an instruction, so we abort before finalizing the incremental session. Specifically, this means that the *previous* session is the last finalized session.
Session 3 (`rpass3`):
* Load artifacts from the previous *finalized* incremental session, namely the dep graph. NOTE that this is from session 1.
* All the dep graph nodes are green since we are basically replaying session 1.
* codegen object file `XXX.o`, which is detected as *reused* from session 1 since dep nodes were green. That means we **reuse** `XXX.o` which had been dirtied from session 2.
* Link the binary and stuff.
This results in a binary which reuses some of the build artifacts from session 2, but thinks it's from session 1.
At this point, I hope it's clear to see that the incremental results from session 1 were dirtied from session 2, but we reuse them as if session 1 was the previous (finalized) incremental session we ran. This is at best really buggy, and at worst **unsound**.
This isn't limited to `-C save-temps`, since there are other combinations of flags that may keep around temporary files (hard linked) in the working directory (like `-C debuginfo=1 -C split-debuginfo=unpacked` on darwin, for example).
---
This PR implements a fix which is to prepend temp filenames with a random string that is generated per invocation of rustc. This string is not *deterministic*, but temporary files are transient anyways, so I don't believe this is a problem.
That means that temp files are now something like... `{crate-name}.{cgu}.{invocation_temp}.rcgu.o`, where `{invocation_temp}` is the new temporary string we generate per invocation of rustc.
Fixes https://github.com/rust-lang/rust/issues/139407
[^1]: 175dcc7773/compiler/rustc_fs_util/src/lib.rs (L60)
[^2]: 175dcc7773/compiler/rustc_incremental/src/persist/fs.rs (L1-L40)
Fix breakage when running compiletest with `--test-args=--edition=2015`
Compiletest has an `--edition` flag to change the default edition tests are run with. Unfortunately no test suite successfully executes when that flag is passed. If the edition is set to something greater than 2015 the breakage is expected, since the test suite currently supports only edition 2015 (Ferrous Systems will open an MCP about fixing that soonish). Surprisingly, the test suite is also broken if `--edition=2015` is passed to compiletest. This PR focuses on fixing the latter.
This PR fixes the two categories of failures happening when `--edition=2015` is passed:
* Some edition-specific tests set their edition through `//@ compile-flags` instead of `//@ edition`. Compiletest doesn't parse the compile flags, so it would see no `//@ edition` and add another `--edition` flag, leading to a rustc error.
* Compiletest would add the edition after `//@ compile-flags`, while some tests depend on flags passed to `//@ compile-flags` being the last flags in the rustc invocation.
Note that for the first category, I opted to manually go and replace all `//@ compile-flags` setting an edition with an explicit `//@ edition`. We could've changed compiletest to instead check whether an edition was set in `//@ compile-flags`, but I thought it was better to enforce a consistent way to set the edition in tests.
I also added the edition to the stamp, so that changing `--edition` results in tests being re-executed.
r? `@jieyouxu`