Allow restricted trait impls under `#[allow_internal_unstable(min_specialization)]`
This is a follow-up to #119963 and a companion to #120866, though it can land independently from the latter.
---
We have several compiler crates that only enable `#[feature(min_specialization)]` because it is required by their expansions of `newtype_index!`, in order to implement traits marked with `#[rustc_specialization_trait]`.
This PR allows those traits to be implemented internally by macros with `#[allow_internal_unstable(min_specialization)]`, without needing specialization to be enabled in the enclosing crate.
Remove unnecessary `#![feature(min_specialization)]`
As of #119963 and #120676, we can now rely on `newtype_index!` having `#[allow_internal_unstable(min_specialization)]`, so there are a few compiler crates that no longer need to include min-spec in their own crate features.
---
Some of the expansions of `newtype_index!` still appear to require min-spec in the crate features. I think this is because `#[orderable]` causes the expansion to include an implementation of `TrustedStep`, which is flagged with `#[rustc_specialization_trait]`, and for whatever reason that isn't permitted by allow-internal-unstable. So this PR only touches the crates where that isn't the case.
Turn the "no saved object file in work product" ICE into a translatable fatal error
I don't know if it's fair to say this fixes https://github.com/rust-lang/rust/issues/120854 but it surely makes the error reporting better and should encourage people with good instincts like ```@CinchBlue.```
Loosen an assertion to account for stashed errors.
The meaning of this assertion changed in #120828 when the meaning of `has_errors` changed to exclude stashed errors. Evidently the new meaning is too restrictive.
Fixes#120856.
r? ```@oli-obk```
Clarify that atomic and regular integers can differ in alignment
The documentation for atomic integers says that they have the "same in-memory representation" as their underlying integers. This might be misconstrued as implying that they have the same layout. Therefore, clarify that atomic integers' alignment is equal to their size.
Remove support for `associated_type_bound` nested in `dyn` types
These necessarily desugar to `impl Trait`, which is inconsistent with the `associated_type_bound` feature after #120584.
This PR keeps the `is_in_dyn_type` hack, which kind of makes me sad. Ideally, we'd be validating that no object types have associated type bounds somewhere else. Unfortunately, we can't do this later during astconv (i think?), nor can we do it earlier during ast validation (i think?) because of the feature gating of ATB being a *warning* rather than an *error*. Let me know if you have thoughts about this.
r? lcnr
static mut: allow mutable reference to arbitrary types, not just slices and arrays
For historical reasons, we allow this:
```rust
static mut ARRAY: &'static mut [isize] = &mut [1];
```
However, we do not allow this:
```rust
static mut INT: &'static mut isize = &mut 1;
```
I think that's terribly inconsistent. I don't care much for `static mut`, but we have to keep it around for backwards compatibility and so we have to keep supporting it properly in the compiler. In recent refactors of how we deal with mutability of data in `static` and `const`, I almost made a fatal mistake since I tested `static mut INT: &'static mut isize = &mut 1` and concluded that we don't allow such `'static` mutable references even inside `static mut`. After all, nobody would expect this to be allowed only for arrays and slices, right?!?? So for the sake of our own sanity, and of whoever else reverse engineers these rules in the future to understand what the Rust compiler accepts or does not accept, I propose that we accept this for all types, not just arrays and slices.
Abstract more over ItemTreeLoc-like structs
Allows reducing some code duplication by using functions generic over said structs. The diff isn't negative due to me adding some additional impls for completeness.
Use `ensure` when the result of the query is not needed beyond its `Result`ness
while I would like to just remove the `tcx` methods for ensure-only queries, that is hard to do without another query annotation or by turning the `define_callbacks` macro into a proc macro to get more control
should fix perf regression of https://github.com/rust-lang/rust/pull/120558
Harmonize `AsyncFn` implementations, make async closures conditionally impl `Fn*` traits
This PR implements several changes to the built-in and libcore-provided implementations of `Fn*` and `AsyncFn*` to address two problems:
1. async closures do not implement the `Fn*` family traits, leading to breakage: https://crater-reports.s3.amazonaws.com/pr-120361/index.html
2. *references* to async closures do not implement `AsyncFn*`, as a consequence of the existing blanket impls of the shape `AsyncFn for F where F: Fn, F::Output: Future`.
In order to fix (1.), we implement `Fn` traits appropriately for async closures. It turns out that async closures can:
* always implement `FnOnce`, meaning that they're drop-in compatible with `FnOnce`-bound combinators like `Option::map`.
* conditionally implement `Fn`/`FnMut` if they have no captures, which means that existing usages of async closures should *probably* work without breakage (crater checking this: https://github.com/rust-lang/rust/pull/120712#issuecomment-1930587805).
In order to fix (2.), we make all of the built-in callables implement `AsyncFn*` via built-in impls, and instead adjust the blanket impls for `AsyncFn*` provided by libcore to match the blanket impls for `Fn*`.
These crates all needed specialization for `newtype_index!`, which will no
longer be necessary when the current nightly eventually becomes the next
bootstrap compiler.
Implementing traits marked with `#[rustc_specialization_trait]` normally
requires (min-)specialization to be enabled for the enclosing crate.
With this change, that permission can also be granted by an
`allow_internal_unstable` attribute on the macro that generates the impl.
fix `llvm_out` to use the correct LLVM root
When `download-ci-llvm` is enabled, `llvm_out` ends up with the
error below due to an incorrect path on cross-compilations. This change fixes that.
```sh
failed to execute command: "/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-config" "--version"
ERROR: No such file or directory (os error 2)
```
Avoid a collection and iteration on empty passes
Just some mini optimization I saw in the wild. This way, we avoid a `collect` and `map` on an empty `passes`. Honestly, I don't even think this is big enough of a change to make a benchmark, but I'd still like to see results.
Based on [this book](https://nnethercote.github.io/perf-book/iterators.html#collect-and-extend)
[rustdoc] Correctly generate path for non-local items in source code pages
While browsing some crates using the "jump to def" feature, I realized that a lot of items didn't have a link generated. The reason is because we only cache foreign items if they appear in the documented API. This means that for the others, we need to infer them.
r? ``@notriddle``
For a rigid projection, recursively look at the self type's item bounds to fix the `associated_type_bounds` feature
Given a deeply nested rigid projection like `<<<T as Trait1>::Assoc1 as Trait2>::Assoc2 as Trait3>::Assoc3`, this PR adjusts both trait solvers to look at the item bounds for all of `Assoc3`, `Assoc2`, and `Assoc1` in order to satisfy a goal. We do this because the item bounds for projections may contain relevant bounds for *other* nested projections when the `associated_type_bounds` (ATB) feature is enabled. For example:
```rust
#![feature(associated_type_bounds)]
trait Trait1 {
type Assoc1: Trait2<Assoc2: Foo>;
// Item bounds for `Assoc1` are:
// `<Self as Trait1>::Assoc1: Trait2`
// `<<Self as Trait1>::Assoc1 as Trait2>::Assoc2: Foo`
}
trait Trait2 {
type Assoc2;
}
trait Foo {}
fn hello<T: Trait1>(x: <<T as Trait1>::Assoc1 as Trait2>::Assoc2) {
fn is_foo(_: impl Foo) {}
is_foo(x);
// Currently fails with:
// ERROR the trait bound `<<Self as Trait1>::Assoc1 as Trait2>::Assoc2: Foo` is not satisfied
}
```
This has been a long-standing place of brokenness for ATBs, and is also part of the reason why ATBs currently desugar so differently in various positions (i.e. sometimes desugaring to param-env bounds, sometimes desugaring to RPITs, etc). For example, in RPIT and TAIT position, `impl Foo<Bar: Baz>` currently desugars to `impl Foo<Bar = impl Baz>` because we do not currently take advantage of these nested item bounds if we desugared them into a single set of item bounds on the opaque. This is obviously both strange and unnecessary if we just take advantage of these bounds as we should.
## Approach
This PR repeatedly peels off each projection of a given goal's self type and tries to match its item bounds against a goal, repeating with the self type of the projection. This is pretty straightforward to implement in the new solver, only requiring us to loop on the self type of a rigid projection to discover inner rigid projections, and we also need to introduce an extra probe so we can normalize them.
In the old solver, we can do essentially the same thing, however we rely on the fact that projections *should* be normalized already. This is obviously not always the case -- however, in the case that they are not fully normalized, such as a projection which has both infer vars and, we bail out with ambiguity if we hit an infer var for the self type.
## Caveats
⚠️ In the old solver, this has the side-effect of actually stalling some higher-ranked trait goals of the form `for<'a> <?0 as Tr<'a>>: Tr2`. Because we stall them, they no longer are eagerly treated as error -- this cause some existing `known-bug` tests to go from fail -> pass.
I'm pretty unconvinced that this is a problem since we make code that we expect to pass in the *new* solver also pass in the *old* solver, though this obviously doesn't solve the *full* problem.
## And then also...
We also adjust the desugaring of ATB to always desugar to a regular associated bound, rather than sometimes to an impl Trait **except** for when the ATB is present in a `dyn Trait`. We need to lower `dyn Trait<Assoc: Bar>` to `dyn Trait<Assoc = impl Bar>` because object types need all of their associated types specified.
I would also be in favor of splitting out the ATB feature and/or removing support for object types in order to stabilize just the set of positions for which the ATB feature is consistent (i.e. always elaborates to a bound).
The meaning of this assertion changed in #120828 when the meaning of
`has_errors` changed to exclude stashed errors. Evidently the new
meaning is too restrictive.
Fixes#120856.