This patch has been extracted from #123720. It specifically enhances
`Sccs` to allow tracking arbitrary commutative properties of SCCs, including
- reachable values (max/min)
- SCC-internal values (max/min)
This helps with among other things universe computation: we can now identify
SCC universes as a straightforward "find max/min" operation during SCC construction.
It's also more or less zero-cost; don't use the new features, don't pay for them.
This commit also vastly extends the documentation of the SCCs module, which I had a very hard time following.
Rollup of 16 pull requests
Successful merges:
- #123374 (DOC: Add FFI example for slice::from_raw_parts())
- #124514 (Recommend to never display zero disambiguators when demangling v0 symbols)
- #125978 (Cleanup: HIR ty lowering: Consolidate the places that do assoc item probing & access checking)
- #125980 (Nvptx remove direct passmode)
- #126187 (For E0277 suggest adding `Result` return type for function when using QuestionMark `?` in the body.)
- #126210 (docs(core): make more const_ptr doctests assert instead of printing)
- #126249 (Simplify `[T; N]::try_map` signature)
- #126256 (Add {{target}} substitution to compiletest)
- #126263 (Make issue-122805.rs big endian compatible)
- #126281 (set_env: State the conclusion upfront)
- #126286 (Make `storage-live.rs` robust against rustc internal changes.)
- #126287 (Update a cranelift patch file for formatting changes.)
- #126301 (Use `tidy` to sort crate attributes for all compiler crates.)
- #126305 (Make PathBuf less Ok with adding UTF-16 then `into_string`)
- #126310 (Migrate run make prefer rlib)
- #126314 (fix RELEASES: we do not support upcasting to auto traits)
r? `@ghost`
`@rustbot` modify labels: rollup
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order.
- Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`.
This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`).
r? `@davidtwco`
Update a cranelift patch file for formatting changes.
PR #125443 will reformat all the use declarations in the repo. This would break a patch kept in `rustc_codegen_cranelift` that gets applied to `library/std/src/sys/pal/windows/rand.rs`.
So this commit formats the use declarations in `library/std/src/sys/pal/windows/rand.rs` in advance of #125443 and updates the patch file accordingly.
The motivation is that #125443 is a huge change and we want to get fiddly little changes like this out of the way so it can be nothing more than an `x fmt --all`.
r? ``@bjorn3``
For E0277 suggest adding `Result` return type for function when using QuestionMark `?` in the body.
Adding suggestions for following function in E0277.
```rust
fn main() {
let mut _file = File::create("foo.txt")?;
}
```
to
```rust
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut _file = File::create("foo.txt")?;
return Ok(());
}
```
According to the issue #125997, only the code examples in the issue are targeted, but the issue covers a wider range of situations.
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
Nvptx remove direct passmode
This PR does what should have been done in #117671. That is fully avoid using the `PassMode::Direct` for `extern "C" fn` for `nvptx64-nvidia-cuda` and enable the compatibility test. `@RalfJung` [pointed me in the right direction](https://github.com/rust-lang/rust/issues/117480#issuecomment-2137712501) for solving this issue.
There are still some ABI bugs after this PR is merged. These ABI tests are created based on what is actually correct, and since they continue passing with even more of them enabled things are improving. I don't have the time to tackle all the remaining issues right now, but I think getting these improvements merged is very valuable in themselves and plan to tackle more of them long term.
This also doesn't remove the use of `PassMode::Direct` for `extern "ptx-kernel" fn`. This was also not trivial to make work. And since the ABI is hidden behind an unstable feature it's less urgent.
I don't know if it's correct to request `@RalfJung` as a reviewer (due to team structures), but he helped me a lot to figure out this stuff. If that's not appropriate then `@davidtwco` would be a good candidate since he know about this topic from #117671
r? `@RalfJung`
Cleanup: HIR ty lowering: Consolidate the places that do assoc item probing & access checking
Use `probe_assoc_item` (for hygienically probing an assoc item and checking if it's accessible wrt. visibility and stability) for assoc item constraints, too, not just for assoc type paths and make the privacy error translatable.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
Make `ObligationEmittingRelation`s emit `Goal` rather than `Obligation`
Helps avoid needing to uplift `Obligation` into the solver. We still can't get rid of `ObligationCause`, but we can keep it as an associated type for `InferCtxtLike` and just give it a `dummy` function.
There's some shuttling between `Goal` and `Obligation` that may be perf-sensitive... Let's see what rust-timer says.
r? lcnr
Edition 2024: Make `!` fall back to `!`
This PR changes never type fallback to be `!` (the never type itself) in the next, 2024, edition.
This makes the never type's behavior more intuitive (in 2024 edition) and is the first step of the path to stabilize it.
r? `@compiler-errors`
PR #125443 will reformat all the use declarations in the repo. This
would break a patch kept in `rustc_codegen_cranelift` that gets applied
to `library/std/src/sys/pal/windows/rand.rs`.
So this commit formats the use declarations in
`library/std/src/sys/pal/windows/rand.rs` in advance of #125443 and
updates the patch file accordingly.
The motivation is that #125443 is a huge change and we want to get
fiddly little changes like this out of the way so it can be nothing more
than an `x fmt --all`.
Rollup of 6 pull requests
Successful merges:
- #115974 (Split core's PanicInfo and std's PanicInfo)
- #125659 (Remove usage of `isize` in example)
- #125669 (CI: Update riscv64gc-linux job to Ubuntu 22.04, rename to riscv64gc-gnu)
- #125684 (Account for existing bindings when suggesting `pin!()`)
- #126055 (Expand list of trait implementers in E0277 when calling rustc with --verbose)
- #126174 (Migrate `tests/run-make/prefer-dylib` to `rmake.rs`)
r? `@ghost`
`@rustbot` modify labels: rollup
Account for existing bindings when suggesting `pin!()`
When we encounter a situation where we'd suggest `pin!()`, we now account for that expression existing as part of an assignment and provide an appropriate suggestion:
```
error[E0599]: no method named `poll` found for type parameter `F` in the current scope
--> $DIR/pin-needed-to-poll-3.rs:19:28
|
LL | impl<F> Future for FutureWrapper<F>
| - method `poll` not found for this type parameter
...
LL | let res = self.fut.poll(cx);
| ^^^^ method not found in `F`
|
help: consider pinning the expression
|
LL ~ let mut pinned = std::pin::pin!(self.fut);
LL ~ let res = pinned.as_mut().poll(cx);
|
```
Fix#125661.
Split core's PanicInfo and std's PanicInfo
`PanicInfo` is used in two ways:
1. As argument to the `#[panic_handler]` in `no_std` context.
2. As argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in `std` context.
In situation 1, the `PanicInfo` always has a *message* (of type `fmt::Arguments`), but never a *payload* (of type `&dyn Any`).
In situation 2, the `PanicInfo` always has a *payload* (which is often a `String`), but not always a *message*.
Having these as the same type is annoying. It means we can't add `.message()` to the first one without also finding a way to properly support it on the second one. (Which is what https://github.com/rust-lang/rust/issues/66745 is blocked on.)
It also means that, because the implementation is in `core`, the implementation cannot make use of the `String` type (which doesn't exist in `core`): 0692db1a90/library/core/src/panic/panic_info.rs (L171-L172)
This also means that we cannot easily add a useful method like `PanicInfo::payload_as_str() -> Option<&str>` that works for both `&'static str` and `String` payloads.
I don't see any good reasons for these to be the same type, other than historical reasons.
---
This PR is makes 1 and 2 separate types. To try to avoid breaking existing code and reduce churn, the first one is still named `core::panic::PanicInfo`, and `std::panic::PanicInfo` is a new (deprecated) alias to `PanicHookInfo`. The crater run showed this as a viable option, since people write `core::` when defining a `#[panic_handler]` (because they're in `no_std`) and `std::` when writing a panic hook (since then they're definitely using `std`). On top of that, many definitions of a panic hook don't specify a type at all: they are written as a closure with an inferred argument type.
(Based on some thoughts I was having here: https://github.com/rust-lang/rust/pull/115561#issuecomment-1725830032)
---
For the release notes:
> We have renamed `std::panic::PanicInfo` to `std::panic::PanicHookInfo`. The old name will continue to work as an alias, but will result in a deprecation warning starting in Rust 1.82.0.
>
> `core::panic::PanicInfo` will remain unchanged, however, as this is now a *different type*.
>
> The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`.
Print `token::Interpolated` with token stream pretty printing.
This is a step towards removing `token::Interpolated` (#124141). It unavoidably changes the output of the `stringify!` macro, generally for the better.
r? `@petrochenkov`
interpret: ensure we check bool/char for validity when they are used in a cast
In general, `Scalar::to_bits` is a bit dangerous as it bypasses all type information. We should usually prefer matching on the type and acting according to that. So I also refactored `unary_op` handling of integers to do that. The remaining `to_bits` uses are operations that just fundamentally don't care about the sign (and only work on integers).
invalid_char_cast.rs is the key new test, the others already passed before this PR.
r? `@oli-obk`
Rollup of 5 pull requests
Successful merges:
- #125913 (Spruce up the diagnostics of some early lints)
- #126234 (Delegation: fix ICE on late diagnostics)
- #126253 (Simplify assert matchers in `run-make-support`)
- #126257 (Rename `needs-matching-clang` to `needs-force-clang-based-tests`)
- #126259 (reachable computation: clarify comments around consts)
r? `@ghost`
`@rustbot` modify labels: rollup
Spruce up the diagnostics of some early lints
Implement the various "*(note to myself) in a follow-up PR we should turn parts of this message into a subdiagnostic (help msg or even struct sugg)*" drive-by comments I left in #124417 during my review.
For context, before #124417, only a few early lints touched/decorated/customized their diagnostic because the former API made it a bit awkward. Likely because of that, things that should've been subdiagnostics were just crammed into the primary message. This PR rectifies this.
Only compute `specializes` query if (min)specialization is enabled in the crate of the specializing impl
Fixes (after backport) https://github.com/rust-lang/rust/issues/125197
### What
https://github.com/rust-lang/rust/pull/122791 makes it so that inductive cycles are no longer hard errors. That means that when we are testing, for example, whether these impls overlap:
```rust
impl PartialEq<Self> for AnyId {
fn eq(&self, _: &Self) -> bool {
todo!()
}
}
impl<T: Identifier> PartialEq<T> for AnyId {
fn eq(&self, _: &T) -> bool {
todo!()
}
}
```
...given...
```rust
pub trait Identifier: Display + 'static {}
impl<T> Identifier for T where T: PartialEq + Display + 'static {}
```
Then we try to see if the second impl holds given `T = AnyId`. That requires `AnyId: Identifier`, which requires that `AnyId: PartialEq`, which is satisfied by these two impl candidates... The `PartialEq<T>` impl is a cycle, and we used to winnow it when we used to treat inductive cycles as errors.
However, now that we don't winnow it, this means that we *now* try calling `candidate_should_be_dropped_in_favor_of`, which tries to check whether one of the impls specializes the other: the `specializes` query. In that query, we currently bail early if the impl is local.
However, in a foreign crate, we try to compute if the two impls specialize each other by doing trait solving. This may itself lead to the same situation where we call `specializes`, which will lead to a query cycle.
### How does this fix the problem
We now record whether specialization is enabled in foreign crates, and extend this early-return behavior to foreign impls too. This means that we can only encounter these cycles if we truly have a specializing impl from a crate with specialization enabled.
-----
r? `@oli-obk` or `@lcnr`
Add `SingleUseConsts` mir-opt pass
The goal here is to make a pass that can be run in debug builds to simplify the common case of constants that are used just once -- that doesn't need SSA handling and avoids any potential downside of multi-use constants. In particular, to simplify the `if T::IS_ZST` pattern that's common in the standard library.
By also handling the case of constants that are *never* actually used this fully replaces the `ConstDebugInfo` pass, since it has all the information needed to do that naturally from the traversal it needs to do anyway.
This is roughly a wash on instructions on its own (a couple regressions, a few improvements https://github.com/rust-lang/rust/pull/125910#issuecomment-2144963361), with a bunch of size improvements. So I'd like to land it as its own PR, then do follow-ups to take more advantage of it (in the inliner, cg_ssa, etc).
r? `@saethlin`
Add explanatory note to async block type mismatch error
The async block type mismatch error might leave the user wondering as to why it occurred. The new note should give them the needed context.
Changes this diagnostic:
```
error[E0308]: mismatched types
--> src/main.rs:5:23
|
2 | let a = async { 1 };
| ----------- the expected `async` block
3 | let b = async { 2 };
| ----------- the found `async` block
4 |
5 | let bad = vec![a, b];
| ^ expected `async` block, found a different `async` block
|
= note: expected `async` block `{async block@src/main.rs:2:13: 2:24}`
found `async` block `{async block@src/main.rs:3:13: 3:24}`
```
to this:
```
error[E0308]: mismatched types
--> src/main.rs:5:23
|
2 | let a = async { 1 };
| ----------- the expected `async` block
3 | let b = async { 2 };
| ----------- the found `async` block
4 |
5 | let bad = vec![a, b];
| ^ expected `async` block, found a different `async` block
|
= note: expected `async` block `{async block@src/main.rs:2:13: 2:24}`
found `async` block `{async block@src/main.rs:3:13: 3:24}`
= note: no two async blocks, even if identical, have the same type
= help: consider pinning your async block and and casting it to a trait object
```
Fixes#125737
Fix ICE due to `unwrap` in `probe_for_name_many`
Fixes#125876
Now `probe_for_name_many` bubbles up the error returned by `probe_op` instead of calling `unwrap` on it.